aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r---0
-rw-r--r--contrib/pg_prewarm/autoprewarm.c8
-rw-r--r--contrib/postgres_fdw/connection.c6
-rw-r--r--src/backend/access/transam/parallel.c10
-rw-r--r--src/backend/access/transam/xlog.c23
-rw-r--r--src/backend/access/transam/xlogfuncs.c8
-rw-r--r--src/backend/executor/nodeGather.c3
-rw-r--r--src/backend/libpq/be-secure-openssl.c4
-rw-r--r--src/backend/libpq/pqmq.c4
-rw-r--r--src/backend/postmaster/autovacuum.c16
-rw-r--r--src/backend/postmaster/bgwriter.c11
-rw-r--r--src/backend/postmaster/checkpointer.c16
-rw-r--r--src/backend/postmaster/pgarch.c4
-rw-r--r--src/backend/postmaster/syslogger.c38
-rw-r--r--src/backend/postmaster/walwriter.c16
-rw-r--r--src/backend/replication/basebackup.c2
-rw-r--r--src/backend/replication/libpqwalreceiver/libpqwalreceiver.c13
-rw-r--r--src/backend/replication/logical/launcher.c24
-rw-r--r--src/backend/replication/logical/tablesync.c30
-rw-r--r--src/backend/replication/logical/worker.c6
-rw-r--r--src/backend/replication/syncrep.c18
-rw-r--r--src/backend/replication/walreceiver.c22
-rw-r--r--src/backend/replication/walsender.c49
-rw-r--r--src/backend/storage/ipc/latch.c38
-rw-r--r--src/backend/storage/ipc/shm_mq.c9
-rw-r--r--src/backend/storage/lmgr/condition_variable.c14
-rw-r--r--src/backend/storage/lmgr/proc.c7
-rw-r--r--src/backend/utils/adt/misc.c2
-rw-r--r--src/include/storage/latch.h3
-rw-r--r--src/test/modules/test_shm_mq/setup.c3
-rw-r--r--src/test/modules/test_shm_mq/test.c3
-rw-r--r--src/test/modules/worker_spi/worker_spi.c6
32 files changed, 174 insertions, 242 deletions
diff --git a/- b/-
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/-
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 03bf90ce2d8..c2a6e5a53f7 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -220,7 +220,7 @@ autoprewarm_main(Datum main_arg)
{
/* We're only dumping at shutdown, so just wait forever. */
rc = WaitLatch(&MyProc->procLatch,
- WL_LATCH_SET | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
-1L,
PG_WAIT_EXTENSION);
}
@@ -249,15 +249,13 @@ autoprewarm_main(Datum main_arg)
/* Sleep until the next dump time. */
rc = WaitLatch(&MyProc->procLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
delay_in_ms,
PG_WAIT_EXTENSION);
}
- /* Reset the latch, bail out if postmaster died, otherwise loop. */
+ /* Reset the latch, loop. */
ResetLatch(&MyProc->procLatch);
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
}
/*
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index fe4893a8e05..a6509932dcf 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -546,7 +546,8 @@ pgfdw_get_result(PGconn *conn, const char *query)
/* Sleep until there's something to do */
wc = WaitLatchOrSocket(MyLatch,
- WL_LATCH_SET | WL_SOCKET_READABLE,
+ WL_LATCH_SET | WL_SOCKET_READABLE |
+ WL_EXIT_ON_PM_DEATH,
PQsocket(conn),
-1L, PG_WAIT_EXTENSION);
ResetLatch(MyLatch);
@@ -1152,7 +1153,8 @@ pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result)
/* Sleep until there's something to do */
wc = WaitLatchOrSocket(MyLatch,
- WL_LATCH_SET | WL_SOCKET_READABLE | WL_TIMEOUT,
+ WL_LATCH_SET | WL_SOCKET_READABLE |
+ WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
PQsocket(conn),
cur_timeout, PG_WAIT_EXTENSION);
ResetLatch(MyLatch);
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 84197192ec2..b9a9ae5c73c 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -692,13 +692,9 @@ WaitForParallelWorkersToAttach(ParallelContext *pcxt)
* just end up waiting for the same worker again.
*/
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
-1, WAIT_EVENT_BGWORKER_STARTUP);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
ResetLatch(MyLatch);
}
@@ -815,8 +811,8 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt)
}
}
- WaitLatch(MyLatch, WL_LATCH_SET, -1,
- WAIT_EVENT_PARALLEL_FINISH);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, -1,
+ WAIT_EVENT_PARALLEL_FINISH);
ResetLatch(MyLatch);
}
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 80616c5f1e7..7397b6ee06b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6189,10 +6189,10 @@ recoveryApplyDelay(XLogReaderState *record)
elog(DEBUG2, "recovery apply delay %ld seconds, %d milliseconds",
secs, microsecs / 1000);
- WaitLatch(&XLogCtl->recoveryWakeupLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- secs * 1000L + microsecs / 1000,
- WAIT_EVENT_RECOVERY_APPLY_DELAY);
+ (void) WaitLatch(&XLogCtl->recoveryWakeupLatch,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
+ secs * 1000L + microsecs / 1000,
+ WAIT_EVENT_RECOVERY_APPLY_DELAY);
}
return true;
}
@@ -12093,9 +12093,11 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
wait_time = wal_retrieve_retry_interval -
(secs * 1000 + usecs / 1000);
- WaitLatch(&XLogCtl->recoveryWakeupLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- wait_time, WAIT_EVENT_RECOVERY_WAL_STREAM);
+ (void) WaitLatch(&XLogCtl->recoveryWakeupLatch,
+ WL_LATCH_SET | WL_TIMEOUT |
+ WL_EXIT_ON_PM_DEATH,
+ wait_time,
+ WAIT_EVENT_RECOVERY_WAL_STREAM);
ResetLatch(&XLogCtl->recoveryWakeupLatch);
now = GetCurrentTimestamp();
}
@@ -12269,9 +12271,10 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
* Wait for more WAL to arrive. Time out after 5 seconds
* to react to a trigger file promptly.
*/
- WaitLatch(&XLogCtl->recoveryWakeupLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- 5000L, WAIT_EVENT_RECOVERY_WAL_ALL);
+ (void) WaitLatch(&XLogCtl->recoveryWakeupLatch,
+ WL_LATCH_SET | WL_TIMEOUT |
+ WL_EXIT_ON_PM_DEATH,
+ 5000L, WAIT_EVENT_RECOVERY_WAL_ALL);
ResetLatch(&XLogCtl->recoveryWakeupLatch);
break;
}
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index bd18f496af1..f139eeff9ff 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -764,10 +764,10 @@ pg_promote(PG_FUNCTION_ARGS)
CHECK_FOR_INTERRUPTS();
- WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- 1000L / WAITS_PER_SECOND,
- WAIT_EVENT_PROMOTE);
+ (void) WaitLatch(MyLatch,
+ WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ 1000L / WAITS_PER_SECOND,
+ WAIT_EVENT_PROMOTE);
}
ereport(WARNING,
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index c979a557749..e6367ade76d 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -383,7 +383,8 @@ gather_readnext(GatherState *gatherstate)
return NULL;
/* Nothing to do except wait for developments. */
- WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_EXECUTE_GATHER);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ WAIT_EVENT_EXECUTE_GATHER);
ResetLatch(MyLatch);
nvisited = 0;
}
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index a910ea2cb40..2ca11c24099 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -410,8 +410,8 @@ aloop:
else
waitfor = WL_SOCKET_WRITEABLE;
- WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
- WAIT_EVENT_SSL_OPEN_SERVER);
+ (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
+ WAIT_EVENT_SSL_OPEN_SERVER);
goto aloop;
case SSL_ERROR_SYSCALL:
if (r < 0)
diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 6eaed5bf0cf..603d9016fd8 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -168,8 +168,8 @@ mq_putmessage(char msgtype, const char *s, size_t len)
if (result != SHM_MQ_WOULD_BLOCK)
break;
- WaitLatch(MyLatch, WL_LATCH_SET, 0,
- WAIT_EVENT_MQ_PUT_MESSAGE);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ WAIT_EVENT_MQ_PUT_MESSAGE);
ResetLatch(MyLatch);
CHECK_FOR_INTERRUPTS();
}
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 31e98db9d69..2d5086d4062 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -628,7 +628,6 @@ AutoVacLauncherMain(int argc, char *argv[])
struct timeval nap;
TimestampTz current_time = 0;
bool can_launch;
- int rc;
/*
* This loop is a bit different from the normal use of WaitLatch,
@@ -644,23 +643,16 @@ AutoVacLauncherMain(int argc, char *argv[])
* Wait until naptime expires or we get some type of signal (all the
* signal handlers will wake us by calling SetLatch).
*/
- rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L),
- WAIT_EVENT_AUTOVACUUM_MAIN);
+ (void) WaitLatch(MyLatch,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
+ (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L),
+ WAIT_EVENT_AUTOVACUUM_MAIN);
ResetLatch(MyLatch);
/* Process sinval catchup interrupts that happened while sleeping */
ProcessCatchupInterrupt();
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
/* the normal shutdown case */
if (got_SIGTERM)
break;
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 54a042843da..bd8dc61182d 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -335,7 +335,7 @@ BackgroundWriterMain(void)
* normal operation.
*/
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
BgWriterDelay /* ms */ , WAIT_EVENT_BGWRITER_MAIN);
/*
@@ -362,20 +362,13 @@ BackgroundWriterMain(void)
StrategyNotifyBgWriter(MyProc->pgprocno);
/* Sleep ... */
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
BgWriterDelay * HIBERNATE_FACTOR,
WAIT_EVENT_BGWRITER_HIBERNATE);
/* Reset the notification request in case we timed out */
StrategyNotifyBgWriter(-1);
}
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (rc & WL_POSTMASTER_DEATH)
- exit(1);
-
prev_hibernate = can_hibernate;
}
}
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 9eac86b554b..b9c118e1560 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -340,7 +340,6 @@ CheckpointerMain(void)
pg_time_t now;
int elapsed_secs;
int cur_timeout;
- int rc;
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
@@ -541,17 +540,10 @@ CheckpointerMain(void)
cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs);
}
- rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- cur_timeout * 1000L /* convert to ms */ ,
- WAIT_EVENT_CHECKPOINTER_MAIN);
-
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (rc & WL_POSTMASTER_DEATH)
- exit(1);
+ (void) WaitLatch(MyLatch,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
+ cur_timeout * 1000L /* convert to ms */ ,
+ WAIT_EVENT_CHECKPOINTER_MAIN);
}
}
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 0ebd63650c6..844b9d1b0e9 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -390,6 +390,8 @@ pgarch_MainLoop(void)
WAIT_EVENT_ARCHIVER_MAIN);
if (rc & WL_TIMEOUT)
wakened = true;
+ if (rc & WL_POSTMASTER_DEATH)
+ time_to_stop = true;
}
else
wakened = true;
@@ -400,7 +402,7 @@ pgarch_MainLoop(void)
* or after completing one more archiving cycle after receiving
* SIGUSR2.
*/
- } while (PostmasterIsAlive() && !time_to_stop);
+ } while (!time_to_stop);
}
/*
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index 35755138890..fbeee311092 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -168,6 +168,7 @@ SysLoggerMain(int argc, char *argv[])
char *currentLogFilename;
int currentLogRotationAge;
pg_time_t now;
+ WaitEventSet *wes;
now = MyStartTime;
@@ -294,13 +295,29 @@ SysLoggerMain(int argc, char *argv[])
*/
whereToSendOutput = DestNone;
+ /*
+ * Set up a reusable WaitEventSet object we'll use to wait for our latch,
+ * and (except on Windows) our socket.
+ *
+ * Unlike all other postmaster child processes, we'll ignore postmaster
+ * death because we want to collect final log output from all backends and
+ * then exit last. We'll do that by running until we see EOF on the
+ * syslog pipe, which implies that all other backends have exited
+ * (including the postmaster).
+ */
+ wes = CreateWaitEventSet(CurrentMemoryContext, 2);
+ AddWaitEventToSet(wes, WL_LATCH_SET, PGINVALID_SOCKET, MyLatch, NULL);
+#ifndef WIN32
+ AddWaitEventToSet(wes, WL_SOCKET_READABLE, syslogPipe[0], NULL, NULL);
+#endif
+
/* main worker loop */
for (;;)
{
bool time_based_rotation = false;
int size_rotation_for = 0;
long cur_timeout;
- int cur_flags;
+ WaitEvent event;
#ifndef WIN32
int rc;
@@ -436,25 +453,18 @@ SysLoggerMain(int argc, char *argv[])
}
else
cur_timeout = 0;
- cur_flags = WL_TIMEOUT;
}
else
- {
cur_timeout = -1L;
- cur_flags = 0;
- }
/*
* Sleep until there's something to do
*/
#ifndef WIN32
- rc = WaitLatchOrSocket(MyLatch,
- WL_LATCH_SET | WL_SOCKET_READABLE | cur_flags,
- syslogPipe[0],
- cur_timeout,
- WAIT_EVENT_SYSLOGGER_MAIN);
+ rc = WaitEventSetWait(wes, cur_timeout, &event, 1,
+ WAIT_EVENT_SYSLOGGER_MAIN);
- if (rc & WL_SOCKET_READABLE)
+ if (rc == 1 && event.events == WL_SOCKET_READABLE)
{
int bytesRead;
@@ -501,10 +511,8 @@ SysLoggerMain(int argc, char *argv[])
*/
LeaveCriticalSection(&sysloggerSection);
- (void) WaitLatch(MyLatch,
- WL_LATCH_SET | cur_flags,
- cur_timeout,
- WAIT_EVENT_SYSLOGGER_MAIN);
+ (void) WaitEventSetWait(wes, cur_timeout, &event, 1,
+ WAIT_EVENT_SYSLOGGER_MAIN);
EnterCriticalSection(&sysloggerSection);
#endif /* WIN32 */
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 3e09827854d..0ae733e886a 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -223,7 +223,6 @@ WalWriterMain(void)
for (;;)
{
long cur_timeout;
- int rc;
/*
* Advertise whether we might hibernate in this cycle. We do this
@@ -276,17 +275,10 @@ WalWriterMain(void)
else
cur_timeout = WalWriterDelay * HIBERNATE_FACTOR;
- rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- cur_timeout,
- WAIT_EVENT_WAL_WRITER_MAIN);
-
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (rc & WL_POSTMASTER_DEATH)
- exit(1);
+ (void) WaitLatch(MyLatch,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
+ cur_timeout,
+ WAIT_EVENT_WAL_WRITER_MAIN);
}
}
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index b20f6c379c6..a7e3db27832 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1686,7 +1686,7 @@ throttle(size_t increment)
* the maximum time to sleep. Thus the cast to long is safe.
*/
wait_result = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
(long) (sleep / 1000),
WAIT_EVENT_BASE_BACKUP_THROTTLE);
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index e2b54265d78..9b75711ebd6 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -186,16 +186,11 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
io_flag = WL_SOCKET_WRITEABLE;
rc = WaitLatchOrSocket(MyLatch,
- WL_POSTMASTER_DEATH |
- WL_LATCH_SET | io_flag,
+ WL_EXIT_ON_PM_DEATH | WL_LATCH_SET | io_flag,
PQsocket(conn->streamConn),
0,
WAIT_EVENT_LIBPQWALRECEIVER_CONNECT);
- /* Emergency bailout? */
- if (rc & WL_POSTMASTER_DEATH)
- exit(1);
-
/* Interrupted? */
if (rc & WL_LATCH_SET)
{
@@ -610,16 +605,12 @@ libpqrcv_PQexec(PGconn *streamConn, const char *query)
* replication connection.
*/
rc = WaitLatchOrSocket(MyLatch,
- WL_POSTMASTER_DEATH | WL_SOCKET_READABLE |
+ WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE |
WL_LATCH_SET,
PQsocket(streamConn),
0,
WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE);
- /* Emergency bailout? */
- if (rc & WL_POSTMASTER_DEATH)
- exit(1);
-
/* Interrupted? */
if (rc & WL_LATCH_SET)
{
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index ce089ac07ca..3a84d8ca86a 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -221,13 +221,9 @@ WaitForReplicationWorkerAttach(LogicalRepWorker *worker,
* about the worker attach. But we don't expect to have to wait long.
*/
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
10L, WAIT_EVENT_BGWORKER_STARTUP);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
{
ResetLatch(MyLatch);
@@ -498,13 +494,9 @@ logicalrep_worker_stop(Oid subid, Oid relid)
/* Wait a bit --- we don't expect to have to wait long. */
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
10L, WAIT_EVENT_BGWORKER_STARTUP);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
{
ResetLatch(MyLatch);
@@ -546,13 +538,9 @@ logicalrep_worker_stop(Oid subid, Oid relid)
/* Wait a bit --- we don't expect to have to wait long. */
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
10L, WAIT_EVENT_BGWORKER_SHUTDOWN);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
{
ResetLatch(MyLatch);
@@ -1072,14 +1060,10 @@ ApplyLauncherMain(Datum main_arg)
/* Wait for more work. */
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
wait_time,
WAIT_EVENT_LOGICAL_LAUNCHER_MAIN);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
{
ResetLatch(MyLatch);
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index 9e682331d2f..38ae1b9ab85 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -159,7 +159,6 @@ finish_sync_worker(void)
static bool
wait_for_relation_state_change(Oid relid, char expected_state)
{
- int rc;
char state;
for (;;)
@@ -192,13 +191,9 @@ wait_for_relation_state_change(Oid relid, char expected_state)
if (!worker)
return false;
- rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
- 1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
-
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
+ (void) WaitLatch(MyLatch,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
+ 1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
ResetLatch(MyLatch);
}
@@ -250,13 +245,9 @@ wait_for_worker_state_change(char expected_state)
* but use a timeout in case it dies without sending one.
*/
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
ResetLatch(MyLatch);
}
@@ -593,7 +584,6 @@ copy_read_data(void *outbuf, int minread, int maxread)
while (maxread > 0 && bytesread < minread)
{
pgsocket fd = PGINVALID_SOCKET;
- int rc;
int len;
char *buf = NULL;
@@ -632,14 +622,10 @@ copy_read_data(void *outbuf, int minread, int maxread)
/*
* Wait for more data or latch.
*/
- rc = WaitLatchOrSocket(MyLatch,
- WL_SOCKET_READABLE | WL_LATCH_SET |
- WL_TIMEOUT | WL_POSTMASTER_DEATH,
- fd, 1000L, WAIT_EVENT_LOGICAL_SYNC_DATA);
-
- /* Emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
+ (void) WaitLatchOrSocket(MyLatch,
+ WL_SOCKET_READABLE | WL_LATCH_SET |
+ WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
+ fd, 1000L, WAIT_EVENT_LOGICAL_SYNC_DATA);
ResetLatch(MyLatch);
}
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 3cd1e0d728e..8d5e0946c4b 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -1264,14 +1264,10 @@ LogicalRepApplyLoop(XLogRecPtr last_received)
rc = WaitLatchOrSocket(MyLatch,
WL_SOCKET_READABLE | WL_LATCH_SET |
- WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
fd, wait_time,
WAIT_EVENT_LOGICAL_APPLY_MAIN);
- /* Emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
if (rc & WL_LATCH_SET)
{
ResetLatch(MyLatch);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index af5ad5fe66f..9a13c50ce88 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -214,6 +214,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
*/
for (;;)
{
+ int rc;
+
/* Must reset the latch before testing state. */
ResetLatch(MyLatch);
@@ -267,24 +269,24 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
}
/*
+ * Wait on latch. Any condition that should wake us up will set the
+ * latch, so no need for timeout.
+ */
+ rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1,
+ WAIT_EVENT_SYNC_REP);
+
+ /*
* If the postmaster dies, we'll probably never get an
* acknowledgment, because all the wal sender processes will exit. So
* just bail out.
*/
- if (!PostmasterIsAlive())
+ if (rc & WL_POSTMASTER_DEATH)
{
ProcDiePending = true;
whereToSendOutput = DestNone;
SyncRepCancelWait();
break;
}
-
- /*
- * Wait on latch. Any condition that should wake us up will set the
- * latch, so no need for timeout.
- */
- WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1,
- WAIT_EVENT_SYNC_REP);
}
/*
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index cb7bb47c9bd..9643c2ed7b3 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -503,7 +503,7 @@ WalReceiverMain(void)
*/
Assert(wait_fd != PGINVALID_SOCKET);
rc = WaitLatchOrSocket(walrcv->latch,
- WL_POSTMASTER_DEATH | WL_SOCKET_READABLE |
+ WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE |
WL_TIMEOUT | WL_LATCH_SET,
wait_fd,
NAPTIME_PER_CYCLE,
@@ -524,15 +524,6 @@ WalReceiverMain(void)
XLogWalRcvSendReply(true, false);
}
}
- if (rc & WL_POSTMASTER_DEATH)
- {
- /*
- * Emergency bailout if postmaster has died. This is to
- * avoid the necessity for manual cleanup of all
- * postmaster children.
- */
- exit(1);
- }
if (rc & WL_TIMEOUT)
{
/*
@@ -673,13 +664,6 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI)
{
ResetLatch(walrcv->latch);
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (!PostmasterIsAlive())
- exit(1);
-
ProcessWalRcvInterrupts();
SpinLockAcquire(&walrcv->mutex);
@@ -706,8 +690,8 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI)
}
SpinLockRelease(&walrcv->mutex);
- WaitLatch(walrcv->latch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
- WAIT_EVENT_WAL_RECEIVER_WAIT_START);
+ (void) WaitLatch(walrcv->latch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ WAIT_EVENT_WAL_RECEIVER_WAIT_START);
}
if (update_process_title)
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 50191ba881a..46edb525e88 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1218,20 +1218,13 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp());
- wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH |
+ wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH |
WL_SOCKET_WRITEABLE | WL_SOCKET_READABLE | WL_TIMEOUT;
/* Sleep until something happens or we time out */
- WaitLatchOrSocket(MyLatch, wakeEvents,
- MyProcPort->sock, sleeptime,
- WAIT_EVENT_WAL_SENDER_WRITE_DATA);
-
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (!PostmasterIsAlive())
- exit(1);
+ (void) WaitLatchOrSocket(MyLatch, wakeEvents,
+ MyProcPort->sock, sleeptime,
+ WAIT_EVENT_WAL_SENDER_WRITE_DATA);
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
@@ -1312,13 +1305,6 @@ WalSndWaitForWal(XLogRecPtr loc)
{
long sleeptime;
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (!PostmasterIsAlive())
- exit(1);
-
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
@@ -1410,15 +1396,15 @@ WalSndWaitForWal(XLogRecPtr loc)
*/
sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp());
- wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH |
- WL_SOCKET_READABLE | WL_TIMEOUT;
+ wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH |
+ WL_SOCKET_READABLE | WL_TIMEOUT;
if (pq_is_send_pending())
wakeEvents |= WL_SOCKET_WRITEABLE;
- WaitLatchOrSocket(MyLatch, wakeEvents,
- MyProcPort->sock, sleeptime,
- WAIT_EVENT_WAL_SENDER_WAIT_WAL);
+ (void) WaitLatchOrSocket(MyLatch, wakeEvents,
+ MyProcPort->sock, sleeptime,
+ WAIT_EVENT_WAL_SENDER_WAIT_WAL);
}
/* reactivate latch so WalSndLoop knows to continue */
@@ -2126,13 +2112,6 @@ WalSndLoop(WalSndSendDataCallback send_data)
*/
for (;;)
{
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- if (!PostmasterIsAlive())
- exit(1);
-
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
@@ -2222,8 +2201,8 @@ WalSndLoop(WalSndSendDataCallback send_data)
long sleeptime;
int wakeEvents;
- wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT |
- WL_SOCKET_READABLE;
+ wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_TIMEOUT |
+ WL_SOCKET_READABLE;
/*
* Use fresh timestamp, not last_processed, to reduce the chance
@@ -2235,9 +2214,9 @@ WalSndLoop(WalSndSendDataCallback send_data)
wakeEvents |= WL_SOCKET_WRITEABLE;
/* Sleep until something happens or we time out */
- WaitLatchOrSocket(MyLatch, wakeEvents,
- MyProcPort->sock, sleeptime,
- WAIT_EVENT_WAL_SENDER_MAIN);
+ (void) WaitLatchOrSocket(MyLatch, wakeEvents,
+ MyProcPort->sock, sleeptime,
+ WAIT_EVENT_WAL_SENDER_MAIN);
}
}
return;
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index c129446f9c9..b0804537cf3 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -48,6 +48,7 @@
#include "port/atomics.h"
#include "portability/instr_time.h"
#include "postmaster/postmaster.h"
+#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/shmem.h"
@@ -92,6 +93,13 @@ struct WaitEventSet
Latch *latch;
int latch_pos;
+ /*
+ * WL_EXIT_ON_PM_DEATH is converted to WL_POSTMASTER_DEATH, but this flag
+ * is set so that we'll exit immediately if postmaster death is detected,
+ * instead of returning.
+ */
+ bool exit_on_postmaster_death;
+
#if defined(WAIT_USE_EPOLL)
int epoll_fd;
/* epoll_wait returns events in a user provided arrays, allocate once */
@@ -348,6 +356,11 @@ WaitLatch(volatile Latch *latch, int wakeEvents, long timeout,
* to be reported as readable/writable/connected, so that the caller can deal
* with the condition.
*
+ * wakeEvents must include either WL_EXIT_ON_PM_DEATH for automatic exit
+ * if the postmaster dies or WL_POSTMASTER_DEATH for a flag set in the
+ * return value if the postmaster dies. The latter is useful for rare cases
+ * where some behavior other than immediate exit is needed.
+ *
* NB: These days this is just a wrapper around the WaitEventSet API. When
* using a latch very frequently, consider creating a longer living
* WaitEventSet instead; that's more efficient.
@@ -370,10 +383,19 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
(Latch *) latch, NULL);
- if (wakeEvents & WL_POSTMASTER_DEATH && IsUnderPostmaster)
+ /* Postmaster-managed callers must handle postmaster death somehow. */
+ Assert(!IsUnderPostmaster ||
+ (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
+ (wakeEvents & WL_POSTMASTER_DEATH));
+
+ if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
NULL, NULL);
+ if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
+ AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
+ NULL, NULL);
+
if (wakeEvents & WL_SOCKET_MASK)
{
int ev;
@@ -562,6 +584,7 @@ CreateWaitEventSet(MemoryContext context, int nevents)
set->latch = NULL;
set->nevents_space = nevents;
+ set->exit_on_postmaster_death = false;
#if defined(WAIT_USE_EPOLL)
#ifdef EPOLL_CLOEXEC
@@ -646,6 +669,7 @@ FreeWaitEventSet(WaitEventSet *set)
* - WL_SOCKET_CONNECTED: Wait for socket connection to be established,
* can be combined with other WL_SOCKET_* events (on non-Windows
* platforms, this is the same as WL_SOCKET_WRITEABLE)
+ * - WL_EXIT_ON_PM_DEATH: Exit immediately if the postmaster dies
*
* Returns the offset in WaitEventSet->events (starting from 0), which can be
* used to modify previously added wait events using ModifyWaitEvent().
@@ -671,6 +695,12 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
/* not enough space */
Assert(set->nevents < set->nevents_space);
+ if (events == WL_EXIT_ON_PM_DEATH)
+ {
+ events = WL_POSTMASTER_DEATH;
+ set->exit_on_postmaster_death = true;
+ }
+
if (latch)
{
if (latch->owner_pid != MyProcPid)
@@ -1114,6 +1144,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
*/
if (!PostmasterIsAliveInternal())
{
+ if (set->exit_on_postmaster_death)
+ proc_exit(1);
occurred_events->fd = PGINVALID_SOCKET;
occurred_events->events = WL_POSTMASTER_DEATH;
occurred_events++;
@@ -1232,6 +1264,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
*/
if (!PostmasterIsAliveInternal())
{
+ if (set->exit_on_postmaster_death)
+ proc_exit(1);
occurred_events->fd = PGINVALID_SOCKET;
occurred_events->events = WL_POSTMASTER_DEATH;
occurred_events++;
@@ -1392,6 +1426,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
*/
if (!PostmasterIsAliveInternal())
{
+ if (set->exit_on_postmaster_death)
+ proc_exit(1);
occurred_events->fd = PGINVALID_SOCKET;
occurred_events->events = WL_POSTMASTER_DEATH;
occurred_events++;
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index fde71afd479..ec0ddd537ba 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -949,7 +949,8 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
* at top of loop, because setting an already-set latch is much
* cheaper than setting one that has been reset.
*/
- WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_SEND);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ WAIT_EVENT_MQ_SEND);
/* Reset the latch so we don't spin. */
ResetLatch(MyLatch);
@@ -1093,7 +1094,8 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
* loop, because setting an already-set latch is much cheaper than
* setting one that has been reset.
*/
- WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_RECEIVE);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ WAIT_EVENT_MQ_RECEIVE);
/* Reset the latch so we don't spin. */
ResetLatch(MyLatch);
@@ -1181,7 +1183,8 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle)
}
/* Wait to be signalled. */
- WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_INTERNAL);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ WAIT_EVENT_MQ_INTERNAL);
/* Reset the latch so we don't spin. */
ResetLatch(MyLatch);
diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c
index ef1d5baf016..7f75ee61cd6 100644
--- a/src/backend/storage/lmgr/condition_variable.c
+++ b/src/backend/storage/lmgr/condition_variable.c
@@ -72,7 +72,7 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
new_event_set = CreateWaitEventSet(TopMemoryContext, 2);
AddWaitEventToSet(new_event_set, WL_LATCH_SET, PGINVALID_SOCKET,
MyLatch, NULL);
- AddWaitEventToSet(new_event_set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
+ AddWaitEventToSet(new_event_set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
NULL, NULL);
/* Don't set cv_wait_event_set until we have a correct WES. */
cv_wait_event_set = new_event_set;
@@ -154,16 +154,8 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
* Wait for latch to be set. (If we're awakened for some other
* reason, the code below will cope anyway.)
*/
- WaitEventSetWait(cv_wait_event_set, -1, &event, 1, wait_event_info);
-
- if (event.events & WL_POSTMASTER_DEATH)
- {
- /*
- * Emergency bailout if postmaster has died. This is to avoid the
- * necessity for manual cleanup of all postmaster children.
- */
- exit(1);
- }
+ (void) WaitEventSetWait(cv_wait_event_set, -1, &event, 1,
+ wait_event_info);
/* Reset latch before examining the state of the wait list. */
ResetLatch(MyLatch);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 6ad504453b1..33387fb71bc 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -1270,8 +1270,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
}
else
{
- WaitLatch(MyLatch, WL_LATCH_SET, 0,
- PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
ResetLatch(MyLatch);
/* check for deadlocks first, as that's probably log-worthy */
if (got_deadlock_timeout)
@@ -1783,7 +1783,8 @@ CheckDeadLockAlert(void)
void
ProcWaitForSignal(uint32 wait_event_info)
{
- WaitLatch(MyLatch, WL_LATCH_SET, 0, wait_event_info);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ wait_event_info);
ResetLatch(MyLatch);
CHECK_FOR_INTERRUPTS();
}
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index d05849f1d42..b8f86973dc7 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -379,7 +379,7 @@ pg_sleep(PG_FUNCTION_ARGS)
break;
(void) WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
delay_ms,
WAIT_EVENT_PG_SLEEP);
ResetLatch(MyLatch);
diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h
index fd8735b7f5f..039a82e1a3a 100644
--- a/src/include/storage/latch.h
+++ b/src/include/storage/latch.h
@@ -126,8 +126,9 @@ typedef struct Latch
#define WL_SOCKET_WRITEABLE (1 << 2)
#define WL_TIMEOUT (1 << 3) /* not for WaitEventSetWait() */
#define WL_POSTMASTER_DEATH (1 << 4)
+#define WL_EXIT_ON_PM_DEATH (1 << 5)
#ifdef WIN32
-#define WL_SOCKET_CONNECTED (1 << 5)
+#define WL_SOCKET_CONNECTED (1 << 6)
#else
/* avoid having to deal with case on platforms not requiring it */
#define WL_SOCKET_CONNECTED WL_SOCKET_WRITEABLE
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 97e8617b3e9..75f76b2c363 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -280,7 +280,8 @@ wait_for_workers_to_become_ready(worker_state *wstate,
}
/* Wait to be signalled. */
- WaitLatch(MyLatch, WL_LATCH_SET, 0, PG_WAIT_EXTENSION);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ PG_WAIT_EXTENSION);
/* Reset the latch so we don't spin. */
ResetLatch(MyLatch);
diff --git a/src/test/modules/test_shm_mq/test.c b/src/test/modules/test_shm_mq/test.c
index ebab9866017..d03be06ff65 100644
--- a/src/test/modules/test_shm_mq/test.c
+++ b/src/test/modules/test_shm_mq/test.c
@@ -231,7 +231,8 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS)
* have read or written data and therefore there may now be work
* for us to do.
*/
- WaitLatch(MyLatch, WL_LATCH_SET, 0, PG_WAIT_EXTENSION);
+ (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
+ PG_WAIT_EXTENSION);
ResetLatch(MyLatch);
CHECK_FOR_INTERRUPTS();
}
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index 0d705a3f2ed..52a3208527e 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -226,15 +226,11 @@ worker_spi_main(Datum main_arg)
* background process goes away immediately in an emergency.
*/
rc = WaitLatch(MyLatch,
- WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
worker_spi_naptime * 1000L,
PG_WAIT_EXTENSION);
ResetLatch(MyLatch);
- /* emergency bailout if postmaster has died */
- if (rc & WL_POSTMASTER_DEATH)
- proc_exit(1);
-
CHECK_FOR_INTERRUPTS();
/*