Make WL_POSTMASTER_DEATH level-triggered on kqueue builds.
authorThomas Munro <tmunro@postgresql.org>
Wed, 14 Oct 2020 22:31:20 +0000 (11:31 +1300)
committerThomas Munro <tmunro@postgresql.org>
Wed, 14 Oct 2020 22:41:58 +0000 (11:41 +1300)
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

src/backend/storage/ipc/latch.c

index 63c6c97536013a1fd345024d063064c518759bba..eacb8c3c9ee9bb41b73d2ee68d3122fb91a0be3b 100644 (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;