return true;
}
-/// whether all kids died from a given signal
-bool Kids::allSignaled(int sgnl) const
+/// whether some kids died from a given signal
+bool Kids::someSignaled(const int sgnl) const
{
for (size_t i = 0; i < storage.size(); ++i) {
- if (!storage[i].signaled(sgnl))
- return false;
+ if (storage[i].signaled(sgnl))
+ return true;
}
- return true;
+ return false;
+}
+
+/// whether some kids are running
+bool Kids::someRunning() const
+{
+ for (size_t i = 0; i < storage.size(); ++i) {
+ if (storage[i].running())
+ return true;
+ }
+ return false;
+}
+
+/// whether some kids should be restarted by master
+bool Kids::shouldRestartSome() const
+{
+ for (size_t i = 0; i < storage.size(); ++i) {
+ if (storage[i].shouldRestart())
+ return true;
+ }
+ return false;
}
/// returns the number of kids
/// whether all kids called exited happy
bool allExitedHappy() const;
- /// whether all kids died from a given signal
- bool allSignaled(int sgnl) const;
+ /// whether some kids died from a given signal
+ bool someSignaled(const int sgnl) const;
+
+ /// whether some kids are running
+ bool someRunning() const;
+
+ /// whether some kids should be restarted by master
+ bool shouldRestartSome() const;
/// returns the number of kids
size_t count() const;
shutdown_status = 1;
#endif
+
+ const pid_t ppid = getppid();
+
+ if (ppid > 1) {
+ // notify master that we are shutting down
+ if (kill(ppid, SIGUSR1) < 0)
+ debugs(1, DBG_IMPORTANT, "Failed to send SIGUSR1 to master process,"
+ " pid " << ppid << ": " << xstrerror());
+ }
+
#ifndef _SQUID_MSWIN_
#if KILL_PARENT_OPT
- if (getppid() > 1) {
- debugs(1, 1, "Killing master process, pid " << getppid());
+ if (ppid > 1) {
+ debugs(1, DBG_IMPORTANT, "Killing master process, pid " << ppid);
- if (kill(getppid(), sig) < 0)
- debugs(1, 1, "kill " << getppid() << ": " << xstrerror());
+ if (kill(ppid, sig) < 0)
+ debugs(1, DBG_IMPORTANT, "kill " << ppid << ": " << xstrerror());
}
#endif /* KILL_PARENT_OPT */
dup2(nullfd, 2);
}
+ // handle shutdown notifications from kids
+ squid_signal(SIGUSR1, sig_shutdown, SA_RESTART);
+
if (Config.workers > 128) {
syslog(LOG_ALERT, "Suspiciously high workers value: %d",
Config.workers);
// start each kid that needs to be [re]started; once
for (int i = TheKids.count() - 1; i >= 0; --i) {
Kid& kid = TheKids.get(i);
- if (kid.hopeless() || kid.exitedHappy() || kid.running())
+ if (!kid.shouldRestart())
continue;
if ((pid = fork()) == 0) {
} else {
syslog(LOG_NOTICE, "Squid Parent: child process %d exited", kid->getPid());
}
+ if (kid->hopeless()) {
+ syslog(LOG_NOTICE, "Squid Parent: child process %d will not"
+ " be restarted due to repeated, frequent failures",
+ kid->getPid());
+ }
} else {
syslog(LOG_NOTICE, "Squid Parent: unknown child process %d exited", pid);
}
while ((pid = waitpid(-1, &status, WNOHANG)) > 0);
#endif
- if (TheKids.allExitedHappy()) {
- exit(0);
- }
+ if (!TheKids.someRunning() && !TheKids.shouldRestartSome()) {
+ if (TheKids.someSignaled(SIGINT) || TheKids.someSignaled(SIGTERM)) {
+ syslog(LOG_ALERT, "Exiting due to unexpected forced shutdown");
+ exit(1);
+ }
- if (TheKids.allHopeless()) {
- syslog(LOG_ALERT, "Exiting due to repeated, frequent failures");
- exit(1);
- }
+ if (TheKids.allHopeless()) {
+ syslog(LOG_ALERT, "Exiting due to repeated, frequent failures");
+ exit(1);
+ }
- if (TheKids.allSignaled(SIGKILL)) {
exit(0);
}
- if (TheKids.allSignaled(SIGINT) || TheKids.allSignaled(SIGTERM)) {
- syslog(LOG_ALERT, "Exiting due to unexpected forced shutdown");
- exit(1);
- }
-
squid_signal(SIGINT, SIG_DFL, SA_RESTART);
sleep(3);
}