diff options
Diffstat (limited to 'src/backend/port')
-rw-r--r-- | src/backend/port/unix_latch.c | 35 | ||||
-rw-r--r-- | src/backend/port/win32_latch.c | 12 |
2 files changed, 34 insertions, 13 deletions
diff --git a/src/backend/port/unix_latch.c b/src/backend/port/unix_latch.c index 10bf2dbec7e..30d1a488f0a 100644 --- a/src/backend/port/unix_latch.c +++ b/src/backend/port/unix_latch.c @@ -50,6 +50,7 @@ #include "miscadmin.h" #include "postmaster/postmaster.h" #include "storage/latch.h" +#include "storage/pmsignal.h" #include "storage/shmem.h" /* Are we currently in WaitLatch? The signal handler would like to know. */ @@ -160,15 +161,7 @@ DisownLatch(volatile Latch *latch) * * Returns bit mask indicating which condition(s) caused the wake-up. Note * that if multiple wake-up conditions are true, there is no guarantee that - * we return all of them in one call, but we will return at least one. Also, - * according to the select(2) man page on Linux, select(2) may spuriously - * return and report a file descriptor as readable, when it's not. We use - * select(2), so WaitLatch can also spuriously claim that a socket is - * readable, or postmaster has died, even when none of the wake conditions - * have been satisfied. That should be rare in practice, but the caller - * should not use the return value for anything critical, re-checking the - * situation with PostmasterIsAlive() or read() on a socket as necessary. - * The latch and timeout flag bits can be trusted, however. + * we return all of them in one call, but we will return at least one. */ int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout) @@ -318,7 +311,17 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, if ((wakeEvents & WL_POSTMASTER_DEATH) && (pfds[nfds - 1].revents & (POLLHUP | POLLIN | POLLERR | POLLNVAL))) { - result |= WL_POSTMASTER_DEATH; + /* + * According to the select(2) man page on Linux, select(2) may + * spuriously return and report a file descriptor as readable, + * when it's not; and presumably so can poll(2). It's not clear + * that the relevant cases would ever apply to the postmaster + * pipe, but since the consequences of falsely returning + * WL_POSTMASTER_DEATH could be pretty unpleasant, we take the + * trouble to positively verify EOF with PostmasterIsAlive(). + */ + if (!PostmasterIsAlive()) + result |= WL_POSTMASTER_DEATH; } #else /* !HAVE_POLL */ @@ -380,7 +383,17 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, if ((wakeEvents & WL_POSTMASTER_DEATH) && FD_ISSET(postmaster_alive_fds[POSTMASTER_FD_WATCH], &input_mask)) { - result |= WL_POSTMASTER_DEATH; + /* + * According to the select(2) man page on Linux, select(2) may + * spuriously return and report a file descriptor as readable, + * when it's not; and presumably so can poll(2). It's not clear + * that the relevant cases would ever apply to the postmaster + * pipe, but since the consequences of falsely returning + * WL_POSTMASTER_DEATH could be pretty unpleasant, we take the + * trouble to positively verify EOF with PostmasterIsAlive(). + */ + if (!PostmasterIsAlive()) + result |= WL_POSTMASTER_DEATH; } #endif /* HAVE_POLL */ } while (result == 0); diff --git a/src/backend/port/win32_latch.c b/src/backend/port/win32_latch.c index e4fe05fa4b6..622798924dc 100644 --- a/src/backend/port/win32_latch.c +++ b/src/backend/port/win32_latch.c @@ -26,6 +26,7 @@ #include "miscadmin.h" #include "postmaster/postmaster.h" #include "storage/latch.h" +#include "storage/pmsignal.h" #include "storage/shmem.h" @@ -217,8 +218,15 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, else if ((wakeEvents & WL_POSTMASTER_DEATH) && rc == WAIT_OBJECT_0 + pmdeath_eventno) { - /* Postmaster died */ - result |= WL_POSTMASTER_DEATH; + /* + * Postmaster apparently died. Since the consequences of falsely + * returning WL_POSTMASTER_DEATH could be pretty unpleasant, we + * take the trouble to positively verify this with + * PostmasterIsAlive(), even though there is no known reason to + * think that the event could be falsely set on Windows. + */ + if (!PostmasterIsAlive()) + result |= WL_POSTMASTER_DEATH; } else elog(ERROR, "unexpected return code from WaitForMultipleObjects(): %lu", rc); |