}
/*
- * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer,
- * walwriter, autovacuum, archiver, slot sync worker, or background worker.
+ * Transition into FatalError state, in response to something bad having
+ * happened. Commonly the caller will have logged the reason for entering
+ * FatalError state.
*
- * The objectives here are to clean up our local state about the child
- * process, and to signal all other remaining children to quickdie.
- *
- * The caller has already released its PMChild slot.
+ * This should only be called when not already in FatalError or
+ * ImmediateShutdown state.
*/
static void
-HandleChildCrash(int pid, int exitstatus, const char *procname)
+HandleFatalError(QuitSignalReason reason, bool consider_sigabrt)
{
- /*
- * We only log messages and send signals if this is the first process
- * crash and we're not doing an immediate shutdown; otherwise, we're only
- * here to update postmaster's idea of live processes. If we have already
- * signaled children, nonzero exit status is to be expected, so don't
- * clutter log.
- */
- if (FatalError || Shutdown == ImmediateShutdown)
- return;
+ int sigtosend;
- LogChildExit(LOG, procname, pid, exitstatus);
- ereport(LOG,
- (errmsg("terminating any other active server processes")));
- SetQuitSignalReason(PMQUIT_FOR_CRASH);
+ Assert(!FatalError);
+ Assert(Shutdown != ImmediateShutdown);
+
+ SetQuitSignalReason(reason);
+
+ if (consider_sigabrt && send_abort_for_crash)
+ sigtosend = SIGABRT;
+ else
+ sigtosend = SIGQUIT;
/*
- * Signal all other child processes to exit. The crashed process has
- * already been removed from ActiveChildList.
+ * Signal all other child processes to exit.
*
* We could exclude dead-end children here, but at least when sending
* SIGABRT it seems better to include them.
*/
- TerminateChildren(send_abort_for_crash ? SIGABRT : SIGQUIT);
+ TerminateChildren(sigtosend);
FatalError = true;
AbortStartTime = time(NULL);
}
+/*
+ * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer,
+ * walwriter, autovacuum, archiver, slot sync worker, or background worker.
+ *
+ * The objectives here are to clean up our local state about the child
+ * process, and to signal all other remaining children to quickdie.
+ *
+ * The caller has already released its PMChild slot.
+ */
+static void
+HandleChildCrash(int pid, int exitstatus, const char *procname)
+{
+ /*
+ * We only log messages and send signals if this is the first process
+ * crash and we're not doing an immediate shutdown; otherwise, we're only
+ * here to update postmaster's idea of live processes. If we have already
+ * signaled children, nonzero exit status is to be expected, so don't
+ * clutter log.
+ */
+ if (FatalError || Shutdown == ImmediateShutdown)
+ return;
+
+ LogChildExit(LOG, procname, pid, exitstatus);
+ ereport(LOG,
+ (errmsg("terminating any other active server processes")));
+
+ /*
+ * Switch into error state. The crashed process has already been removed
+ * from ActiveChildList.
+ */
+ HandleFatalError(PMQUIT_FOR_CRASH, true);
+}
+
/*
* Log the death of a child process.
*/