@@ -154,8 +154,9 @@ struct WaitEventSet
154154/* A common WaitEventSet used to implement WaitLatch() */
155155static WaitEventSet * LatchWaitSet ;
156156
157- /* The position of the latch in LatchWaitSet. */
157+ /* The positions of the latch and PM death events in LatchWaitSet */
158158#define LatchWaitSetLatchPos 0
159+ #define LatchWaitSetPostmasterDeathPos 1
159160
160161#ifndef WIN32
161162/* Are we currently in WaitLatch? The signal handler would like to know. */
@@ -353,11 +354,18 @@ InitializeLatchWaitSet(void)
353354 LatchWaitSet = CreateWaitEventSet (NULL , 2 );
354355 latch_pos = AddWaitEventToSet (LatchWaitSet , WL_LATCH_SET , PGINVALID_SOCKET ,
355356 MyLatch , NULL );
356- if (IsUnderPostmaster )
357- AddWaitEventToSet (LatchWaitSet , WL_EXIT_ON_PM_DEATH ,
358- PGINVALID_SOCKET , NULL , NULL );
359-
360357 Assert (latch_pos == LatchWaitSetLatchPos );
358+
359+ /*
360+ * WaitLatch will modify this to WL_EXIT_ON_PM_DEATH or
361+ * WL_POSTMASTER_DEATH on each call.
362+ */
363+ if (IsUnderPostmaster )
364+ {
365+ latch_pos = AddWaitEventToSet (LatchWaitSet , WL_EXIT_ON_PM_DEATH ,
366+ PGINVALID_SOCKET , NULL , NULL );
367+ Assert (latch_pos == LatchWaitSetPostmasterDeathPos );
368+ }
361369}
362370
363371/*
@@ -505,8 +513,9 @@ WaitLatch(Latch *latch, int wakeEvents, long timeout,
505513 if (!(wakeEvents & WL_LATCH_SET ))
506514 latch = NULL ;
507515 ModifyWaitEvent (LatchWaitSet , LatchWaitSetLatchPos , WL_LATCH_SET , latch );
508- LatchWaitSet -> exit_on_postmaster_death =
509- ((wakeEvents & WL_EXIT_ON_PM_DEATH ) != 0 );
516+ ModifyWaitEvent (LatchWaitSet , LatchWaitSetPostmasterDeathPos ,
517+ (wakeEvents & (WL_EXIT_ON_PM_DEATH | WL_POSTMASTER_DEATH )),
518+ NULL );
510519
511520 if (WaitEventSetWait (LatchWaitSet ,
512521 (wakeEvents & WL_TIMEOUT ) ? timeout : -1 ,
@@ -1027,6 +1036,21 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
10271036 old_events = event -> events ;
10281037#endif
10291038
1039+ /*
1040+ * Allow switching between WL_POSTMASTER_DEATH and WL_EXIT_ON_PM_DEATH.
1041+ *
1042+ * Note that because WL_EXIT_ON_PM_DEATH is mapped to WL_POSTMASTER_DEATH
1043+ * in AddWaitEventToSet(), this needs to be checked before the fast-path
1044+ * below that checks if 'events' has changed.
1045+ */
1046+ if (event -> events == WL_POSTMASTER_DEATH )
1047+ {
1048+ if (events != WL_POSTMASTER_DEATH && events != WL_EXIT_ON_PM_DEATH )
1049+ elog (ERROR , "cannot remove postmaster death event" );
1050+ set -> exit_on_postmaster_death = ((events & WL_EXIT_ON_PM_DEATH ) != 0 );
1051+ return ;
1052+ }
1053+
10301054 /*
10311055 * If neither the event mask nor the associated latch changes, return
10321056 * early. That's an important optimization for some sockets, where
@@ -1037,16 +1061,8 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
10371061 (!(event -> events & WL_LATCH_SET ) || set -> latch == latch ))
10381062 return ;
10391063
1040- if (event -> events & WL_LATCH_SET &&
1041- events != event -> events )
1042- {
1064+ if (event -> events & WL_LATCH_SET && events != event -> events )
10431065 elog (ERROR , "cannot modify latch event" );
1044- }
1045-
1046- if (event -> events & WL_POSTMASTER_DEATH )
1047- {
1048- elog (ERROR , "cannot modify postmaster death event" );
1049- }
10501066
10511067 /* FIXME: validate event mask */
10521068 event -> events = events ;
0 commit comments