]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/Kids.cc
e5bc1926cdd637b423daac4bbdb343e98542c727
[thirdparty/squid.git] / src / ipc / Kids.cc
1 /*
2 * Copyright (C) 1996-2019 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 /* DEBUG: section 54 Interprocess Communication */
10
11 #include "squid.h"
12 #include "base/TextException.h"
13 #include "globals.h"
14 #include "ipc/Kids.h"
15 #include "SquidConfig.h"
16 #include "tools.h"
17
18 Kids TheKids;
19 SBuf TheKidName;
20
21 Kids::Kids()
22 {
23 }
24
25 /// maintain n kids
26 void Kids::init()
27 {
28 storage.clear();
29
30 storage.reserve(NumberOfKids());
31
32 for (int i = 0; i < Config.workers; ++i)
33 storage.emplace_back("squid", storage.size() + 1);
34
35 // add Kid records for all disk processes
36 for (int i = 0; i < Config.cacheSwap.n_strands; ++i)
37 storage.emplace_back("squid-disk", storage.size() + 1);
38
39 // if coordination is needed, add a Kid record for Coordinator
40 if (storage.size() > 1)
41 storage.emplace_back("squid-coord", storage.size() + 1);
42
43 Must(storage.size() == static_cast<size_t>(NumberOfKids()));
44 }
45
46 /// returns kid by pid
47 Kid* Kids::find(pid_t pid)
48 {
49 assert(pid > 0);
50 assert(count() > 0);
51
52 for (size_t i = 0; i < storage.size(); ++i) {
53 if (storage[i].getPid() == pid)
54 return &storage[i];
55 }
56 return NULL;
57 }
58
59 /// returns the kid by index, useful for kids iteration
60 Kid& Kids::get(size_t i)
61 {
62 assert(i < count());
63 return storage[i];
64 }
65
66 /// whether all kids are hopeless
67 bool Kids::allHopeless() const
68 {
69 for (size_t i = 0; i < storage.size(); ++i) {
70 if (!storage[i].hopeless())
71 return false;
72 }
73 return true;
74 }
75
76 void
77 Kids::forgetAllFailures()
78 {
79 for (auto &kid: storage)
80 kid.forgetFailures();
81 }
82
83 time_t
84 Kids::forgetOldFailures()
85 {
86 time_t nextCheckDelay = 0;
87 for (auto &kid: storage) {
88 if (!kid.hopeless())
89 continue;
90
91 const auto deathDuration = kid.deathDuration(); // protect from time changes
92 if (Config.hopelessKidRevivalDelay <= deathDuration) {
93 kid.forgetFailures(); // this kid will be revived now
94 continue;
95 }
96
97 const auto remainingDeathTime = Config.hopelessKidRevivalDelay - deathDuration;
98 assert(remainingDeathTime > 0);
99 if (remainingDeathTime < nextCheckDelay || !nextCheckDelay)
100 nextCheckDelay = remainingDeathTime;
101 }
102 return nextCheckDelay; // still zero if there were no still-hopeless kids
103 }
104
105 /// whether all kids called exited happy
106 bool Kids::allExitedHappy() const
107 {
108 for (size_t i = 0; i < storage.size(); ++i) {
109 if (!storage[i].exitedHappy())
110 return false;
111 }
112 return true;
113 }
114
115 /// whether some kids died from a given signal
116 bool Kids::someSignaled(const int sgnl) const
117 {
118 for (size_t i = 0; i < storage.size(); ++i) {
119 if (storage[i].signaled(sgnl))
120 return true;
121 }
122 return false;
123 }
124
125 /// whether some kids are running
126 bool Kids::someRunning() const
127 {
128 for (size_t i = 0; i < storage.size(); ++i) {
129 if (storage[i].running())
130 return true;
131 }
132 return false;
133 }
134
135 /// whether some kids should be restarted by master
136 bool Kids::shouldRestartSome() const
137 {
138 for (size_t i = 0; i < storage.size(); ++i) {
139 if (storage[i].shouldRestart())
140 return true;
141 }
142 return false;
143 }
144
145 /// returns the number of kids
146 size_t Kids::count() const
147 {
148 return storage.size();
149 }
150