postgresql/src/port/pqsignal.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

62 lines
1.7 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* pqsignal.c
* reliable BSD-style signal(2) routine stolen from RWW who stole it
* from Stevens...
*
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/port/pqsignal.c
*
* We now assume that all Unix-oid systems have POSIX sigaction(2)
* with support for restartable signals (SA_RESTART). We used to also
* support BSD-style signal(2), but there really shouldn't be anything
* out there anymore that doesn't have the POSIX API.
*
* Windows, of course, is resolutely in a class by itself. In the backend,
* we don't use this file at all; src/backend/port/win32/signal.c provides
* pqsignal() for the backend environment. Frontend programs can use
* this version of pqsignal() if they wish, but beware that this does
* not provide restartable signals on Windows.
*
* ------------------------------------------------------------------------
*/
#include "c.h"
#include <signal.h>
#if !defined(WIN32) || defined(FRONTEND)
/*
Run the postmaster's signal handlers without SA_RESTART. The postmaster keeps signals blocked everywhere except while waiting for something to happen in ServerLoop(). The code expects that the select(2) will be cancelled with EINTR if an interrupt occurs; without that, followup actions that should be performed by ServerLoop() itself will be delayed. However, some platforms interpret the SA_RESTART signal flag as meaning that they should restart rather than cancel the select(2). Worse yet, some of them restart it with the original timeout delay, meaning that a steady stream of signal interrupts can prevent ServerLoop() from iterating at all if there are no incoming connection requests. Observable symptoms of this, on an affected platform such as HPUX 10, include extremely slow parallel query startup (possibly as much as 30 seconds) and failure to update timestamps on the postmaster's sockets and lockfiles when no new connections arrive for a long time. We can fix this by running the postmaster's signal handlers without SA_RESTART. That would be quite a scary change if the range of code where signals are accepted weren't so tiny, but as it is, it seems safe enough. (Note that postmaster children do, and must, reset all the handlers before unblocking signals; so this change should not affect any child process.) There is talk of rewriting the postmaster to use a WaitEventSet and not do signal response work in signal handlers, at which point it might be appropriate to revert this patch. But that's not happening before v11 at the earliest. Back-patch to 9.6. The problem exists much further back, but the worst symptom arises only in connection with parallel query, so it does not seem worth taking any portability risks in older branches. Discussion: https://postgr.es/m/9205.1492833041@sss.pgh.pa.us
2017-04-24 19:00:23 +02:00
* Set up a signal handler, with SA_RESTART, for signal "signo"
*
* Returns the previous handler.
*/
pqsigfunc
pqsignal(int signo, pqsigfunc func)
{
#ifndef WIN32
struct sigaction act,
oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
#ifdef SA_NOCLDSTOP
if (signo == SIGCHLD)
act.sa_flags |= SA_NOCLDSTOP;
#endif
if (sigaction(signo, &act, &oact) < 0)
return SIG_ERR;
return oact.sa_handler;
#else /* WIN32 */
return signal(signo, func);
#endif
}
#endif /* !defined(WIN32) || defined(FRONTEND) */