--------------------- PatchSet 6409 Date: 2007/12/19 23:09:37 Author: rousskov Branch: async-calls Tag: (none) Log: Async calls are not longer using time-based events with zero delay. They have a dedicated AsyncCallQueue. I did not make the queue a child of the Dispatcher because I hope to get rid of dispatchers eventually. Members: src/AsyncCall.cc:1.3.22.10->1.3.22.11 src/AsyncCall.h:1.3.22.17->1.3.22.18 src/AsyncCallQueue.cc:1.1->1.1.2.1 src/AsyncCallQueue.h:1.1->1.1.2.1 src/EventLoop.cc:1.5.4.2->1.5.4.3 src/Makefile.am:1.131.4.3->1.131.4.4 Index: squid3/src/AsyncCall.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/AsyncCall.cc,v retrieving revision 1.3.22.10 retrieving revision 1.3.22.11 diff -u -r1.3.22.10 -r1.3.22.11 --- squid3/src/AsyncCall.cc 13 Dec 2007 18:51:45 -0000 1.3.22.10 +++ squid3/src/AsyncCall.cc 19 Dec 2007 23:09:37 -0000 1.3.22.11 @@ -1,28 +1,20 @@ /* - * $Id: AsyncCall.cc,v 1.3.22.10 2007/12/13 18:51:45 chtsanti Exp $ + * $Id: AsyncCall.cc,v 1.3.22.11 2007/12/19 23:09:37 rousskov Exp $ */ #include "squid.h" #include "AsyncCall.h" +#include "AsyncCallQueue.h" #include "cbdata.h" unsigned int AsyncCall::TheLastId = 0; -// This static method will be moved to the global async call loop -void AsyncCall::FireWrapper(void *data) { - AsyncCall *call = static_cast(data); - debugs(call->debugSection, call->debugLevel, "entering " << *call); - call->make(); - debugs(call->debugSection, call->debugLevel, "leaving " << *call); - delete call; -} - /* AsyncCall */ AsyncCall::AsyncCall(int aDebugSection, int aDebugLevel, const char *aName): name(aName), debugSection(aDebugSection), - debugLevel(aDebugLevel), id(++TheLastId), isCanceled(NULL) + debugLevel(aDebugLevel), id(++TheLastId), theNext(0), isCanceled(NULL) { debugs(debugSection, debugLevel, "The AsyncCall " << name << " constructed, this=" << this << " [call" << id << ']'); @@ -30,6 +22,7 @@ AsyncCall::~AsyncCall() { + assert(!theNext); // AsyncCallQueue must clean } void @@ -81,7 +74,7 @@ { debugs(call->debugSection, call->debugLevel, fileName << "(" << fileLine << ") will call " << *call << " [call"<< call->id << ']' ); - eventAdd(call->name, &(AsyncCall::FireWrapper), call, 0.0, 0, false); + AsyncCallQueue::Instance().schedule(call); return true; } Index: squid3/src/AsyncCall.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/AsyncCall.h,v retrieving revision 1.3.22.17 retrieving revision 1.3.22.18 diff -u -r1.3.22.17 -r1.3.22.18 --- squid3/src/AsyncCall.h 13 Dec 2007 18:51:45 -0000 1.3.22.17 +++ squid3/src/AsyncCall.h 19 Dec 2007 23:09:37 -0000 1.3.22.18 @@ -1,6 +1,6 @@ /* - * $Id: AsyncCall.h,v 1.3.22.17 2007/12/13 18:51:45 chtsanti Exp $ + * $Id: AsyncCall.h,v 1.3.22.18 2007/12/19 23:09:37 rousskov Exp $ */ #ifndef SQUID_ASYNCCALL_H @@ -27,14 +27,14 @@ // debugging. class CallDialer; +class AsyncCallQueue; // TODO: add unique call IDs // TODO: CBDATA_CLASS2 kids class AsyncCall { public: - - static void FireWrapper(void *data); + friend class AsyncCallQueue; AsyncCall(int aDebugSection, int aDebugLevel, const char *aName); virtual ~AsyncCall(); @@ -59,6 +59,8 @@ virtual void fire() = 0; + AsyncCall *theNext; // used exclusively by AsyncCallQueue + private: const char *isCanceled; // set to the cancelation reason by cancel() static unsigned int TheLastId; --- /dev/null Wed Dec 26 01:24:21 2007 +++ squid3/src/AsyncCallQueue.cc Wed Dec 26 01:24:21 2007 @@ -0,0 +1,67 @@ + +/* + * $Id: AsyncCallQueue.cc,v 1.1.2.1 2007/12/19 23:09:37 rousskov Exp $ + * + * DEBUG: section 41 Event Processing + * + */ + +#include "AsyncCallQueue.h" +#include "AsyncCall.h" + +AsyncCallQueue *AsyncCallQueue::TheInstance = 0; + + +AsyncCallQueue::AsyncCallQueue(): theHead(NULL), theTail(NULL) +{ +} + +void AsyncCallQueue::schedule(AsyncCall *call) +{ + assert(call); + assert(!call->theNext); + if (theHead) { // append + assert(!theTail->theNext); + theTail->theNext = call; + theTail = call; + } else { // create queue from cratch + theHead = theTail = call; + } +} + +// Fire all scheduled calls; returns true if at least one call was fired. +// The calls may be added while the current call is in progress. +bool +AsyncCallQueue::fire() +{ + const bool made = theHead != NULL; + while (theHead != NULL) + fireNext(); + return made; +} + +void +AsyncCallQueue::fireNext() +{ + AsyncCall *call = theHead; + theHead = call->theNext; + call->theNext = NULL; + if (theTail == call) + theTail = NULL; + + debugs(call->debugSection, call->debugLevel, "entering " << *call); + call->make(); + debugs(call->debugSection, call->debugLevel, "leaving " << *call); + delete call; +} + +AsyncCallQueue & +AsyncCallQueue::Instance() +{ + // TODO: how to remove this frequent check while supporting early calls? + if (!TheInstance) + TheInstance = new AsyncCallQueue(); + + return *TheInstance; +} + --- /dev/null Wed Dec 26 01:24:21 2007 +++ squid3/src/AsyncCallQueue.h Wed Dec 26 01:24:21 2007 @@ -0,0 +1,40 @@ + +/* + * $Id: AsyncCallQueue.h,v 1.1.2.1 2007/12/19 23:09:37 rousskov Exp $ + * + */ + +#ifndef SQUID_ASYNCCALLQUEUE_H +#define SQUID_ASYNCCALLQUEUE_H + +#include "squid.h" +// #include "AsyncCall.h" + +class AsyncCall; + +// The queue of asynchronous calls. All calls are fired during a single main +// loop iteration until the queue is exhausted +class AsyncCallQueue +{ +public: + // there is only one queue + static AsyncCallQueue &Instance(); + + // make this async call when we get a chance + void schedule(AsyncCall *call); + + // fire all scheduled calls; returns true if at least one was fired + bool fire(); + +private: + AsyncCallQueue(); + + void fireNext(); + + AsyncCall* theHead; + AsyncCall* theTail; + + static AsyncCallQueue *TheInstance; +}; + +#endif /* SQUID_ASYNCCALLQUEUE_H */ Index: squid3/src/EventLoop.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/EventLoop.cc,v retrieving revision 1.5.4.2 retrieving revision 1.5.4.3 diff -u -r1.5.4.2 -r1.5.4.3 --- squid3/src/EventLoop.cc 19 Dec 2007 19:03:05 -0000 1.5.4.2 +++ squid3/src/EventLoop.cc 19 Dec 2007 23:09:37 -0000 1.5.4.3 @@ -1,6 +1,6 @@ /* - * $Id: EventLoop.cc,v 1.5.4.2 2007/12/19 19:03:05 rousskov Exp $ + * $Id: EventLoop.cc,v 1.5.4.3 2007/12/19 23:09:37 rousskov Exp $ * * DEBUG: section 1 Main Loop * AUTHOR: Harvest Derived @@ -34,6 +34,7 @@ */ #include "EventLoop.h" +#include "AsyncCallQueue.h" EventLoop::EventLoop() : errcount(0), last_loop(false), timeService(NULL), primaryEngine(NULL) @@ -158,7 +159,8 @@ bool EventLoop::dispatchCalls() { - bool dispatchedSome = false; + bool dispatchedSome = AsyncCallQueue::Instance().fire(); + typedef dispatcher_vector::iterator DVI; for (DVI i = dispatchers.begin(); i != dispatchers.end(); ++i) { if ((*i)->dispatch()) Index: squid3/src/Makefile.am =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Makefile.am,v retrieving revision 1.131.4.3 retrieving revision 1.131.4.4 diff -u -r1.131.4.3 -r1.131.4.4 --- squid3/src/Makefile.am 16 Dec 2007 11:36:22 -0000 1.131.4.3 +++ squid3/src/Makefile.am 19 Dec 2007 23:09:37 -0000 1.131.4.4 @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.131.4.3 2007/12/16 11:36:22 chtsanti Exp $ +# $Id: Makefile.am,v 1.131.4.4 2007/12/19 23:09:37 rousskov Exp $ # # Uncomment and customize the following to suit your needs: # @@ -417,6 +417,8 @@ ACLChecklist.h \ $(squid_ACLSOURCES) \ asn.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ AsyncCall.h \ AsyncJobCalls.h \ @@ -745,6 +747,8 @@ time.cc \ ufsdump.cc \ url.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ AsyncCall.h \ BodyPipe.cc \ @@ -1273,6 +1277,8 @@ ACLStringData.cc \ ACLRegexData.cc \ ACLUserData.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ authenticate.cc \ BodyPipe.cc \ @@ -1439,6 +1445,8 @@ ACLStringData.cc \ ACLRegexData.cc \ ACLUserData.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ authenticate.cc \ BodyPipe.cc \ @@ -1591,6 +1599,8 @@ ACLStringData.cc \ ACLRegexData.cc \ ACLUserData.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ authenticate.cc \ BodyPipe.cc \ @@ -1767,6 +1777,8 @@ ACLStringData.cc \ ACLRegexData.cc \ ACLUserData.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ authenticate.cc \ BodyPipe.cc \ @@ -1926,6 +1938,8 @@ ACLStringData.cc \ ACLRegexData.cc \ ACLUserData.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ authenticate.cc \ BodyPipe.cc \ @@ -2264,6 +2278,8 @@ ACLStringData.cc \ ACLRegexData.cc \ ACLUserData.cc \ + AsyncCallQueue.cc \ + AsyncCallQueue.h \ AsyncCall.cc \ authenticate.cc \ BodyPipe.cc \