]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/RunnersRegistry.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / base / RunnersRegistry.cc
CommitLineData
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
16typedef std::set<RegisteredRunner*> Runners;
17/// all known runners
18static Runners *TheRunners = NULL;
a27fcaed
CT
19/// used to avoid re-creating deleted TheRunners after shutdown finished.
20static 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 24static inline Runners *
a27fcaed 25FindRunners()
6d57128b 26{
a27fcaed 27 if (!TheRunners && !RunnersGone)
21b7990f 28 TheRunners = new Runners;
a27fcaed 29 return TheRunners;
6d57128b
AR
30}
31
a27fcaed
CT
32static inline void
33GetRidOfRunner(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
40static inline void
41RegisterRunner_(RegisteredRunner *rr)
42{
43 Runners *runners = FindRunners();
44 Must(runners);
45 runners->insert(rr);
46}
47
a27fcaed
CT
48bool
49RegisterRunner(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 63void
a27fcaed 64RunRegistered(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
95void
96IndependentRunner::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
103void
104IndependentRunner::registerRunner()
105{
106 if (FindRunners())
107 RegisterRunner_(this);
108 // else do nothing past finishShutdown
109}
110
6d57128b
AR
111bool
112UseThisStatic(const void *)
113{
114 return true;
115}
f53969cc 116