]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
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. | |
7 | */ | |
8 | ||
f7f3304a | 9 | #include "squid.h" |
6d57128b | 10 | #include "base/RunnersRegistry.h" |
b856803f | 11 | #include "base/TextException.h" |
ebaabe74 | 12 | #include "Debug.h" |
21b7990f | 13 | #include <set> |
6d57128b | 14 | |
21b7990f AR |
15 | /// a collection of unique runners, in no particular order |
16 | typedef std::set<RegisteredRunner*> Runners; | |
17 | /// all known runners | |
18 | static Runners *TheRunners = NULL; | |
a27fcaed CT |
19 | /// used to avoid re-creating deleted TheRunners after shutdown finished. |
20 | static bool RunnersGone = false; | |
6d57128b | 21 | |
a27fcaed CT |
22 | /// creates the registered runners container if needed |
23 | /// \return either registered runners (if they should exist) or nil (otherwise) | |
b856803f | 24 | static inline Runners * |
a27fcaed | 25 | FindRunners() |
6d57128b | 26 | { |
a27fcaed | 27 | if (!TheRunners && !RunnersGone) |
21b7990f | 28 | TheRunners = new Runners; |
a27fcaed | 29 | return TheRunners; |
6d57128b AR |
30 | } |
31 | ||
a27fcaed CT |
32 | static inline void |
33 | GetRidOfRunner(RegisteredRunner *rr) | |
6d57128b | 34 | { |
a27fcaed CT |
35 | if (!dynamic_cast<IndependentRunner*>(rr)) |
36 | delete rr; | |
d39a7c59 | 37 | // else ignore; IndependentRunner |
6d57128b AR |
38 | } |
39 | ||
b856803f CT |
40 | static inline void |
41 | RegisterRunner_(RegisteredRunner *rr) | |
42 | { | |
43 | Runners *runners = FindRunners(); | |
44 | Must(runners); | |
45 | runners->insert(rr); | |
46 | } | |
47 | ||
a27fcaed CT |
48 | bool |
49 | RegisterRunner(RegisteredRunner *rr) | |
d442618d | 50 | { |
b856803f CT |
51 | Must(!dynamic_cast<IndependentRunner*>(rr)); |
52 | ||
53 | if (FindRunners()) { | |
54 | RegisterRunner_(rr); | |
a27fcaed CT |
55 | return true; |
56 | } | |
57 | ||
58 | // past finishShutdown | |
59 | GetRidOfRunner(rr); | |
60 | return false; | |
d442618d AJ |
61 | } |
62 | ||
21b7990f | 63 | void |
a27fcaed | 64 | RunRegistered(const RegisteredRunner::Method &event) |
6d57128b | 65 | { |
a27fcaed CT |
66 | if (Runners *runners = FindRunners()) { |
67 | // Many things may happen during the loop below. We copy to withstand | |
68 | // runner removal/addition and avoid surprises due to registrations from | |
69 | // parent constructors (with a half-baked "this"!). This copy also | |
70 | // simplifies overall RR logic as it guarantees that registering a | |
71 | // runner during event X loop does not execute runner::X(). | |
72 | Runners oldRunners(*runners); | |
73 | for (auto runner: oldRunners) { | |
74 | if (runners->find(runner) != runners->end()) // still registered | |
75 | (runner->*event)(); | |
76 | } | |
6d57128b | 77 | } |
a27fcaed CT |
78 | |
79 | if (event != &RegisteredRunner::finishShutdown) | |
80 | return; | |
81 | ||
82 | // this is the last event; delete registry-dependent runners (and only them) | |
83 | if (Runners *runners = FindRunners()) { | |
84 | RunnersGone = true; | |
85 | TheRunners = nullptr; | |
86 | // from now on, no runners can be registered or unregistered | |
87 | for (auto runner: *runners) | |
88 | GetRidOfRunner(runner); // leaves a dangling pointer in runners | |
89 | delete runners; | |
90 | } | |
91 | } | |
92 | ||
93 | /* IndependentRunner */ | |
94 | ||
95 | void | |
96 | IndependentRunner::unregisterRunner() | |
97 | { | |
98 | if (Runners *runners = FindRunners()) | |
99 | runners->erase(this); | |
100 | // else it is too late, finishShutdown() has been called | |
6d57128b AR |
101 | } |
102 | ||
b856803f CT |
103 | void |
104 | IndependentRunner::registerRunner() | |
105 | { | |
106 | if (FindRunners()) | |
107 | RegisterRunner_(this); | |
108 | // else do nothing past finishShutdown | |
109 | } | |
110 | ||
6d57128b AR |
111 | bool |
112 | UseThisStatic(const void *) | |
113 | { | |
114 | return true; | |
115 | } | |
f53969cc | 116 |