Make WL_POSTMASTER_DEATH level-triggered on kqueue builds.

If WaitEventSetWait() reports that the postmaster has gone away, later
calls to WaitEventSetWait() should continue to report that.  Otherwise
further waits that occur in the proc_exit() path after we already
noticed the postmaster's demise could block forever.

Back-patch to 13, where the kqueue support landed.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/3624029.1602701929%40sss.pgh.pa.us
This commit is contained in:
Thomas Munro 2020-10-15 11:31:20 +13:00
parent a04daa97a4
commit b94109ce37
1 changed files with 11 additions and 1 deletions

View File

@ -1492,7 +1492,10 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
timeout_p = &timeout;
}
/* Report events discovered by WaitEventAdjustKqueue(). */
/*
* Report postmaster events discovered by WaitEventAdjustKqueue() or an
* earlier call to WaitEventSetWait().
*/
if (unlikely(set->report_postmaster_not_running))
{
if (set->exit_on_postmaster_death)
@ -1563,6 +1566,13 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
cur_kqueue_event->filter == EVFILT_PROC &&
(cur_kqueue_event->fflags & NOTE_EXIT) != 0)
{
/*
* The kernel will tell this kqueue object only once about the exit
* of the postmaster, so let's remember that for next time so that
* we provide level-triggered semantics.
*/
set->report_postmaster_not_running = true;
if (set->exit_on_postmaster_death)
proc_exit(1);
occurred_events->fd = PGINVALID_SOCKET;