@@ -154,8 +154,9 @@ struct WaitEventSet
154
154
/* A common WaitEventSet used to implement WaitLatch() */
155
155
static WaitEventSet * LatchWaitSet ;
156
156
157
- /* The position of the latch in LatchWaitSet. */
157
+ /* The positions of the latch and PM death events in LatchWaitSet */
158
158
#define LatchWaitSetLatchPos 0
159
+ #define LatchWaitSetPostmasterDeathPos 1
159
160
160
161
#ifndef WIN32
161
162
/* Are we currently in WaitLatch? The signal handler would like to know. */
@@ -353,11 +354,18 @@ InitializeLatchWaitSet(void)
353
354
LatchWaitSet = CreateWaitEventSet (NULL , 2 );
354
355
latch_pos = AddWaitEventToSet (LatchWaitSet , WL_LATCH_SET , PGINVALID_SOCKET ,
355
356
MyLatch , NULL );
356
- if (IsUnderPostmaster )
357
- AddWaitEventToSet (LatchWaitSet , WL_EXIT_ON_PM_DEATH ,
358
- PGINVALID_SOCKET , NULL , NULL );
359
-
360
357
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
+ }
361
369
}
362
370
363
371
/*
@@ -505,8 +513,9 @@ WaitLatch(Latch *latch, int wakeEvents, long timeout,
505
513
if (!(wakeEvents & WL_LATCH_SET ))
506
514
latch = NULL ;
507
515
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 );
510
519
511
520
if (WaitEventSetWait (LatchWaitSet ,
512
521
(wakeEvents & WL_TIMEOUT ) ? timeout : -1 ,
@@ -1027,6 +1036,21 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
1027
1036
old_events = event -> events ;
1028
1037
#endif
1029
1038
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
+
1030
1054
/*
1031
1055
* If neither the event mask nor the associated latch changes, return
1032
1056
* early. That's an important optimization for some sockets, where
@@ -1037,16 +1061,8 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
1037
1061
(!(event -> events & WL_LATCH_SET ) || set -> latch == latch ))
1038
1062
return ;
1039
1063
1040
- if (event -> events & WL_LATCH_SET &&
1041
- events != event -> events )
1042
- {
1064
+ if (event -> events & WL_LATCH_SET && events != event -> events )
1043
1065
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
- }
1050
1066
1051
1067
/* FIXME: validate event mask */
1052
1068
event -> events = events ;
0 commit comments