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