]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Merging async-call branch changes to HEAD:
authorrousskov <>
Wed, 13 Feb 2008 06:27:42 +0000 (06:27 +0000)
committerrousskov <>
Wed, 13 Feb 2008 06:27:42 +0000 (06:27 +0000)
        Use async calls for firing ready events. Deleted
        EventDispatcher as unused.

src/event.cc
src/event.h

index 6b2d8f6ef02a380fe7ac2cd534dda04baae0d7b2..1574e7ca9d590697ad83d07d205ac0409d10c4a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: event.cc,v 1.50 2007/12/14 23:11:46 amosjeffries Exp $
+ * $Id: event.cc,v 1.51 2008/02/12 23:27:42 rousskov Exp $
  *
  * DEBUG: section 41    Event Processing
  * AUTHOR: Henrik Nordstrom
 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(AsyncCall &call);
+
+    void dial(AsyncCall &) { 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(AsyncCall &call) {
+    // 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 @@ eventFind(EVH * func, void *arg)
     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<ev_entry *>::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 @@ EventScheduler::cancel(EVH * func, void *arg)
 
         *E = event->next;
 
-        if (event->cbdata)
-            cbdataReferenceDone(event->arg);
-
         delete event;
 
        if (arg)
@@ -228,16 +252,22 @@ EventScheduler::checkEvents(int timeout)
         if (event->when > current_dtime)
             break;
 
-        dispatcher->add
-        (event);
+        /* XXX assumes event->name is static memory! */
+        AsyncCall::Pointer 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 @@ EventScheduler::clean()
 {
     while (ev_entry * event = tasks) {
         tasks = event->next;
-
-        if (event->cbdata)
-            cbdataReferenceDone(event->arg);
-
         delete event;
     }
 
index d5757ec13a486d602bf065c99dc872403c76af89..531c860167ce71ff58a44664141482dc76b16502 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: event.h,v 1.3 2006/09/02 12:20:53 serassio Exp $
+ * $Id: event.h,v 1.4 2008/02/12 23:27:42 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 @@ class ev_entry
 
 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 @@ public:
 
 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<ev_entry *> 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 @@ public:
 
 private:
     static EventScheduler _instance;
-    EventDispatcher * dispatcher;
     ev_entry * tasks;
 };