]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/Kid.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / ipc / Kid.cc
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 /* DEBUG: section 54 Interprocess Communication */
10
11 #include "squid.h"
12 #include "globals.h"
13 #include "ipc/Kid.h"
14 #include "SquidConfig.h"
15
16 #include <ctime>
17 #if HAVE_SYS_WAIT_H
18 #include <sys/wait.h>
19 #endif
20
21 int TheProcessKind = pkOther;
22
23 Kid::Kid()
24 {
25 }
26
27 Kid::Kid(const char *aRole, const int anId):
28 processRole(aRole),
29 processId(anId)
30 {
31 }
32
33 /// called when this kid got started, records PID
34 void Kid::start(pid_t cpid)
35 {
36 assert(!running());
37 assert(cpid > 0);
38
39 isRunning = true;
40 stopTime = 0;
41 pid = cpid;
42 startTime = squid_curtime;
43 }
44
45 /// called when kid terminates, sets exiting status
46 void
47 Kid::stop(PidStatus const theExitStatus)
48 {
49 assert(running());
50 assert(startTime != 0);
51
52 isRunning = false;
53 stopTime = squid_curtime;
54 status = theExitStatus;
55
56 if ((stopTime - startTime) < fastFailureTimeLimit)
57 ++badFailures;
58 else
59 badFailures = 0; // the failures are not "frequent" [any more]
60
61 reportStopped(); // after all state changes
62 }
63
64 /// describes a recently stopped kid
65 void
66 Kid::reportStopped() const
67 {
68 if (calledExit()) {
69 syslog(LOG_NOTICE,
70 "Squid Parent: %s process %d exited with status %d",
71 gist().c_str(), pid, exitStatus());
72 } else if (signaled()) {
73 syslog(LOG_NOTICE,
74 "Squid Parent: %s process %d exited due to signal %d with status %d",
75 gist().c_str(), pid, termSignal(), exitStatus());
76 } else {
77 syslog(LOG_NOTICE, "Squid Parent: %s process %d exited",
78 gist().c_str(), pid);
79 }
80
81 if (hopeless() && Config.hopelessKidRevivalDelay) {
82 syslog(LOG_NOTICE, "Squid Parent: %s process %d will not be restarted for %ld "
83 "seconds due to repeated, frequent failures",
84 gist().c_str(),
85 pid,
86 static_cast<long int>(Config.hopelessKidRevivalDelay));
87 }
88 }
89
90 /// returns true if tracking of kid is stopped
91 bool Kid::running() const
92 {
93 return isRunning;
94 }
95
96 /// returns true if master process should restart this kid
97 bool Kid::shouldRestart() const
98 {
99 return !(running() ||
100 exitedHappy() ||
101 hopeless() ||
102 shutting_down ||
103 signaled(SIGINT) || // unexpected forced shutdown
104 signaled(SIGTERM)); // unexpected forced shutdown
105 }
106
107 /// returns current pid for a running kid and last pid for a stopped kid
108 pid_t Kid::getPid() const
109 {
110 assert(pid > 0);
111 return pid;
112 }
113
114 /// whether the failures are "repeated and frequent"
115 bool Kid::hopeless() const
116 {
117 return badFailures > badFailureLimit;
118 }
119
120 /// returns true if the process terminated normally
121 bool Kid::calledExit() const
122 {
123 return (pid > 0) && !running() && WIFEXITED(status);
124 }
125
126 /// returns the exit status of the process
127 int Kid::exitStatus() const
128 {
129 return WEXITSTATUS(status);
130 }
131
132 /// whether the process exited with a given exit status code
133 bool Kid::calledExit(int code) const
134 {
135 return calledExit() && (exitStatus() == code);
136 }
137
138 /// whether the process exited with code 0
139 bool Kid::exitedHappy() const
140 {
141 return calledExit(0);
142 }
143
144 /// returns true if the kid was terminated by a signal
145 bool Kid::signaled() const
146 {
147 return (pid > 0) && !running() && WIFSIGNALED(status);
148 }
149
150 /// returns the number of the signal that caused the kid to terminate
151 int Kid::termSignal() const
152 {
153 return WTERMSIG(status);
154 }
155
156 /// whether the process was terminated by a given signal
157 bool Kid::signaled(int sgnl) const
158 {
159 return signaled() && (termSignal() == sgnl);
160 }
161
162 /// returns kid name
163 SBuf Kid::processName() const
164 {
165 SBuf name("(");
166 name.append(gist());
167 name.append(")");
168 return name;
169 }
170
171 SBuf Kid::gist() const
172 {
173 SBuf name(processRole);
174 name.appendf("-%d", processId);
175 return name;
176 }
177
178 time_t
179 Kid::deathDuration() const
180 {
181 return squid_curtime > stopTime ? squid_curtime - stopTime : 0;
182 }
183