]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Merging async-call branch changes to HEAD:
authorrousskov <>
Wed, 13 Feb 2008 06:49:44 +0000 (06:49 +0000)
committerrousskov <>
Wed, 13 Feb 2008 06:49:44 +0000 (06:49 +0000)
Async-call work replaces event-based asynchronous calls with
stand-alone implementation. The common async call API allows Squid
core do call, debug, and troubleshoot all callback handlers in a
uniform way.

An async "job" API is introduced to manage independent logical threads
or work such as protocol transaction handlers on client, server, and
ICAP sides. These jobs should communicate with each other using async
calls to minimize dependencies and avoid reentrant callback loops.

These changes will eventually improve overall code quality, debugging
quality, and Squid robustness.

Below you will find log messages from the async-call branch that are
relevant to the file(s) being committed.

        Do not use CompletionDispatcher.

        Async calls are not longer using time-based events with zero
        delay. They have a dedicated AsyncCallQueue.

        Moved duplicated code into dispatchCalls().

EventLoop will need further internal polishing to polish, simplify and
possibly speed up the code.

src/EventLoop.cc
src/EventLoop.h

index 1b04926c8841a78592b0890f105a5396f290f0e3..cc2af543109daf8c4d8625e9cca3968a53b0ad49 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: EventLoop.cc,v 1.5 2007/07/23 19:55:21 rousskov Exp $
+ * $Id: EventLoop.cc,v 1.6 2008/02/12 23:49:44 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)
@@ -80,12 +81,6 @@ EventLoop::prepareToRun()
     errcount = 0;
 }
 
-void
-EventLoop::registerDispatcher(CompletionDispatcher *dispatcher)
-{
-    dispatchers.push_back(dispatcher);
-}
-
 void
 EventLoop::registerEngine(AsyncEngine *engine)
 {
@@ -105,31 +100,39 @@ EventLoop::run()
 bool
 EventLoop::runOnce()
 {
+    bool sawActivity = false;
     runOnceResult = true;
     error = false;
     loop_delay = 10; /* 10 ms default delay */
 
-    for (engine_vector::iterator i = engines.begin();
-            i != engines.end(); ++i) {
-        /* check the primary outside the loop */
+    AsyncEngine *waitingEngine = primaryEngine;
+    if (!waitingEngine && !engines.empty())
+        waitingEngine = engines.back();
 
-        if (*i == primaryEngine)
-            continue;
+    do {
+        // generate calls and events
+        typedef engine_vector::iterator EVI;
+        for (EVI i = engines.begin(); i != engines.end(); ++i) {
+            if (*i != waitingEngine)
+                checkEngine(*i, false);
+        }
 
-        /* special case the last engine to be primary */
-        checkEngine(*i, primaryEngine == NULL && (i - engines.end() == -1));
-    }
+        // dispatch calls accumulated so far
+        sawActivity = dispatchCalls();
+        if (sawActivity)
+            runOnceResult = false;
+       } while (sawActivity);
 
-    if (primaryEngine != NULL)
-        checkEngine(primaryEngine, true);
+    if (waitingEngine != NULL)
+        checkEngine(waitingEngine, true);
 
     if (timeService != NULL)
         timeService->tick();
 
-    for (dispatcher_vector::iterator i = dispatchers.begin();
-            i != dispatchers.end(); ++i)
-        if ((*i)->dispatch())
-            runOnceResult = false;
+    // dispatch calls scheduled by waitingEngine and timeService
+    sawActivity = dispatchCalls();
+    if (sawActivity)
+        runOnceResult = false;
 
     if (error) {
         ++errcount;
@@ -146,6 +149,14 @@ EventLoop::runOnce()
     return runOnceResult;
 }
 
+// dispatches calls accumulated during checkEngine()
+bool
+EventLoop::dispatchCalls()
+{
+    bool dispatchedSome = AsyncCallQueue::Instance().fire();
+    return dispatchedSome;
+}
+
 void
 EventLoop::setPrimaryEngine(AsyncEngine * engine)
 {
index 21e50bd676a4defac604586081a1a84a3378f055..1262295be2b0a95767aed425e7274458f5557ee6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: EventLoop.h,v 1.3 2006/08/19 12:31:21 robertc Exp $
+ * $Id: EventLoop.h,v 1.4 2008/02/12 23:49:44 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"
 #include "SquidTime.h"
 
 /* An event loop. An event loop is the core inner loop of squid.
@@ -52,8 +51,6 @@ class EventLoop
 
 public:
     EventLoop();
-    /* register an event dispatcher to be invoked on each event loop. */
-    void registerDispatcher(CompletionDispatcher *dispatcher);
     /* register an async engine which will be given the opportunity to perform
      * in-main-thread tasks each event loop.
      */
@@ -93,9 +90,10 @@ private:
     void prepareToRun();
     /* check an individual engine */
     void checkEngine(AsyncEngine * engine, bool const primary);
+    /* dispatch calls and events scheduled during checkEngine() */
+    bool dispatchCalls();
+
     bool last_loop;
-    typedef Vector<CompletionDispatcher *> dispatcher_vector;
-    dispatcher_vector dispatchers;
     typedef Vector<AsyncEngine *> engine_vector;
     engine_vector engines;
     TimeEngine * timeService;