]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Use ModifyWaitEvent to update exit_on_postmaster_death
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 5 Mar 2025 23:26:12 +0000 (01:26 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 5 Mar 2025 23:26:12 +0000 (01:26 +0200)
This is in preparation for splitting WaitEventSet related functions to
a separate source file. That will hide the details of WaitEventSet
from WaitLatch, so it must use an exposed function instead of
modifying WaitEventSet->exit_on_postmaster_death directly.

Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://www.postgresql.org/message-id/8a507fb6-df28-49d3-81a5-ede180d7f0fb@iki.fi

src/backend/storage/ipc/latch.c

index cd09a10f3d118056ed47198b3f3248b61d31416e..997bcb58ff75091ae67019481631ce7b1265894d 100644 (file)
@@ -154,8 +154,9 @@ struct WaitEventSet
 /* A common WaitEventSet used to implement WaitLatch() */
 static WaitEventSet *LatchWaitSet;
 
-/* The position of the latch in LatchWaitSet. */
+/* The positions of the latch and PM death events in LatchWaitSet */
 #define LatchWaitSetLatchPos 0
+#define LatchWaitSetPostmasterDeathPos 1
 
 #ifndef WIN32
 /* Are we currently in WaitLatch? The signal handler would like to know. */
@@ -353,11 +354,18 @@ InitializeLatchWaitSet(void)
        LatchWaitSet = CreateWaitEventSet(NULL, 2);
        latch_pos = AddWaitEventToSet(LatchWaitSet, WL_LATCH_SET, PGINVALID_SOCKET,
                                                                  MyLatch, NULL);
-       if (IsUnderPostmaster)
-               AddWaitEventToSet(LatchWaitSet, WL_EXIT_ON_PM_DEATH,
-                                                 PGINVALID_SOCKET, NULL, NULL);
-
        Assert(latch_pos == LatchWaitSetLatchPos);
+
+       /*
+        * WaitLatch will modify this to WL_EXIT_ON_PM_DEATH or
+        * WL_POSTMASTER_DEATH on each call.
+        */
+       if (IsUnderPostmaster)
+       {
+               latch_pos = AddWaitEventToSet(LatchWaitSet, WL_EXIT_ON_PM_DEATH,
+                                                                         PGINVALID_SOCKET, NULL, NULL);
+               Assert(latch_pos == LatchWaitSetPostmasterDeathPos);
+       }
 }
 
 /*
@@ -505,8 +513,9 @@ WaitLatch(Latch *latch, int wakeEvents, long timeout,
        if (!(wakeEvents & WL_LATCH_SET))
                latch = NULL;
        ModifyWaitEvent(LatchWaitSet, LatchWaitSetLatchPos, WL_LATCH_SET, latch);
-       LatchWaitSet->exit_on_postmaster_death =
-               ((wakeEvents & WL_EXIT_ON_PM_DEATH) != 0);
+       ModifyWaitEvent(LatchWaitSet, LatchWaitSetPostmasterDeathPos,
+                                       (wakeEvents & (WL_EXIT_ON_PM_DEATH | WL_POSTMASTER_DEATH)),
+                                       NULL);
 
        if (WaitEventSetWait(LatchWaitSet,
                                                 (wakeEvents & WL_TIMEOUT) ? timeout : -1,
@@ -1027,6 +1036,21 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
        old_events = event->events;
 #endif
 
+       /*
+        * Allow switching between WL_POSTMASTER_DEATH and WL_EXIT_ON_PM_DEATH.
+        *
+        * Note that because WL_EXIT_ON_PM_DEATH is mapped to WL_POSTMASTER_DEATH
+        * in AddWaitEventToSet(), this needs to be checked before the fast-path
+        * below that checks if 'events' has changed.
+        */
+       if (event->events == WL_POSTMASTER_DEATH)
+       {
+               if (events != WL_POSTMASTER_DEATH && events != WL_EXIT_ON_PM_DEATH)
+                       elog(ERROR, "cannot remove postmaster death event");
+               set->exit_on_postmaster_death = ((events & WL_EXIT_ON_PM_DEATH) != 0);
+               return;
+       }
+
        /*
         * If neither the event mask nor the associated latch changes, return
         * early. That's an important optimization for some sockets, where
@@ -1037,16 +1061,8 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
                (!(event->events & WL_LATCH_SET) || set->latch == latch))
                return;
 
-       if (event->events & WL_LATCH_SET &&
-               events != event->events)
-       {
+       if (event->events & WL_LATCH_SET && events != event->events)
                elog(ERROR, "cannot modify latch event");
-       }
-
-       if (event->events & WL_POSTMASTER_DEATH)
-       {
-               elog(ERROR, "cannot modify postmaster death event");
-       }
 
        /* FIXME: validate event mask */
        event->events = events;