]> git.ipfire.org Git - thirdparty/squid.git/blame - src/EventLoop.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / EventLoop.cc
CommitLineData
a553a5a3 1/*
bbc27441 2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
a553a5a3 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
a553a5a3 7 */
8
bbc27441
AJ
9/* DEBUG: section 01 Main Loop */
10
f7f3304a 11#include "squid.h"
314782d4 12#include "AsyncEngine.h"
602d9612 13#include "base/AsyncCallQueue.h"
582c2af2 14#include "Debug.h"
a553a5a3 15#include "EventLoop.h"
314782d4
FC
16#include "SquidTime.h"
17
0a720258
AR
18EventLoop *EventLoop::Running = NULL;
19
bef81ea5 20EventLoop::EventLoop() : errcount(0), last_loop(false), timeService(NULL),
2e2f336f
AJ
21 primaryEngine(NULL),
22 loop_delay(EVENT_LOOP_TIMEOUT),
23 error(false),
24 runOnceResult(false)
a553a5a3 25{}
26
bef81ea5 27void
28EventLoop::checkEngine(AsyncEngine * engine, bool const primary)
29{
30 int requested_delay;
31
32 if (!primary)
33 requested_delay = engine->checkEvents(0);
34 else
35 requested_delay = engine->checkEvents(loop_delay);
36
37 if (requested_delay < 0)
38 switch (requested_delay) {
39
40 case AsyncEngine::EVENT_IDLE:
41 debugs(1, 9, "Engine " << engine << " is idle.");
42 break;
43
44 case AsyncEngine::EVENT_ERROR:
45 runOnceResult = false;
46 error = true;
47 break;
48
49 default:
50 fatal_dump("unknown AsyncEngine result");
51 }
52 else {
53 /* not idle or error */
54 runOnceResult = false;
55
56 if (requested_delay < loop_delay)
57 loop_delay = requested_delay;
58 }
59}
60
a553a5a3 61void
62EventLoop::prepareToRun()
63{
64 last_loop = false;
65 errcount = 0;
66}
67
8ff3fa2e 68void
69EventLoop::registerEngine(AsyncEngine *engine)
70{
71 engines.push_back(engine);
72}
73
a553a5a3 74void
75EventLoop::run()
76{
77 prepareToRun();
78
0a720258
AR
79 assert(!Running);
80 Running = this;
81
3d0ac046 82 while (!runOnce());
0a720258
AR
83
84 Running = NULL;
a553a5a3 85}
86
8ff3fa2e 87bool
a553a5a3 88EventLoop::runOnce()
89{
1fd133b5 90 bool sawActivity = false;
bef81ea5 91 runOnceResult = true;
92 error = false;
6289f91f 93 loop_delay = EVENT_LOOP_TIMEOUT;
8ff3fa2e 94
1fd133b5 95 AsyncEngine *waitingEngine = primaryEngine;
96 if (!waitingEngine && !engines.empty())
97 waitingEngine = engines.back();
bef81ea5 98
1fd133b5 99 do {
100 // generate calls and events
101 typedef engine_vector::iterator EVI;
102 for (EVI i = engines.begin(); i != engines.end(); ++i) {
103 if (*i != waitingEngine)
104 checkEngine(*i, false);
105 }
bef81ea5 106
1fd133b5 107 // dispatch calls accumulated so far
108 sawActivity = dispatchCalls();
109 if (sawActivity)
110 runOnceResult = false;
26ac0430 111 } while (sawActivity);
8ff3fa2e 112
1fd133b5 113 if (waitingEngine != NULL)
114 checkEngine(waitingEngine, true);
bef81ea5 115
8ff3fa2e 116 if (timeService != NULL)
117 timeService->tick();
a553a5a3 118
1fd133b5 119 // dispatch calls scheduled by waitingEngine and timeService
120 sawActivity = dispatchCalls();
121 if (sawActivity)
122 runOnceResult = false;
a553a5a3 123
8ff3fa2e 124 if (error) {
125 ++errcount;
fa84c01d 126 debugs(1, DBG_CRITICAL, "Select loop Error. Retry " << errcount);
8ff3fa2e 127 } else
128 errcount = 0;
a553a5a3 129
8ff3fa2e 130 if (errcount == 10)
131 return true;
a553a5a3 132
8ff3fa2e 133 if (last_loop)
134 return true;
a553a5a3 135
bef81ea5 136 return runOnceResult;
137}
138
1fd133b5 139// dispatches calls accumulated during checkEngine()
140bool
141EventLoop::dispatchCalls()
142{
143 bool dispatchedSome = AsyncCallQueue::Instance().fire();
144 return dispatchedSome;
145}
146
bef81ea5 147void
148EventLoop::setPrimaryEngine(AsyncEngine * engine)
149{
150 for (engine_vector::iterator i = engines.begin();
151 i != engines.end(); ++i)
152 if (*i == engine) {
153 primaryEngine = engine;
154 return;
155 }
156
157 fatal("EventLoop::setPrimaryEngine: No such engine!.");
8ff3fa2e 158}
a553a5a3 159
8ff3fa2e 160void
161EventLoop::setTimeService(TimeEngine *engine)
162{
163 timeService = engine;
a553a5a3 164}
165
166void
167EventLoop::stop()
168{
169 last_loop = true;
170}