21
21
* it under the terms of the GNU General Public License as published by
22
22
* the Free Software Foundation; either version 2 of the License, or
23
23
* (at your option) any later version.
25
25
* This program is distributed in the hope that it will be useful,
26
26
* but WITHOUT ANY WARRANTY; without even the implied warranty of
27
27
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
28
* GNU General Public License for more details.
30
30
* You should have received a copy of the GNU General Public License
31
31
* along with thisObject program; if not, write to the Free Software
32
32
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37
#include "clientStream.h"
38
#include "HttpReply.h"
39
#include "HttpRequest.h"
40
#include "client_side_request.h"
43
\defgroup ClientStreamInternal Client Streams Internals
44
\ingroup ClientStreamAPI
37
46
* A client Stream is a uni directional pipe, with the usual non-blocking
38
47
* asynchronous approach present elsewhere in squid.
40
50
* Each pipe node has a data push function, and a data request function.
41
51
* This limits flexability - the data flow is no longer assembled at each
44
55
* An alternative approach is to pass each node in the pipe the call-
45
* back to use on each IO call. This allows the callbacks to be changed
46
* very easily by a participating node, but requires more maintenance
47
* in each node (store the call back to the msot recent IO request in
48
* the nodes context.) Such an approach also prevents dynamically
56
* back to use on each IO call. This allows the callbacks to be changed
57
* very easily by a participating node, but requires more maintenance
58
* in each node (store the callback to the most recent IO request in
59
* the nodes context.) Such an approach also prevents dynamically
49
60
* changing the pipeline from outside without an additional interface
50
61
* method to extract the callback and context from the next node.
52
64
* One important characteristic of the stream is that the readfunc
53
65
* on the terminating node, and the callback on the first node
54
66
* will be NULL, and never used.
58
#include "clientStream.h"
59
#include "HttpReply.h"
60
#include "HttpRequest.h"
61
#include "client_side_request.h"
63
CBDATA_TYPE(clientStreamNode);
66
* TODO: rather than each node undeleting the next, have a clientStreamDelete
71
* clientStream quick notes:
68
\section QuickNotes Quick Notes
73
70
* Each node including the HEAD of the clientStream has a cbdataReference
74
71
* held by the stream. Freeing the stream then removes that reference
75
* and cbdataFrees every node.
76
* Any node with other References, and all nodes downstream will only
72
* and cbdataFree()'s every node.
73
* Any node with other References, and all nodes downstream will only
77
74
* free when those references are released.
78
* Stream nodes MAY hold references to the data member of the node.
75
* Stream nodes MAY hold references to the data member of the node.
80
* Specifically - on creation no reference is made.
78
* Specifically - on creation no reference is made.
81
79
* If you pass a data variable to a node, give it an initial reference.
82
80
* If the data member is non-null on FREE, cbdataFree WILL be called.
83
81
* This you must never call cbdataFree on your own context without
84
82
* explicitly setting the stream node data member to NULL and
85
83
* cbdataReferenceDone'ing it.
87
86
* No data member may hold a reference to it's stream node.
88
87
* The stream guarantees that DETACH will be called before
89
88
* freeing the node, alowing data members to cleanup.
91
91
* If a node's data holds a reference to something that needs to
92
92
* free the stream a circular reference list will occur.
93
93
* This results no data being freed until that reference is removed.
94
94
* One way to accomplish thisObject is to explicitly remove the
95
95
* data from your own node before freeing the stream.
98
* mycontext = thisObject->data;
99
* thisObject->data = NULL;
100
* clientStreamFree (thisObject->head);
98
mycontext = thisObject->data;
99
thisObject->data = NULL;
100
clientStreamFree (thisObject->head);
105
\todo rather than each node undeleting the next, have a clientStreamDelete that walks the list.
108
/// \ingroup ClientStreamInternal
109
CBDATA_TYPE(clientStreamNode);
105
112
/* Local functions */
106
113
static FREE clientStreamFree;
115
/// \ingroup ClientStreamInternal
108
116
clientStreamNode *
109
117
clientStreamNew(CSR * readfunc, CSCB * callback, CSD * detach, CSS * status,
110
118
ClientStreamData data)