--------------------- PatchSet 6410 Date: 2007/12/20 04:42:06 Author: rousskov Branch: async-calls Tag: (none) Log: Use async calls for firing ready events. Deleted EventDispatcher as unused. Members: src/event.cc:1.16->1.16.4.1 src/event.h:1.3->1.3.32.1 src/main.cc:1.89.4.1->1.89.4.2 Index: squid3/src/event.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/event.cc,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -u -r1.16 -r1.16.4.1 --- squid3/src/event.cc 30 Jul 2007 15:51:15 -0000 1.16 +++ squid3/src/event.cc 20 Dec 2007 04:42:06 -0000 1.16.4.1 @@ -1,6 +1,6 @@ /* - * $Id: event.cc,v 1.16 2007/07/30 15:51:15 squidadm Exp $ + * $Id: event.cc,v 1.16.4.1 2007/12/20 04:42:06 rousskov Exp $ * * DEBUG: section 41 Event Processing * AUTHOR: Henrik Nordstrom @@ -43,8 +43,82 @@ static OBJH eventDump; static const char *last_event_ran = NULL; -ev_entry::ev_entry(char const * name, EVH * func, void * arg, double when, int weight, bool cbdata) : name(name), func(func), arg(cbdata ? cbdataReference(arg) : arg), when(when), weight(weight), cbdata(cbdata) -{} +// This AsyncCall dialer can be configured to check that the event cbdata is +// valid before calling the event handler +class EventDialer: public CallDialer +{ +public: + typedef CallDialer Parent; + + EventDialer(EVH *aHandler, void *anArg, bool lockedArg); + EventDialer(const EventDialer &d); + virtual ~EventDialer(); + + virtual void print(std::ostream &os) const; + virtual bool canDial(); + + void dial() { theHandler(theArg); } + +private: + EVH *theHandler; + void *theArg; + bool isLockedArg; +}; + +EventDialer::EventDialer(EVH *aHandler, void *anArg, bool lockedArg): + theHandler(aHandler), theArg(anArg), isLockedArg(lockedArg) +{ + if (isLockedArg) + cbdataReference(theArg); +} + +EventDialer::EventDialer(const EventDialer &d): + theHandler(d.theHandler), theArg(d.theArg), isLockedArg(d.isLockedArg) +{ + if (isLockedArg) + cbdataReference(theArg); +} + +EventDialer::~EventDialer() +{ + if (isLockedArg) + cbdataReferenceDone(theArg); +} + +bool +EventDialer::canDial() { + // TODO: add Parent::canDial() that always returns true + //if (!Parent::canDial()) + // return false; + + if (isLockedArg && !cbdataReferenceValid(theArg)) + return call->cancel("stale handler data"); + + return true; +} + +void +EventDialer::print(std::ostream &os) const +{ + os << '('; + if (theArg) + os << theArg << (isLockedArg ? "*?" : ""); + os << ')'; +} + + +ev_entry::ev_entry(char const * name, EVH * func, void * arg, double when, + int weight, bool cbdata) : name(name), func(func), + arg(cbdata ? cbdataReference(arg) : arg), when(when), weight(weight), + cbdata(cbdata) +{ +} + +ev_entry::~ev_entry() +{ + if (cbdata) + cbdataReferenceDone(arg); +} void eventAdd(const char *name, EVH * func, void *arg, double when, int weight, bool cbdata) @@ -98,56 +172,9 @@ return EventScheduler::GetInstance()->find(func, arg); } -EventDispatcher EventDispatcher::_instance; - -EventDispatcher::EventDispatcher() -{} - -void - -EventDispatcher::add - (ev_entry * event) -{ - queue.push_back(event); -} - -bool -EventDispatcher::dispatch() -{ - bool result = queue.size() != 0; - - PROF_start(EventDispatcher_dispatch); - for (Vector::iterator i = queue.begin(); i != queue.end(); ++i) { - ev_entry * event = *i; - EVH *callback; - void *cbdata = event->arg; - callback = event->func; - event->func = NULL; - - if (!event->cbdata || cbdataReferenceValidDone(event->arg, &cbdata)) { - /* XXX assumes ->name is static memory! */ - last_event_ran = event->name; - debugs(41, 5, "EventDispatcher::dispatch: Running '" << event->name << "'"); - callback(cbdata); - } - - delete event; - } - - queue.clean(); - PROF_stop(EventDispatcher_dispatch); - return result; -} - -EventDispatcher * -EventDispatcher::GetInstance() -{ - return &_instance; -} - -EventScheduler EventScheduler::_instance(EventDispatcher::GetInstance()); +EventScheduler EventScheduler::_instance; -EventScheduler::EventScheduler(EventDispatcher *dispatcher) : dispatcher(dispatcher), tasks(NULL) +EventScheduler::EventScheduler(): tasks(NULL) {} EventScheduler::~EventScheduler() @@ -170,9 +197,6 @@ *E = event->next; - if (event->cbdata) - cbdataReferenceDone(event->arg); - delete event; if (arg) @@ -228,16 +252,22 @@ if (event->when > current_dtime) break; - dispatcher->add - (event); + /* XXX assumes event->name is static memory! */ + AsyncCall *call = asyncCall(41,5, event->name, + EventDialer(event->func, event->arg, event->cbdata)); + ScheduleCallHere(call); + + last_event_ran = event->name; // XXX: move this to AsyncCallQueue + const bool heavy = event->weight && + (!event->cbdata || cbdataReferenceValid(event->arg)); tasks = event->next; + delete event; - if (!event->cbdata || cbdataReferenceValid(event->arg)) - if (event->weight) - /* this event is marked as being 'heavy', so dont dequeue any others. - */ - break; + // XXX: We may be called again during the same event loop iteration. + // Is there a point in breaking now? + if (heavy) + break; // do not dequeue events following a heavy event } PROF_stop(eventRun); @@ -249,10 +279,6 @@ { while (ev_entry * event = tasks) { tasks = event->next; - - if (event->cbdata) - cbdataReferenceDone(event->arg); - delete event; } Index: squid3/src/event.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/event.h,v retrieving revision 1.3 retrieving revision 1.3.32.1 diff -u -r1.3 -r1.3.32.1 --- squid3/src/event.h 2 Sep 2006 12:50:15 -0000 1.3 +++ squid3/src/event.h 20 Dec 2007 04:42:06 -0000 1.3.32.1 @@ -1,6 +1,6 @@ /* - * $Id: event.h,v 1.3 2006/09/02 12:50:15 squidadm Exp $ + * $Id: event.h,v 1.3.32.1 2007/12/20 04:42:06 rousskov Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -37,7 +37,6 @@ #include "squid.h" #include "Array.h" #include "AsyncEngine.h" -#include "CompletionDispatcher.h" /* forward decls */ @@ -59,6 +58,7 @@ public: ev_entry(char const * name, EVH * func, void *arg, double when, int weight, bool cbdata=true); + ~ev_entry(); MEMPROXY_CLASS(ev_entry); const char *name; EVH *func; @@ -73,41 +73,12 @@ MEMPROXY_CLASS_INLINE(ev_entry); -class EventDispatcher : public CompletionDispatcher -{ - -public: - EventDispatcher(); - /* add an event to dequeue when dispatch is called */ - - void add - (ev_entry *); - - /* add an event to be dispatched in the future */ - void add - (const char *name, EVH * func, void *arg, double when, int, bool cbdata=true); - - bool dispatch(); - - static EventDispatcher *GetInstance(); - -private: - Vector queue; - - static EventDispatcher _instance; -}; - +// manages time-based events class EventScheduler : public AsyncEngine { public: - /* Create an event scheduler that will hand its ready to run callbacks to - * an EventDispatcher - * - * TODO: add should include a dispatcher to use perhaps? then it would be - * more decoupled.. - */ - EventScheduler(EventDispatcher *); + EventScheduler(); ~EventScheduler(); /* cancel a scheduled but not dispatched event */ void cancel(EVH * func, void * arg); @@ -126,7 +97,6 @@ private: static EventScheduler _instance; - EventDispatcher * dispatcher; ev_entry * tasks; }; Index: squid3/src/main.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/main.cc,v retrieving revision 1.89.4.1 retrieving revision 1.89.4.2 diff -u -r1.89.4.1 -r1.89.4.2 --- squid3/src/main.cc 19 Dec 2007 18:29:07 -0000 1.89.4.1 +++ squid3/src/main.cc 20 Dec 2007 04:42:06 -0000 1.89.4.2 @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.89.4.1 2007/12/19 18:29:07 rousskov Exp $ + * $Id: main.cc,v 1.89.4.2 2007/12/20 04:42:06 rousskov Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -1293,9 +1293,6 @@ mainLoop.registerDispatcher(&signal_dispatcher); /* TODO: stop requiring the singleton here */ - mainLoop.registerDispatcher(EventDispatcher::GetInstance()); - - /* TODO: stop requiring the singleton here */ mainLoop.registerEngine(EventScheduler::GetInstance()); StoreRootEngine store_engine;