diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 6fdea3fc2d2..bbbc09b0b5c 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -713,22 +713,6 @@ bgworker_die(SIGNAL_ARGS) MyBgworkerEntry->bgw_type))); } -/* - * Standard SIGUSR1 handler for unconnected workers - * - * Here, we want to make sure an unconnected worker will at least heed - * latch activity. - */ -static void -bgworker_sigusr1_handler(SIGNAL_ARGS) -{ - int save_errno = errno; - - latch_sigusr1_handler(); - - errno = save_errno; -} - /* * Start a new background worker * @@ -759,6 +743,7 @@ StartBackgroundWorker(void) */ if ((worker->bgw_flags & BGWORKER_SHMEM_ACCESS) == 0) { + ShutdownLatchSupport(); dsm_detach_all(); PGSharedMemoryDetach(); } @@ -786,7 +771,7 @@ StartBackgroundWorker(void) else { pqsignal(SIGINT, SIG_IGN); - pqsignal(SIGUSR1, bgworker_sigusr1_handler); + pqsignal(SIGUSR1, SIG_IGN); pqsignal(SIGFPE, SIG_IGN); } pqsignal(SIGTERM, bgworker_die); diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 9568dafbe24..3f1ce135a85 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -656,6 +656,10 @@ PostmasterMain(int argc, char *argv[]) pqsignal_pm(SIGUSR2, dummy_handler); /* unused, reserve for children */ pqsignal_pm(SIGCHLD, reaper); /* handle child termination */ +#ifdef SIGURG + pqsignal_pm(SIGURG, SIG_IGN); /* ignored */ +#endif + /* * No other place in Postgres should touch SIGTTIN/SIGTTOU handling. We * ignore those signals in a postmaster environment, so that there is no diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index eacf8d51ea0..0f274280e65 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -16,7 +16,7 @@ * * When SetLatch is called from the same process that owns the latch, * SetLatch writes the byte directly to the pipe. If it's owned by another - * process, SIGUSR1 is sent and the signal handler in the waiting process + * process, SIGURG is sent and the signal handler in the waiting process * writes the byte to the pipe on behalf of the signaling process. * * The Windows implementation uses Windows events that are inherited by all @@ -148,6 +148,7 @@ static int selfpipe_writefd = -1; static int selfpipe_owner_pid = 0; /* Private function prototypes */ +static void latch_sigurg_handler(SIGNAL_ARGS); static void sendSelfPipeByte(void); static void drainSelfPipe(void); #endif /* WIN32 */ @@ -244,6 +245,8 @@ InitializeLatchSupport(void) /* Tell fd.c about these two long-lived FDs */ ReserveExternalFD(); ReserveExternalFD(); + + pqsignal(SIGURG, latch_sigurg_handler); #else /* currently, nothing to do here for Windows */ #endif @@ -267,6 +270,24 @@ InitializeLatchWaitSet(void) Assert(latch_pos == LatchWaitSetLatchPos); } +void +ShutdownLatchSupport(void) +{ + pqsignal(SIGURG, SIG_IGN); + + if (LatchWaitSet) + { + FreeWaitEventSet(LatchWaitSet); + LatchWaitSet = NULL; + } + + close(selfpipe_readfd); + close(selfpipe_writefd); + selfpipe_readfd = -1; + selfpipe_writefd = -1; + selfpipe_owner_pid = InvalidPid; +} + /* * Initialize a process-local latch. */ @@ -335,10 +356,6 @@ InitSharedLatch(Latch *latch) * any sort of locking here, meaning that we could fail to detect the error * if two processes try to own the same latch at about the same time. If * there is any risk of that, caller must provide an interlock to prevent it. - * - * In any process that calls OwnLatch(), make sure that - * latch_sigusr1_handler() is called from the SIGUSR1 signal handler, - * as shared latches use SIGUSR1 for inter-process communication. */ void OwnLatch(Latch *latch) @@ -562,7 +579,7 @@ SetLatch(Latch *latch) sendSelfPipeByte(); } else - kill(owner_pid, SIGUSR1); + kill(owner_pid, SIGURG); #else /* @@ -1266,7 +1283,7 @@ WaitEventSetWait(WaitEventSet *set, long timeout, * the pipe-buffer fill up we're still ok, because the pipe is in * nonblocking mode. It's unlikely for that to happen, because the * self pipe isn't filled unless we're blocking (waiting = true), or - * from inside a signal handler in latch_sigusr1_handler(). + * from inside a signal handler in latch_sigurg_handler(). * * On windows, we'll also notice if there's a pending event for the * latch when blocking, but there's no danger of anything filling up, @@ -1934,22 +1951,21 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, } #endif -/* - * SetLatch uses SIGUSR1 to wake up the process waiting on the latch. - * - * Wake up WaitLatch, if we're waiting. (We might not be, since SIGUSR1 is - * overloaded for multiple purposes; or we might not have reached WaitLatch - * yet, in which case we don't need to fill the pipe either.) - * - * NB: when calling this in a signal handler, be sure to save and restore - * errno around it. - */ #ifndef WIN32 -void -latch_sigusr1_handler(void) +/* + * SetLatch uses SIGURG to wake up the process waiting on the latch. + * + * Wake up WaitLatch, if we're waiting. + */ +static void +latch_sigurg_handler(SIGNAL_ARGS) { + int save_errno = errno; + if (waiting) sendSelfPipeByte(); + + errno = save_errno; } #endif /* !WIN32 */ diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index c43cdd685b4..ed97f4a3e97 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -688,7 +688,5 @@ procsignal_sigusr1_handler(SIGNAL_ARGS) SetLatch(MyLatch); - latch_sigusr1_handler(); - errno = save_errno; } diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 393591be03c..9e94fcaec24 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -163,6 +163,7 @@ extern void OwnLatch(Latch *latch); extern void DisownLatch(Latch *latch); extern void SetLatch(Latch *latch); extern void ResetLatch(Latch *latch); +extern void ShutdownLatchSupport(void); extern WaitEventSet *CreateWaitEventSet(MemoryContext context, int nevents); extern void FreeWaitEventSet(WaitEventSet *set); @@ -179,14 +180,4 @@ extern int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info); extern void InitializeLatchWaitSet(void); -/* - * Unix implementation uses SIGUSR1 for inter-process signaling. - * Win32 doesn't need this. - */ -#ifndef WIN32 -extern void latch_sigusr1_handler(void); -#else -#define latch_sigusr1_handler() ((void) 0) -#endif - #endif /* LATCH_H */