mån 2012-12-03 klockan 09:07 -0700 skrev Alex Rousskov:
> Could you please fix this properly by adding
> AsyncEngine::timeTillNextEvent() or similar API and removing loop_delay
> manipulation from checkEvents() as discussed above?
The attached patch adds AsyncEngine::timeTillNextEvent() API. It also
kills the discussed sawActivity loop which imho should not be needed.
The patch is only lightly tested.
Regards
Henrik
=== modified file 'src/AsyncEngine.h'
--- src/AsyncEngine.h 2012-02-05 06:09:46 +0000
+++ src/AsyncEngine.h 2012-12-04 00:06:06 +0000
@@ -71,16 +71,19 @@
* events.
*
* The return value is the status code of the event checking. If its a
- * non-negative value then it is used as hint for the minimum requested
- * time before checkEvents is called again. I.e. the event engine knows
- * how long it is until the next event will be scheduled - so it will
- * return that time (in milliseconds).
+ * non-negative value then timeTillNextEvent() should be used to check
+ * desired time until next call after other processing have completed.
*
- * The timeout value is a requested timeout for this engine - the engine
- * should not block for more than this period. (If it takes longer than the
- * timeout to do actual checks thats fine though undesirable).
+ * The timeout value is a requested timeout in msec for this engine - the
+ * engine should not block for more than this period. (If it takes longer
+ * than the timeout to do actual checks thats fine though undesirable).
*/
virtual int checkEvents(int timeout) = 0;
+
+ /* Returns the desired time in msec until the engine needs to be called
+ * again to continue processing events.
+ */
+ virtual int timeTillNextEvent() = 0;
};
#endif /* SQUID_ASYNCENGINE_H */
=== modified file 'src/EventLoop.cc'
--- src/EventLoop.cc 2012-02-05 06:09:46 +0000
+++ src/EventLoop.cc 2012-12-03 23:58:00 +0000
@@ -43,17 +43,18 @@
void
EventLoop::checkEngine(AsyncEngine * engine, bool const primary)
{
- int requested_delay;
+ int rc;
if (!primary)
- requested_delay = engine->checkEvents(0);
+ rc = engine->checkEvents(0);
else
- requested_delay = engine->checkEvents(loop_delay);
+ rc = engine->checkEvents(loop_delay);
- if (requested_delay < 0)
- switch (requested_delay) {
+ if (rc < 0)
+ switch (rc) {
case AsyncEngine::EVENT_IDLE:
+ runOnceResult = false;
debugs(1, 9, "Engine " << engine << " is idle.");
break;
@@ -68,9 +69,6 @@
else {
/* not idle or error */
runOnceResult = false;
-
- if (requested_delay < loop_delay)
- loop_delay = requested_delay;
}
}
@@ -107,19 +105,24 @@
if (!waitingEngine && !engines.empty())
waitingEngine = engines.back();
- do {
- // generate calls and events
- typedef engine_vector::iterator EVI;
- for (EVI i = engines.begin(); i != engines.end(); ++i) {
- if (*i != waitingEngine)
+ // generate calls and events
+ typedef engine_vector::iterator EVI;
+ for (EVI i = engines.begin(); i != engines.end(); ++i) {
+ if (*i != waitingEngine)
checkEngine(*i, false);
- }
-
- // dispatch calls accumulated so far
- sawActivity = dispatchCalls();
- if (sawActivity)
- runOnceResult = false;
- } while (sawActivity);
+ }
+
+ // dispatch calls accumulated so far
+ sawActivity = dispatchCalls();
+ if (sawActivity)
+ runOnceResult = false;
+
+ // Figure out how long the waitingEngien is allowed to sleep
+ for (EVI i = engines.begin(); i != engines.end(); ++i) {
+ int requested_timeout = (*i)->timeTillNextEvent();
+ if (requested_timeout >= 0 && loop_delay < requested_timeout)
+ loop_delay = requested_timeout;
+ }
if (waitingEngine != NULL)
checkEngine(waitingEngine, true);
=== modified file 'src/comm.cc'
--- src/comm.cc 2012-11-26 08:28:09 +0000
+++ src/comm.cc 2012-12-03 23:59:29 +0000
@@ -2086,6 +2086,13 @@
};
}
+int
+CommSelectEngine::timeTillNextEvent()
+{
+ // We don't know when next event is, so say nothing in particular.
+ return EVENT_IDLE;
+}
+
/// Create a unix-domain socket (UDS) that only supports FD_MSGHDR I/O.
int
comm_open_uds(int sock_type,
=== modified file 'src/comm.h'
--- src/comm.h 2012-02-05 06:09:46 +0000
+++ src/comm.h 2012-12-03 22:51:18 +0000
@@ -107,7 +107,8 @@
{
public:
- virtual int checkEvents(int timeout);
+ int checkEvents(int timeout);
+ int timeTillNextEvent();
};
#endif
=== modified file 'src/event.cc'
--- src/event.cc 2012-02-05 06:09:46 +0000
+++ src/event.cc 2012-12-04 00:03:39 +0000
@@ -242,10 +242,10 @@
ev_entry *event = NULL;
if (NULL == tasks)
- return checkDelay();
+ return EVENT_IDLE;
if (tasks->when > current_dtime)
- return checkDelay();
+ return 0;
PROF_start(eventRun);
@@ -274,6 +274,15 @@
}
PROF_stop(eventRun);
+
+ if (NULL == tasks)
+ return EVENT_IDLE;
+
+ return 0;
+}
+
+int EventScheduler::timeTillNextEvent()
+{
return checkDelay();
}
=== modified file 'src/event.h'
--- src/event.h 2012-02-05 06:09:46 +0000
+++ src/event.h 2012-12-03 22:50:46 +0000
@@ -93,6 +93,7 @@
/* schedule a callback function to run in when seconds */
void schedule(const char *name, EVH * func, void *arg, double when, int weight, bool cbdata=true);
int checkEvents(int timeout);
+ int timeTillNextEvent();
static EventScheduler *GetInstance();
private:
=== modified file 'src/main.cc'
--- src/main.cc 2012-11-29 11:20:18 +0000
+++ src/main.cc 2012-12-03 22:57:21 +0000
@@ -190,6 +190,10 @@
Store::Root().callback();
return EVENT_IDLE;
};
+ int timeTillNextEvent() {
+ // TODO: Should this check if there is pending callbacks somehow?
+ return EVENT_IDLE;
+ };
};
class SignalEngine: public AsyncEngine
@@ -197,7 +201,8 @@
public:
SignalEngine(EventLoop &evtLoop) : loop(evtLoop) {}
- virtual int checkEvents(int timeout);
+ int checkEvents(int timeout);
+ int timeTillNextEvent();
private:
static void StopEventLoop(void * data) {
@@ -233,6 +238,20 @@
return EVENT_IDLE;
}
+int
+SignalEngine::timeTillNextEvent()
+{
+ if (DebugSignal >= 0)
+ return 0;
+ if (RotateSignal >= 0)
+ return 0;
+ if (ReconfigureSignal >= 0)
+ return 0;
+ if (ShutdownSignal >= 0 )
+ return 0;
+ return EVENT_IDLE;
+}
+
void
SignalEngine::doShutdown(time_t wait)
{
=== modified file 'src/tests/testEventLoop.cc'
--- src/tests/testEventLoop.cc 2012-02-05 06:09:46 +0000
+++ src/tests/testEventLoop.cc 2012-12-04 00:05:36 +0000
@@ -73,6 +73,9 @@
virtual int checkEvents(int timeout) {
++calls;
lasttimeout = timeout;
+ return 0;
+ }
+ int timeTillNextEvent() {
return return_timeout;
}
};