Client Streams Internals
[Client Streams API]

Collaboration diagram for Client Streams Internals:

Functions

 CBDATA_TYPE (clientStreamNode)
clientStreamNodeclientStreamNew (CSR *readfunc, CSCB *callback, CSD *detach, CSS *status, ClientStreamData data)
void clientStreamInit (dlink_list *list, CSR *func, CSD *rdetach, CSS *readstatus, ClientStreamData readdata, CSCB *callback, CSD *cdetach, ClientStreamData callbackdata, StoreIOBuffer tailBuffer)
void clientStreamInsertHead (dlink_list *list, CSR *func, CSCB *callback, CSD *detach, CSS *status, ClientStreamData data)
void clientStreamRead (clientStreamNode *thisObject, ClientHttpRequest *http, StoreIOBuffer readBuffer)
void clientStreamDetach (clientStreamNode *thisObject, ClientHttpRequest *http)
void clientStreamAbort (clientStreamNode *thisObject, ClientHttpRequest *http)
clientStream_status_t clientStreamStatus (clientStreamNode *thisObject, ClientHttpRequest *http)
void clientStreamFree (void *foo)

Detailed Description

A client Stream is a uni directional pipe, with the usual non-blocking asynchronous approach present elsewhere in squid.
Each pipe node has a data push function, and a data request function. This limits flexability - the data flow is no longer assembled at each step.
An alternative approach is to pass each node in the pipe the call- back to use on each IO call. This allows the callbacks to be changed very easily by a participating node, but requires more maintenance in each node (store the callback to the most recent IO request in the nodes context.) Such an approach also prevents dynamically changing the pipeline from outside without an additional interface method to extract the callback and context from the next node.
One important characteristic of the stream is that the readfunc on the terminating node, and the callback on the first node will be NULL, and never used.

Quick Notes

Each node including the HEAD of the clientStream has a cbdataReference held by the stream. Freeing the stream then removes that reference and cbdataFree()'s every node. Any node with other References, and all nodes downstream will only free when those references are released. Stream nodes MAY hold references to the data member of the node.
Specifically - on creation no reference is made. If you pass a data variable to a node, give it an initial reference. If the data member is non-null on FREE, cbdataFree WILL be called. This you must never call cbdataFree on your own context without explicitly setting the stream node data member to NULL and cbdataReferenceDone'ing it.
No data member may hold a reference to it's stream node. The stream guarantees that DETACH will be called before freeing the node, alowing data members to cleanup.
If a node's data holds a reference to something that needs to free the stream a circular reference list will occur. This results no data being freed until that reference is removed. One way to accomplish thisObject is to explicitly remove the data from your own node before freeing the stream.
   mycontext = thisObject->data;
   thisObject->data = NULL;
   clientStreamFree (thisObject->head);
   mycontext = NULL;
   return;
Todo:
rather than each node undeleting the next, have a clientStreamDelete that walks the list.

Function Documentation

CBDATA_TYPE ( clientStreamNode   ) 
void clientStreamAbort ( clientStreamNode thisObject,
ClientHttpRequest http 
)

Abort the stream - detach every node in the pipeline.

Parameters:
thisObject ??
http ??

Definition at line 266 of file clientStream.cc.

References assert, clientStreamDetach(), dlink_node::data, debugs, clientStreamNode::head, NULL, and dlink_list::tail.

Referenced by ClientHttpRequest::freeResources().

void clientStreamFree ( void *  foo  ) 
void clientStreamInit ( dlink_list list,
CSR func,
CSD rdetach,
CSS readstatus,
ClientStreamData  readdata,
CSCB callback,
CSD cdetach,
ClientStreamData  callbackdata,
StoreIOBuffer  tailBuffer 
)

Initialise a client Stream. list is the stream func is the read function for the head callback is the callback for the tail tailbuf and taillen are the initial buffer and length for the tail.

Definition at line 140 of file clientStream.cc.

References cbdataReference, clientStreamInsertHead(), clientStreamNew(), dlink_node::data, dlinkAdd(), clientStreamNode::head, clientStreamNode::node, NULL, clientStreamNode::readBuffer, and dlink_list::tail.

Referenced by clientBeginRequest(), parseHttpRequest(), and parseHttpRequestAbort().

void clientStreamInsertHead ( dlink_list list,
CSR func,
CSCB callback,
CSD detach,
CSS status,
ClientStreamData  data 
)

Doesn't actually insert at head. Instead it inserts one *after* head. This is because HEAD is a special node, as is tail This function is not suitable for inserting the real HEAD.

Definition at line 160 of file clientStream.cc.

References assert, cbdataReference, clientStreamNew(), dlink_node::data, debugs, dlinkAddAfter(), RefCount< C >::getRaw(), clientStreamNode::head, dlink_list::head, dlink_node::next, clientStreamNode::node, NULL, and clientStreamNode::readBuffer.

Referenced by clientStreamInit(), and clientReplyContext::processReplyAccessResult().

void clientStreamRead ( clientStreamNode thisObject,
ClientHttpRequest http,
StoreIOBuffer  readBuffer 
)

Call the previous node in the chain to read some data

Parameters:
thisObject ??
http ??
readBuffer ??

Definition at line 201 of file clientStream.cc.

References assert, debugs, clientStreamNode::prev(), and clientStreamNode::readBuffer.

Referenced by ClientRequestContext::clientAccessCheckDone(), esiBufferRecipient(), esiProcessStream(), esiStreamRead(), ClientHttpRequest::httpStart(), ClientSocketContext::pullData(), and ConnStateData::requestTimeout().

clientStream_status_t clientStreamStatus ( clientStreamNode thisObject,
ClientHttpRequest http 
)

Call the upstream node to find it's status

Parameters:
thisObject ??
http ??

Definition at line 288 of file clientStream.cc.

References assert, dlink_node::data, clientStreamNode::node, dlink_node::prev, and clientStreamNode::status.

Referenced by esiBufferRecipient(), esiStreamStatus(), and ClientSocketContext::socketState().

Search

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors