public:
CommRead ();
CommRead (int fd, char *buf, int len, AsyncCall::Pointer &callback);
- void queueCallback(size_t retval, comm_err_t errcode, int xerrno);
- bool hasCallback() const;
- void hasCallbackInvariant() const;
- void hasNoCallbackInvariant() const;
- void tryReading();
- void read();
- void initiateActualRead();
- void doCallback(comm_err_t errcode, int xerrno);
int fd;
char *buf;
int len;
AsyncCall::Pointer callback;
- static void ReadTry(int fd, void *data);
};
class DeferredRead
void *theContext;
CommRead theRead;
bool cancelled;
+ AsyncCall::Pointer closer; ///< internal close handler used by Comm
private:
};
comm_close(fd);
}
-void
-CommRead::doCallback(comm_err_t errcode, int xerrno)
-{
- if (callback != NULL) {
- typedef CommIoCbParams Params;
- Params ¶ms = GetCommParams<Params>(callback);
- params.fd = fd;
- params.size = 0;
- params.flag = errcode;
- params.xerrno = xerrno;
- ScheduleCallHere(callback);
- callback = NULL;
- }
-}
-
void
comm_close_start(int fd, void *data)
{
DeferredReadManager::delayRead(DeferredRead const &aRead) {
debugs(5, 3, "Adding deferred read on FD " << aRead.theRead.fd);
CbDataList<DeferredRead> *temp = deferredReads.push_back(aRead);
- comm_add_close_handler (aRead.theRead.fd, CloseHandler, temp);
+
+ // We have to use a global function as a closer and point to temp
+ // instead of "this" because DeferredReadManager is not a job and
+ // is not even cbdata protected
+ AsyncCall::Pointer closer = commCbCall(5,4,
+ "DeferredReadManager::CloseHandler",
+ CommCloseCbPtrFun(&CloseHandler, temp));
+ comm_add_close_handler(aRead.theRead.fd, closer);
+ temp->element.closer = closer; // remeber so that we can cancel
}
void
CbDataList<DeferredRead> *temp = (CbDataList<DeferredRead> *)thecbdata;
+ temp->element.closer = NULL;
temp->element.markCancelled();
}
DeferredReadManager::popHead(CbDataListContainer<DeferredRead> &deferredReads) {
assert (!deferredReads.empty());
- if (!deferredReads.head->element.cancelled)
- comm_remove_close_handler(deferredReads.head->element.theRead.fd, CloseHandler, deferredReads.head);
+ DeferredRead &read = deferredReads.head->element;
+ if (!read.cancelled) {
+ comm_remove_close_handler(read.theRead.fd, read.closer);
+ read.closer = NULL;
+ }
DeferredRead result = deferredReads.pop_front();