Commit 7b05b3fa authored by Heikki Linnakangas's avatar Heikki Linnakangas

Provide support for multiplexing SIGUSR1 signal. The upcoming synchronous

replication patch needs a signal, but we've already used SIGUSR1 and
SIGUSR2 in normal backends. This patch allows reusing SIGUSR1 for that,
and for other purposes too if the need arises.
parent 9edd7200
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.48 2008/11/19 10:34:50 heikki Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.49 2008/12/09 14:28:20 heikki Exp $
* *
* NOTES * NOTES
* Each global transaction is associated with a global transaction * Each global transaction is associated with a global transaction
...@@ -287,6 +287,7 @@ MarkAsPreparing(TransactionId xid, const char *gid, ...@@ -287,6 +287,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
gxact->proc.databaseId = databaseid; gxact->proc.databaseId = databaseid;
gxact->proc.roleId = owner; gxact->proc.roleId = owner;
gxact->proc.inCommit = false; gxact->proc.inCommit = false;
MemSet(gxact->proc.signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
gxact->proc.vacuumFlags = 0; gxact->proc.vacuumFlags = 0;
gxact->proc.lwWaiting = false; gxact->proc.lwWaiting = false;
gxact->proc.lwExclusive = false; gxact->proc.lwExclusive = false;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.142 2008/11/02 01:45:27 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.143 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -915,9 +915,10 @@ EnableNotifyInterrupt(void) ...@@ -915,9 +915,10 @@ EnableNotifyInterrupt(void)
* a frontend command. Signal handler execution of inbound notifies * a frontend command. Signal handler execution of inbound notifies
* is disabled until the next EnableNotifyInterrupt call. * is disabled until the next EnableNotifyInterrupt call.
* *
* The SIGUSR1 signal handler also needs to call this, so as to * This also needs to be called when SIGUSR1 with
* prevent conflicts if one signal interrupts the other. So we * PROCSIG_CATCHUP_INTERRUPT is received, so as to prevent conflicts
* must return the previous state of the flag. * if one signal interrupts the other. So we must return the previous
* state of the flag.
*/ */
bool bool
DisableNotifyInterrupt(void) DisableNotifyInterrupt(void)
...@@ -954,7 +955,7 @@ ProcessIncomingNotify(void) ...@@ -954,7 +955,7 @@ ProcessIncomingNotify(void)
nulls[Natts_pg_listener]; nulls[Natts_pg_listener];
bool catchup_enabled; bool catchup_enabled;
/* Must prevent SIGUSR1 interrupt while I am running */ /* Must prevent catchup interrupt while I am running */
catchup_enabled = DisableCatchupInterrupt(); catchup_enabled = DisableCatchupInterrupt();
if (Trace_notify) if (Trace_notify)
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.88 2008/12/04 11:42:24 heikki Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.89 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1477,7 +1477,7 @@ AutoVacWorkerMain(int argc, char *argv[]) ...@@ -1477,7 +1477,7 @@ AutoVacWorkerMain(int argc, char *argv[])
pqsignal(SIGALRM, handle_sig_alarm); pqsignal(SIGALRM, handle_sig_alarm);
pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, CatchupInterruptHandler); pqsignal(SIGUSR1, proc_sigusr1_handler);
/* We don't listen for async notifies */ /* We don't listen for async notifies */
pqsignal(SIGUSR2, SIG_IGN); pqsignal(SIGUSR2, SIG_IGN);
pqsignal(SIGFPE, FloatExceptionHandler); pqsignal(SIGFPE, FloatExceptionHandler);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.86 2008/06/19 21:32:56 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.87 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
* Because backends sitting idle will not be reading sinval events, we * Because backends sitting idle will not be reading sinval events, we
* need a way to give an idle backend a swift kick in the rear and make * need a way to give an idle backend a swift kick in the rear and make
* it catch up before the sinval queue overflows and forces it to go * it catch up before the sinval queue overflows and forces it to go
* through a cache reset exercise. This is done by sending SIGUSR1 * through a cache reset exercise. This is done by sending
* to any backend that gets too far behind. * PROCSIG_CATCHUP_INTERRUPT to any backend that gets too far behind.
* *
* State for catchup events consists of two flags: one saying whether * State for catchup events consists of two flags: one saying whether
* the signal handler is currently allowed to call ProcessCatchupEvent * the signal handler is currently allowed to call ProcessCatchupEvent
...@@ -144,9 +144,9 @@ ReceiveSharedInvalidMessages( ...@@ -144,9 +144,9 @@ ReceiveSharedInvalidMessages(
/* /*
* CatchupInterruptHandler * HandleCatchupInterrupt
* *
* This is the signal handler for SIGUSR1. * This is called when PROCSIG_CATCHUP_INTERRUPT signal is received.
* *
* If we are idle (catchupInterruptEnabled is set), we can safely * If we are idle (catchupInterruptEnabled is set), we can safely
* invoke ProcessCatchupEvent directly. Otherwise, just set a flag * invoke ProcessCatchupEvent directly. Otherwise, just set a flag
...@@ -156,13 +156,11 @@ ReceiveSharedInvalidMessages( ...@@ -156,13 +156,11 @@ ReceiveSharedInvalidMessages(
* since there's no longer any reason to do anything.) * since there's no longer any reason to do anything.)
*/ */
void void
CatchupInterruptHandler(SIGNAL_ARGS) HandleCatchupInterrupt(void)
{ {
int save_errno = errno;
/* /*
* Note: this is a SIGNAL HANDLER. You must be very wary what you do * Note: this is called by a SIGNAL HANDLER.
* here. * You must be very wary what you do here.
*/ */
/* Don't joggle the elbow of proc_exit */ /* Don't joggle the elbow of proc_exit */
...@@ -216,8 +214,6 @@ CatchupInterruptHandler(SIGNAL_ARGS) ...@@ -216,8 +214,6 @@ CatchupInterruptHandler(SIGNAL_ARGS)
*/ */
catchupInterruptOccurred = 1; catchupInterruptOccurred = 1;
} }
errno = save_errno;
} }
/* /*
...@@ -289,7 +285,8 @@ DisableCatchupInterrupt(void) ...@@ -289,7 +285,8 @@ DisableCatchupInterrupt(void)
/* /*
* ProcessCatchupEvent * ProcessCatchupEvent
* *
* Respond to a catchup event (SIGUSR1) from another backend. * Respond to a catchup event (PROCSIG_CATCHUP_INTERRUPT) from another
* backend.
* *
* This is called either directly from the SIGUSR1 signal handler, * This is called either directly from the SIGUSR1 signal handler,
* or the next time control reaches the outer idle loop (assuming * or the next time control reaches the outer idle loop (assuming
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.74 2008/07/18 14:45:48 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.75 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "storage/backendid.h" #include "storage/backendid.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/proc.h" #include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/shmem.h" #include "storage/shmem.h"
#include "storage/sinvaladt.h" #include "storage/sinvaladt.h"
#include "storage/spin.h" #include "storage/spin.h"
...@@ -136,9 +137,9 @@ ...@@ -136,9 +137,9 @@
/* Per-backend state in shared invalidation structure */ /* Per-backend state in shared invalidation structure */
typedef struct ProcState typedef struct ProcState
{ {
/* procPid is zero in an inactive ProcState array entry. */ /* proc is NULL in an inactive ProcState array entry. */
pid_t procPid; /* PID of backend, for signaling */ PGPROC *proc; /* PGPROC entry of backend, for signaling */
/* nextMsgNum is meaningless if procPid == 0 or resetState is true. */ /* nextMsgNum is meaningless if proc == NULL or resetState is true. */
int nextMsgNum; /* next message number to read */ int nextMsgNum; /* next message number to read */
bool resetState; /* backend needs to reset its state */ bool resetState; /* backend needs to reset its state */
bool signaled; /* backend has been sent catchup signal */ bool signaled; /* backend has been sent catchup signal */
...@@ -235,7 +236,7 @@ CreateSharedInvalidationState(void) ...@@ -235,7 +236,7 @@ CreateSharedInvalidationState(void)
/* Mark all backends inactive, and initialize nextLXID */ /* Mark all backends inactive, and initialize nextLXID */
for (i = 0; i < shmInvalBuffer->maxBackends; i++) for (i = 0; i < shmInvalBuffer->maxBackends; i++)
{ {
shmInvalBuffer->procState[i].procPid = 0; /* inactive */ shmInvalBuffer->procState[i].proc = NULL; /* inactive */
shmInvalBuffer->procState[i].nextMsgNum = 0; /* meaningless */ shmInvalBuffer->procState[i].nextMsgNum = 0; /* meaningless */
shmInvalBuffer->procState[i].resetState = false; shmInvalBuffer->procState[i].resetState = false;
shmInvalBuffer->procState[i].signaled = false; shmInvalBuffer->procState[i].signaled = false;
...@@ -266,7 +267,7 @@ SharedInvalBackendInit(void) ...@@ -266,7 +267,7 @@ SharedInvalBackendInit(void)
/* Look for a free entry in the procState array */ /* Look for a free entry in the procState array */
for (index = 0; index < segP->lastBackend; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
if (segP->procState[index].procPid == 0) /* inactive slot? */ if (segP->procState[index].proc == NULL) /* inactive slot? */
{ {
stateP = &segP->procState[index]; stateP = &segP->procState[index];
break; break;
...@@ -278,7 +279,7 @@ SharedInvalBackendInit(void) ...@@ -278,7 +279,7 @@ SharedInvalBackendInit(void)
if (segP->lastBackend < segP->maxBackends) if (segP->lastBackend < segP->maxBackends)
{ {
stateP = &segP->procState[segP->lastBackend]; stateP = &segP->procState[segP->lastBackend];
Assert(stateP->procPid == 0); Assert(stateP->proc == NULL);
segP->lastBackend++; segP->lastBackend++;
} }
else else
...@@ -303,7 +304,7 @@ SharedInvalBackendInit(void) ...@@ -303,7 +304,7 @@ SharedInvalBackendInit(void)
nextLocalTransactionId = stateP->nextLXID; nextLocalTransactionId = stateP->nextLXID;
/* mark myself active, with all extant messages already read */ /* mark myself active, with all extant messages already read */
stateP->procPid = MyProcPid; stateP->proc = MyProc;
stateP->nextMsgNum = segP->maxMsgNum; stateP->nextMsgNum = segP->maxMsgNum;
stateP->resetState = false; stateP->resetState = false;
stateP->signaled = false; stateP->signaled = false;
...@@ -341,7 +342,7 @@ CleanupInvalidationState(int status, Datum arg) ...@@ -341,7 +342,7 @@ CleanupInvalidationState(int status, Datum arg)
stateP->nextLXID = nextLocalTransactionId; stateP->nextLXID = nextLocalTransactionId;
/* Mark myself inactive */ /* Mark myself inactive */
stateP->procPid = 0; stateP->proc = NULL;
stateP->nextMsgNum = 0; stateP->nextMsgNum = 0;
stateP->resetState = false; stateP->resetState = false;
stateP->signaled = false; stateP->signaled = false;
...@@ -349,7 +350,7 @@ CleanupInvalidationState(int status, Datum arg) ...@@ -349,7 +350,7 @@ CleanupInvalidationState(int status, Datum arg)
/* Recompute index of last active backend */ /* Recompute index of last active backend */
for (i = segP->lastBackend; i > 0; i--) for (i = segP->lastBackend; i > 0; i--)
{ {
if (segP->procState[i - 1].procPid != 0) if (segP->procState[i - 1].proc != NULL)
break; break;
} }
segP->lastBackend = i; segP->lastBackend = i;
...@@ -374,7 +375,7 @@ BackendIdIsActive(int backendID) ...@@ -374,7 +375,7 @@ BackendIdIsActive(int backendID)
{ {
ProcState *stateP = &segP->procState[backendID - 1]; ProcState *stateP = &segP->procState[backendID - 1];
result = (stateP->procPid != 0); result = (stateP->proc != NULL);
} }
else else
result = false; result = false;
...@@ -590,7 +591,7 @@ SICleanupQueue(bool callerHasWriteLock, int minFree) ...@@ -590,7 +591,7 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
int n = stateP->nextMsgNum; int n = stateP->nextMsgNum;
/* Ignore if inactive or already in reset state */ /* Ignore if inactive or already in reset state */
if (stateP->procPid == 0 || stateP->resetState) if (stateP->proc == NULL || stateP->resetState)
continue; continue;
/* /*
...@@ -644,18 +645,20 @@ SICleanupQueue(bool callerHasWriteLock, int minFree) ...@@ -644,18 +645,20 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
segP->nextThreshold = (numMsgs / CLEANUP_QUANTUM + 1) * CLEANUP_QUANTUM; segP->nextThreshold = (numMsgs / CLEANUP_QUANTUM + 1) * CLEANUP_QUANTUM;
/* /*
* Lastly, signal anyone who needs a catchup interrupt. Since kill() * Lastly, signal anyone who needs a catchup interrupt. Since
* might not be fast, we don't want to hold locks while executing it. * SendProcSignal() might not be fast, we don't want to hold locks while
* executing it.
*/ */
if (needSig) if (needSig)
{ {
pid_t his_pid = needSig->procPid; PGPROC *his_proc = needSig->proc;
needSig->signaled = true; needSig->signaled = true;
LWLockRelease(SInvalReadLock); LWLockRelease(SInvalReadLock);
LWLockRelease(SInvalWriteLock); LWLockRelease(SInvalWriteLock);
elog(DEBUG4, "sending sinval catchup signal to PID %d", (int) his_pid); elog(DEBUG4, "sending sinval catchup signal to PID %d",
kill(his_pid, SIGUSR1); (int) his_proc->pid);
SendProcSignal(his_proc, PROCSIG_CATCHUP_INTERRUPT);
if (callerHasWriteLock) if (callerHasWriteLock)
LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE); LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.202 2008/11/02 21:24:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.203 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -289,6 +289,7 @@ InitProcess(void) ...@@ -289,6 +289,7 @@ InitProcess(void)
MyProc->databaseId = InvalidOid; MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid; MyProc->roleId = InvalidOid;
MyProc->inCommit = false; MyProc->inCommit = false;
MemSet(MyProc->signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
MyProc->vacuumFlags = 0; MyProc->vacuumFlags = 0;
if (IsAutoVacuumWorkerProcess()) if (IsAutoVacuumWorkerProcess())
MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM; MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
...@@ -428,6 +429,7 @@ InitAuxiliaryProcess(void) ...@@ -428,6 +429,7 @@ InitAuxiliaryProcess(void)
MyProc->databaseId = InvalidOid; MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid; MyProc->roleId = InvalidOid;
MyProc->inCommit = false; MyProc->inCommit = false;
MemSet(MyProc->signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
/* we don't set the "is autovacuum" flag in the launcher */ /* we don't set the "is autovacuum" flag in the launcher */
MyProc->vacuumFlags = 0; MyProc->vacuumFlags = 0;
MyProc->lwWaiting = false; MyProc->lwWaiting = false;
...@@ -1277,6 +1279,54 @@ ProcSendSignal(int pid) ...@@ -1277,6 +1279,54 @@ ProcSendSignal(int pid)
PGSemaphoreUnlock(&proc->sem); PGSemaphoreUnlock(&proc->sem);
} }
/*
* SendProcSignal - send the signal with the reason to a process.
*
* The process can be a backend or an auxiliary process that has a PGPROC
* entry, like an autovacuum worker.
*/
void
SendProcSignal(PGPROC *proc, ProcSignalReason reason)
{
pid_t pid;
/*
* If the process is gone, do nothing.
*
* Since there's no locking, it's possible that the process detaches
* from shared memory and exits right after this test, before we set
* the flag and send signal. And the PGPROC entry might even be recycled
* by a new process, so it's remotely possible that we signal a wrong
* process. That's OK, all the signals are such that no harm is done.
*/
pid = proc->pid;
if (pid == 0)
return;
/* Atomically set the proper flag */
proc->signalFlags[reason] = true;
/* Send SIGUSR1 to the process */
kill(pid, SIGUSR1);
}
/*
* CheckProcSignal - check to see if the particular reason has been
* signaled, and clear the signal flag. Should be called after
* receiving SIGUSR1.
*/
bool
CheckProcSignal(ProcSignalReason reason)
{
/* Careful here --- don't clear flag if we haven't seen it set */
if (MyProc->signalFlags[reason])
{
MyProc->signalFlags[reason] = false;
return true;
}
return false;
}
/***************************************************************************** /*****************************************************************************
* SIGALRM interrupt support * SIGALRM interrupt support
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.558 2008/11/30 20:51:25 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.559 2008/12/09 14:28:20 heikki Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -2436,6 +2436,23 @@ drop_unnamed_stmt(void) ...@@ -2436,6 +2436,23 @@ drop_unnamed_stmt(void)
* -------------------------------- * --------------------------------
*/ */
/*
* proc_sigusr1_handler - handle SIGUSR1 signal.
*
* SIGUSR1 is multiplexed to handle multiple different events. The signalFlags
* array in PGPROC indicates which events have been signaled.
*/
void
proc_sigusr1_handler(SIGNAL_ARGS)
{
int save_errno = errno;
if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT))
HandleCatchupInterrupt();
errno = save_errno;
}
/* /*
* quickdie() occurs when signalled SIGQUIT by the postmaster. * quickdie() occurs when signalled SIGQUIT by the postmaster.
* *
...@@ -3180,7 +3197,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -3180,7 +3197,7 @@ PostgresMain(int argc, char *argv[], const char *username)
* of output during who-knows-what operation... * of output during who-knows-what operation...
*/ */
pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, CatchupInterruptHandler); pqsignal(SIGUSR1, proc_sigusr1_handler);
pqsignal(SIGUSR2, NotifyInterruptHandler); pqsignal(SIGUSR2, NotifyInterruptHandler);
pqsignal(SIGFPE, FloatExceptionHandler); pqsignal(SIGFPE, FloatExceptionHandler);
......
...@@ -7,13 +7,15 @@ ...@@ -7,13 +7,15 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.107 2008/11/02 21:24:52 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.108 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef _PROC_H_ #ifndef _PROC_H_
#define _PROC_H_ #define _PROC_H_
#include <signal.h>
#include "storage/lock.h" #include "storage/lock.h"
#include "storage/pg_sema.h" #include "storage/pg_sema.h"
...@@ -38,6 +40,19 @@ struct XidCache ...@@ -38,6 +40,19 @@ struct XidCache
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]; TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS];
}; };
/*
* Reasons for signaling a process (a backend or an auxiliary process, like
* autovacuum worker). We can cope with simultaneous signals for different
* reasons. If the same reason is signaled multiple times in quick succession,
* however, the process is likely to observe only one notification of it.
* This is okay for the present uses.
*/
typedef enum
{
PROCSIG_CATCHUP_INTERRUPT, /* catchup interrupt */
NUM_PROCSIGNALS /* Must be last value of enum! */
} ProcSignalReason;
/* Flags for PGPROC->vacuumFlags */ /* Flags for PGPROC->vacuumFlags */
#define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */ #define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */
#define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */ #define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */
...@@ -93,6 +108,16 @@ struct PGPROC ...@@ -93,6 +108,16 @@ struct PGPROC
uint8 vacuumFlags; /* vacuum-related flags, see above */ uint8 vacuumFlags; /* vacuum-related flags, see above */
/*
* SIGUSR1 signal is multiplexed for multiple purposes. signalFlags
* indicates which "reasons" have been signaled.
*
* The flags are declared as "volatile sig_atomic_t" for maximum
* portability. This should ensure that loads and stores of the flag
* values are atomic, allowing us to dispense with any explicit locking.
*/
volatile sig_atomic_t signalFlags[NUM_PROCSIGNALS];
/* Info about LWLock the process is currently waiting for, if any. */ /* Info about LWLock the process is currently waiting for, if any. */
bool lwWaiting; /* true if waiting for an LW lock */ bool lwWaiting; /* true if waiting for an LW lock */
bool lwExclusive; /* true if waiting for exclusive access */ bool lwExclusive; /* true if waiting for exclusive access */
...@@ -171,6 +196,9 @@ extern void LockWaitCancel(void); ...@@ -171,6 +196,9 @@ extern void LockWaitCancel(void);
extern void ProcWaitForSignal(void); extern void ProcWaitForSignal(void);
extern void ProcSendSignal(int pid); extern void ProcSendSignal(int pid);
extern void SendProcSignal(PGPROC *proc, ProcSignalReason reason);
extern bool CheckProcSignal(ProcSignalReason reason);
extern bool enable_sig_alarm(int delayms, bool is_statement_timeout); extern bool enable_sig_alarm(int delayms, bool is_statement_timeout);
extern bool disable_sig_alarm(bool is_statement_timeout); extern bool disable_sig_alarm(bool is_statement_timeout);
extern void handle_sig_alarm(SIGNAL_ARGS); extern void handle_sig_alarm(SIGNAL_ARGS);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.48 2008/06/19 21:32:56 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.49 2008/12/09 14:28:20 heikki Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -90,7 +90,7 @@ extern void ReceiveSharedInvalidMessages( ...@@ -90,7 +90,7 @@ extern void ReceiveSharedInvalidMessages(
void (*resetFunction) (void)); void (*resetFunction) (void));
/* signal handler for catchup events (SIGUSR1) */ /* signal handler for catchup events (SIGUSR1) */
extern void CatchupInterruptHandler(SIGNAL_ARGS); extern void HandleCatchupInterrupt(void);
/* /*
* enable/disable processing of catchup events directly from signal handler. * enable/disable processing of catchup events directly from signal handler.
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.93 2008/03/10 12:55:13 mha Exp $ * $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.94 2008/12/09 14:28:20 heikki Exp $
* *
* OLD COMMENTS * OLD COMMENTS
* This file was created so that other c files could get the two * This file was created so that other c files could get the two
...@@ -56,6 +56,7 @@ extern List *pg_plan_queries(List *querytrees, int cursorOptions, ...@@ -56,6 +56,7 @@ extern List *pg_plan_queries(List *querytrees, int cursorOptions,
extern bool assign_max_stack_depth(int newval, bool doit, GucSource source); extern bool assign_max_stack_depth(int newval, bool doit, GucSource source);
extern void proc_sigusr1_handler(SIGNAL_ARGS);
extern void die(SIGNAL_ARGS); extern void die(SIGNAL_ARGS);
extern void quickdie(SIGNAL_ARGS); extern void quickdie(SIGNAL_ARGS);
extern void authdie(SIGNAL_ARGS); extern void authdie(SIGNAL_ARGS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment