From 89fd72cbf26f5d2e3d86ab19c1ead73ab8fac0fe Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 8 Jul 2011 18:27:49 +0300 Subject: Introduce a pipe between postmaster and each backend, which can be used to detect postmaster death. Postmaster keeps the write-end of the pipe open, so when it dies, children get EOF in the read-end. That can conveniently be waited for in select(), which allows eliminating some of the polling loops that check for postmaster death. This patch doesn't yet change all the loops to use the new mechanism, expect a follow-on patch to do that. This changes the interface to WaitLatch, so that it takes as argument a bitmask of events that it waits for. Possible events are latch set, timeout, postmaster death, and socket becoming readable or writeable. The pipe method behaves slightly differently from the kill() method previously used in PostmasterIsAlive() in the case that postmaster has died, but its parent has not yet read its exit code with waitpid(). The pipe returns EOF as soon as the process dies, but kill() continues to return true until waitpid() has been called (IOW while the process is a zombie). Because of that, change PostmasterIsAlive() to use the pipe too, otherwise WaitLatch() would return immediately with WL_POSTMASTER_DEATH, while PostmasterIsAlive() would claim it's still alive. That could easily lead to busy-waiting while postmaster is in zombie state. Peter Geoghegan with further changes by me, reviewed by Fujii Masao and Florian Pflug. --- src/include/postmaster/postmaster.h | 8 ++++++++ src/include/storage/latch.h | 13 ++++++++++--- src/include/storage/pmsignal.h | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src/include') diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index f7072f55cf8..be4f8a74989 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -32,6 +32,14 @@ extern bool restart_after_crash; #ifdef WIN32 extern HANDLE PostmasterHandle; +#else +extern int postmaster_alive_fds[2]; +/* + * Constants that represent which of postmaster_alive_fds is held by + * postmaster, and which is used in children to check for postmaster death. + */ +#define POSTMASTER_FD_WATCH 0 /* used in children to check for postmaster death */ +#define POSTMASTER_FD_OWN 1 /* kept open by postmaster only */ #endif extern const char *progname; diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 03ec07119b9..df891e68aab 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -31,6 +31,13 @@ typedef struct #endif } Latch; +/* Bitmasks for events that may wake-up WaitLatch() clients */ +#define WL_LATCH_SET (1 << 0) +#define WL_SOCKET_READABLE (1 << 1) +#define WL_SOCKET_WRITEABLE (1 << 2) +#define WL_TIMEOUT (1 << 3) +#define WL_POSTMASTER_DEATH (1 << 4) + /* * prototypes for functions in latch.c */ @@ -38,9 +45,9 @@ extern void InitLatch(volatile Latch *latch); extern void InitSharedLatch(volatile Latch *latch); extern void OwnLatch(volatile Latch *latch); extern void DisownLatch(volatile Latch *latch); -extern bool WaitLatch(volatile Latch *latch, long timeout); -extern int WaitLatchOrSocket(volatile Latch *latch, pgsocket sock, - bool forRead, bool forWrite, long timeout); +extern int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout); +extern int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, + pgsocket sock, long timeout); extern void SetLatch(volatile Latch *latch); extern void ResetLatch(volatile Latch *latch); diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h index 7606b0961cc..90fe0c2f73d 100644 --- a/src/include/storage/pmsignal.h +++ b/src/include/storage/pmsignal.h @@ -50,6 +50,6 @@ extern bool IsPostmasterChildWalSender(int slot); extern void MarkPostmasterChildActive(void); extern void MarkPostmasterChildInactive(void); extern void MarkPostmasterChildWalSender(void); -extern bool PostmasterIsAlive(bool amDirectChild); +extern bool PostmasterIsAlive(void); #endif /* PMSIGNAL_H */ -- cgit v1.2.3