]>
Commit | Line | Data |
---|---|---|
a553a5a3 | 1 | |
2 | /* | |
262a0e14 | 3 | * $Id$ |
a553a5a3 | 4 | * |
5 | * DEBUG: section 1 Main Loop | |
6 | * AUTHOR: Harvest Derived | |
7 | * | |
8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
9 | * ---------------------------------------------------------- | |
10 | * | |
11 | * Squid is the result of efforts by numerous individuals from | |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
19 | * | |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
26ac0430 | 24 | * |
a553a5a3 | 25 | * This program is distributed in the hope that it will be useful, |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
26ac0430 | 29 | * |
a553a5a3 | 30 | * You should have received a copy of the GNU General Public License |
31 | * along with this program; if not, write to the Free Software | |
32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
33 | * | |
34 | */ | |
35 | ||
a553a5a3 | 36 | #include "EventLoop.h" |
882255af | 37 | #include "base/AsyncCallQueue.h" |
a553a5a3 | 38 | |
bef81ea5 | 39 | EventLoop::EventLoop() : errcount(0), last_loop(false), timeService(NULL), |
40 | primaryEngine(NULL) | |
a553a5a3 | 41 | {} |
42 | ||
bef81ea5 | 43 | void |
44 | EventLoop::checkEngine(AsyncEngine * engine, bool const primary) | |
45 | { | |
46 | int requested_delay; | |
47 | ||
48 | if (!primary) | |
49 | requested_delay = engine->checkEvents(0); | |
50 | else | |
51 | requested_delay = engine->checkEvents(loop_delay); | |
52 | ||
53 | if (requested_delay < 0) | |
54 | switch (requested_delay) { | |
55 | ||
56 | case AsyncEngine::EVENT_IDLE: | |
57 | debugs(1, 9, "Engine " << engine << " is idle."); | |
58 | break; | |
59 | ||
60 | case AsyncEngine::EVENT_ERROR: | |
61 | runOnceResult = false; | |
62 | error = true; | |
63 | break; | |
64 | ||
65 | default: | |
66 | fatal_dump("unknown AsyncEngine result"); | |
67 | } | |
68 | else { | |
69 | /* not idle or error */ | |
70 | runOnceResult = false; | |
71 | ||
72 | if (requested_delay < loop_delay) | |
73 | loop_delay = requested_delay; | |
74 | } | |
75 | } | |
76 | ||
a553a5a3 | 77 | void |
78 | EventLoop::prepareToRun() | |
79 | { | |
80 | last_loop = false; | |
81 | errcount = 0; | |
82 | } | |
83 | ||
8ff3fa2e | 84 | void |
85 | EventLoop::registerEngine(AsyncEngine *engine) | |
86 | { | |
87 | engines.push_back(engine); | |
88 | } | |
89 | ||
a553a5a3 | 90 | void |
91 | EventLoop::run() | |
92 | { | |
93 | prepareToRun(); | |
94 | ||
3d0ac046 | 95 | while (!runOnce()); |
a553a5a3 | 96 | } |
97 | ||
8ff3fa2e | 98 | bool |
a553a5a3 | 99 | EventLoop::runOnce() |
100 | { | |
1fd133b5 | 101 | bool sawActivity = false; |
bef81ea5 | 102 | runOnceResult = true; |
103 | error = false; | |
6289f91f | 104 | loop_delay = EVENT_LOOP_TIMEOUT; |
8ff3fa2e | 105 | |
1fd133b5 | 106 | AsyncEngine *waitingEngine = primaryEngine; |
107 | if (!waitingEngine && !engines.empty()) | |
108 | waitingEngine = engines.back(); | |
bef81ea5 | 109 | |
1fd133b5 | 110 | do { |
111 | // generate calls and events | |
112 | typedef engine_vector::iterator EVI; | |
113 | for (EVI i = engines.begin(); i != engines.end(); ++i) { | |
114 | if (*i != waitingEngine) | |
115 | checkEngine(*i, false); | |
116 | } | |
bef81ea5 | 117 | |
1fd133b5 | 118 | // dispatch calls accumulated so far |
119 | sawActivity = dispatchCalls(); | |
120 | if (sawActivity) | |
121 | runOnceResult = false; | |
26ac0430 | 122 | } while (sawActivity); |
8ff3fa2e | 123 | |
1fd133b5 | 124 | if (waitingEngine != NULL) |
125 | checkEngine(waitingEngine, true); | |
bef81ea5 | 126 | |
8ff3fa2e | 127 | if (timeService != NULL) |
128 | timeService->tick(); | |
a553a5a3 | 129 | |
1fd133b5 | 130 | // dispatch calls scheduled by waitingEngine and timeService |
131 | sawActivity = dispatchCalls(); | |
132 | if (sawActivity) | |
133 | runOnceResult = false; | |
a553a5a3 | 134 | |
8ff3fa2e | 135 | if (error) { |
136 | ++errcount; | |
a553a5a3 | 137 | debugs(1, 0, "Select loop Error. Retry " << errcount); |
8ff3fa2e | 138 | } else |
139 | errcount = 0; | |
a553a5a3 | 140 | |
8ff3fa2e | 141 | if (errcount == 10) |
142 | return true; | |
a553a5a3 | 143 | |
8ff3fa2e | 144 | if (last_loop) |
145 | return true; | |
a553a5a3 | 146 | |
bef81ea5 | 147 | return runOnceResult; |
148 | } | |
149 | ||
1fd133b5 | 150 | // dispatches calls accumulated during checkEngine() |
151 | bool | |
152 | EventLoop::dispatchCalls() | |
153 | { | |
154 | bool dispatchedSome = AsyncCallQueue::Instance().fire(); | |
155 | return dispatchedSome; | |
156 | } | |
157 | ||
bef81ea5 | 158 | void |
159 | EventLoop::setPrimaryEngine(AsyncEngine * engine) | |
160 | { | |
161 | for (engine_vector::iterator i = engines.begin(); | |
162 | i != engines.end(); ++i) | |
163 | if (*i == engine) { | |
164 | primaryEngine = engine; | |
165 | return; | |
166 | } | |
167 | ||
168 | fatal("EventLoop::setPrimaryEngine: No such engine!."); | |
8ff3fa2e | 169 | } |
a553a5a3 | 170 | |
8ff3fa2e | 171 | void |
172 | EventLoop::setTimeService(TimeEngine *engine) | |
173 | { | |
174 | timeService = engine; | |
a553a5a3 | 175 | } |
176 | ||
177 | void | |
178 | EventLoop::stop() | |
179 | { | |
180 | last_loop = true; | |
181 | } |