RunnersRegistry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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 
9 #include "squid.h"
10 #include "base/RunnersRegistry.h"
11 #include "base/TextException.h"
12 #include "debug/Stream.h"
13 #include <set>
14 
16 typedef std::set<RegisteredRunner*> Runners;
18 static Runners *TheRunners = nullptr;
20 static bool RunnersGone = false;
21 
24 static inline Runners *
26 {
27  if (!TheRunners && !RunnersGone)
28  TheRunners = new Runners;
29  return TheRunners;
30 }
31 
32 static inline void
34 {
35  if (!dynamic_cast<IndependentRunner*>(rr))
36  delete rr;
37  // else ignore; IndependentRunner
38 }
39 
40 static inline void
42 {
43  Runners *runners = FindRunners();
44  Must(runners);
45  runners->insert(rr);
46 }
47 
48 bool
50 {
51  Must(!dynamic_cast<IndependentRunner*>(rr));
52 
53  if (FindRunners()) {
54  RegisterRunner_(rr);
55  return true;
56  }
57 
58  // past finishShutdown
59  GetRidOfRunner(rr);
60  return false;
61 }
62 
63 void
65 {
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  }
77  }
78 
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
97 {
98  if (Runners *runners = FindRunners())
99  runners->erase(this);
100  // else it is too late, finishShutdown() has been called
101 }
102 
103 void
105 {
106  if (FindRunners())
107  RegisterRunner_(this);
108  // else do nothing past finishShutdown
109 }
110 
A RegisteredRunner with lifetime determined by forces outside the Registry.
static bool RunnersGone
used to avoid re-creating deleted TheRunners after shutdown finished.
void unregisterRunner()
unregisters self; safe to call multiple times
void RunRegistered(const RegisteredRunner::Method &event)
static void GetRidOfRunner(RegisteredRunner *rr)
static void RegisterRunner_(RegisteredRunner *rr)
static Runners * TheRunners
all known runners
static Runners * FindRunners()
virtual void finishShutdown()
Meant for cleanup of services needed by the already destroyed objects.
#define Must(condition)
Definition: TextException.h:75
std::set< RegisteredRunner * > Runners
a collection of unique runners, in no particular order
bool RegisterRunner(RegisteredRunner *rr)
registers a given runner with the given registry and returns true on success
void(RegisteredRunner::* Method)()
a pointer to one of the above notification methods

 

Introduction

Documentation

Support

Miscellaneous