Hi,
http://archives.postgresql.org/pgsql-hackers/2009-07/msg00191.php
In line with Robert's suggestion, I submit the signal multiplexing patch
as self-contained one.
This patch provides 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.
Regards,
--
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center
diff -rcN base/src/backend/bootstrap/bootstrap.c new/src/backend/bootstrap/bootstrap.c
*** base/src/backend/bootstrap/bootstrap.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/bootstrap/bootstrap.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 35,40 ****
--- 35,41 ----
#include "storage/bufmgr.h"
#include "storage/ipc.h"
#include "storage/proc.h"
+ #include "storage/procsignal.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
***************
*** 388,393 ****
--- 389,405 ----
InitAuxiliaryProcess();
#endif
+ /*
+ * Assign backend ID to auxiliary processes like backends, in order to
+ * allow multiplexing signal to auxiliary processes. Since backends use
+ * ID in the range from 1 to MaxBackends (inclusive), we assign
+ * auxiliary processes with MaxBackends + AuxProcType + 1 as an unique ID.
+ */
+ MyBackendId = MaxBackends + auxType + 1;
+ MyProc->backendId = MyBackendId;
+
+ ProcSignalInit();
+
/* finish setting up bufmgr.c */
InitBufferPoolBackend();
diff -rcN base/src/backend/postmaster/autovacuum.c new/src/backend/postmaster/autovacuum.c
*** base/src/backend/postmaster/autovacuum.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/postmaster/autovacuum.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 91,96 ****
--- 91,97 ----
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procarray.h"
+ #include "storage/procsignal.h"
#include "storage/sinvaladt.h"
#include "tcop/tcopprot.h"
#include "utils/dynahash.h"
***************
*** 1501,1507 ****
pqsignal(SIGALRM, handle_sig_alarm);
pqsignal(SIGPIPE, SIG_IGN);
! pqsignal(SIGUSR1, CatchupInterruptHandler);
/* We don't listen for async notifies */
pqsignal(SIGUSR2, SIG_IGN);
pqsignal(SIGFPE, FloatExceptionHandler);
--- 1502,1508 ----
pqsignal(SIGALRM, handle_sig_alarm);
pqsignal(SIGPIPE, SIG_IGN);
! pqsignal(SIGUSR1, procsignal_sigusr1_handler);
/* We don't listen for async notifies */
pqsignal(SIGUSR2, SIG_IGN);
pqsignal(SIGFPE, FloatExceptionHandler);
diff -rcN base/src/backend/storage/ipc/Makefile new/src/backend/storage/ipc/Makefile
*** base/src/backend/storage/ipc/Makefile 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/storage/ipc/Makefile 2009-06-30 15:02:42.000000000 +0900
***************
*** 15,21 ****
endif
endif
! OBJS = ipc.o ipci.o pmsignal.o procarray.o shmem.o shmqueue.o \
sinval.o sinvaladt.o
include $(top_srcdir)/src/backend/common.mk
--- 15,21 ----
endif
endif
! OBJS = ipc.o ipci.o pmsignal.o procarray.o procsignal.o shmem.o shmqueue.o \
sinval.o sinvaladt.o
include $(top_srcdir)/src/backend/common.mk
diff -rcN base/src/backend/storage/ipc/ipci.c new/src/backend/storage/ipc/ipci.c
*** base/src/backend/storage/ipc/ipci.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/storage/ipc/ipci.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 30,35 ****
--- 30,36 ----
#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
#include "storage/procarray.h"
+ #include "storage/procsignal.h"
#include "storage/sinvaladt.h"
#include "storage/spin.h"
***************
*** 114,119 ****
--- 115,121 ----
size = add_size(size, PMSignalShmemSize());
size = add_size(size, BgWriterShmemSize());
size = add_size(size, AutoVacuumShmemSize());
+ size = add_size(size, ProcSignalShmemSize());
size = add_size(size, BTreeShmemSize());
size = add_size(size, SyncScanShmemSize());
#ifdef EXEC_BACKEND
***************
*** 210,215 ****
--- 212,218 ----
PMSignalShmemInit();
BgWriterShmemInit();
AutoVacuumShmemInit();
+ ProcSignalShmemInit();
/*
* Set up other modules that need some shared memory space
diff -rcN base/src/backend/storage/ipc/procsignal.c new/src/backend/storage/ipc/procsignal.c
*** base/src/backend/storage/ipc/procsignal.c 1970-01-01 09:00:00.000000000 +0900
--- new/src/backend/storage/ipc/procsignal.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 0 ****
--- 1,216 ----
+ /*-------------------------------------------------------------------------
+ *
+ * procsignal.c
+ * routines for signaling processes
+ *
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+ #include "postgres.h"
+
+ #include <signal.h>
+ #include <unistd.h>
+
+ #include "bootstrap/bootstrap.h"
+ #include "miscadmin.h"
+ #include "storage/backendid.h"
+ #include "storage/ipc.h"
+ #include "storage/procsignal.h"
+ #include "storage/shmem.h"
+ #include "storage/sinval.h"
+
+ /*
+ * SIGUSR1 signal is multiplexed for multiple events. The specific reason
+ * is communicated via flags in shared memory. We keep a boolean flag for
+ * each possible "reason", so that different reasons can be signaled by
+ * different backends at the same time. (However, if the same reason is
+ * signaled more than once simultaneously, the process will observe it only
+ * once.)
+ *
+ * Each process that wants to receive signals registers its process ID
+ * in the ProcSignalSlots array. The array is indexed by backend ID to make
+ * slot allocation simple, and to avoid having to search the array when you
+ * know the backend ID of the process you're signaling.
+ *
+ * The flags are actually 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.
+ */
+ typedef struct {
+ pid_t pss_pid;
+ sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS];
+ } ProcSignalSlot;
+
+ static ProcSignalSlot *ProcSignalSlots;
+
+ static bool CheckProcSignal(ProcSignalReason reason);
+ static void CleanupProcSignalState(int status, Datum arg);
+
+ /*
+ * ProcSignalShmemInit - initialize during shared-memory creation
+ */
+ Size
+ ProcSignalShmemSize(void)
+ {
+ return (MaxBackends + NUM_AUXPROCTYPE) * sizeof(ProcSignalSlot);
+ }
+
+
+ /*
+ * ProcSignalShmemInit - initialize during shared-memory creation
+ */
+ void
+ ProcSignalShmemInit(void)
+ {
+ bool found;
+
+ ProcSignalSlots = (ProcSignalSlot *)
+ ShmemInitStruct("ProcSignalSlots", ProcSignalShmemSize(),
+ &found);
+
+ if (!found)
+ MemSet(ProcSignalSlots, 0, ProcSignalShmemSize());
+ }
+
+ /*
+ * ProcSignalInit - register a process to the procsignal array
+ */
+ void
+ ProcSignalInit(void)
+ {
+ volatile ProcSignalSlot *slot;
+
+ Assert(MyBackendId >= 1 &&
+ MyBackendId <= MaxBackends + NUM_AUXPROCTYPE);
+
+ slot = &ProcSignalSlots[MyBackendId - 1];
+ MemSet(slot->pss_signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
+ slot->pss_pid = MyProcPid;
+
+ on_shmem_exit(CleanupProcSignalState, Int32GetDatum(MyBackendId));
+ }
+
+
+ /*
+ * CleanupProcSignalState
+ * Remove current process from ProcSignalSlots
+ *
+ * This function is called via on_shmem_exit() during backend shutdown.
+ *
+ * arg is really of type "BackendId".
+ */
+ static void
+ CleanupProcSignalState(int status, Datum arg)
+ {
+ BackendId backendId = (BackendId) DatumGetInt32(arg);
+ volatile ProcSignalSlot *slot;
+
+ slot = &ProcSignalSlots[backendId - 1];
+
+ /* sanity check */
+ if (slot->pss_pid != MyProcPid)
+ {
+ /*
+ * don't ERROR here. We're exiting anyway, and don't want to
+ * get into infinite loop trying to exit
+ */
+ elog(WARNING, "current process not in ProcSignalSlots array");
+ return;
+ }
+ slot->pss_pid = 0;
+ }
+
+ /*
+ * SendProcSignal - signal a process with a reason code
+ *
+ * Providing backendId is optional, but it will speed up the operation.
+ *
+ * Not to be confused with ProcSendSignal
+ */
+ void
+ SendProcSignal(pid_t pid, ProcSignalReason reason, BackendId backendId)
+ {
+ volatile ProcSignalSlot *slot;
+
+ if (backendId != InvalidBackendId)
+ {
+ slot = &ProcSignalSlots[backendId - 1];
+
+ /*
+ * Note: Since there's no locking, it's possible that the target
+ * process detaches from shared memory and exits right after this
+ * test, before we set the flag and send signal. And the signal slot
+ * might even be recycled by a new process, so it's remotely possible
+ * that we set a flag for a wrong process. That's OK, all the signals
+ * are such that no harm is done if they're mistakenly fired.
+ */
+ if (slot->pss_pid == pid)
+ {
+ /* Atomically set the proper flag */
+ slot->pss_signalFlags[reason] = true;
+ /* Send signal */
+ kill(pid, SIGUSR1);
+ }
+ }
+ else
+ {
+ /* same as above, but linear search the array using pid */
+ int i;
+ for (i = 0; i <= MaxBackends + NUM_AUXPROCTYPE; i++)
+ {
+ slot = &ProcSignalSlots[i];
+ if (slot->pss_pid == pid)
+ {
+ /* the above note about race conditions applies here too */
+
+ /* Atomically set the proper flag */
+ slot->pss_signalFlags[reason] = true;
+ /* Send signal */
+ kill(pid, SIGUSR1);
+
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * CheckProcSignal - check to see if a particular reason has been
+ * signaled, and clear the signal flag. Should be called after receiving
+ * SIGUSR1.
+ */
+ static bool
+ CheckProcSignal(ProcSignalReason reason)
+ {
+ volatile ProcSignalSlot *slot;
+
+ slot = &ProcSignalSlots[MyBackendId - 1];
+
+ /* Careful here --- don't clear flag if we haven't seen it set */
+ if (slot->pss_signalFlags[reason])
+ {
+ slot->pss_signalFlags[reason] = false;
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * procsignal_sigusr1_handler - handle SIGUSR1 signal.
+ */
+ void
+ procsignal_sigusr1_handler(SIGNAL_ARGS)
+ {
+ int save_errno = errno;
+
+ if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT))
+ HandleCatchupInterrupt();
+
+ errno = save_errno;
+ }
diff -rcN base/src/backend/storage/ipc/sinval.c new/src/backend/storage/ipc/sinval.c
*** base/src/backend/storage/ipc/sinval.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/storage/ipc/sinval.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 26,33 ****
* 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
* it catch up before the sinval queue overflows and forces it to go
! * through a cache reset exercise. This is done by sending SIGUSR1
! * to any backend that gets too far behind.
*
* State for catchup events consists of two flags: one saying whether
* the signal handler is currently allowed to call ProcessCatchupEvent
--- 26,33 ----
* 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
* it catch up before the sinval queue overflows and forces it to go
! * through a cache reset exercise. This is done by sending
! * PROCSIG_CATHCUP_INTERRUPT to any backend that gets too far behind.
*
* State for catchup events consists of two flags: one saying whether
* the signal handler is currently allowed to call ProcessCatchupEvent
***************
*** 145,153 ****
/*
! * CatchupInterruptHandler
*
! * This is the signal handler for SIGUSR1.
*
* If we are idle (catchupInterruptEnabled is set), we can safely
* invoke ProcessCatchupEvent directly. Otherwise, just set a flag
--- 145,153 ----
/*
! * HandleCatchupInterrupt
*
! * This is called when PROCSIG_CATCHUP_INTERRUPT signal is received.
*
* If we are idle (catchupInterruptEnabled is set), we can safely
* invoke ProcessCatchupEvent directly. Otherwise, just set a flag
***************
*** 157,169 ****
* since there's no longer any reason to do anything.)
*/
void
! CatchupInterruptHandler(SIGNAL_ARGS)
{
- int save_errno = errno;
-
/*
! * Note: this is a SIGNAL HANDLER. You must be very wary what you do
! * here.
*/
/* Don't joggle the elbow of proc_exit */
--- 157,167 ----
* since there's no longer any reason to do anything.)
*/
void
! HandleCatchupInterrupt(void)
{
/*
! * Note: this called by a SIGNAL HANDLER. You must be very wary what
! * you do here.
*/
/* Don't joggle the elbow of proc_exit */
***************
*** 217,224 ****
*/
catchupInterruptOccurred = 1;
}
-
- errno = save_errno;
}
/*
--- 215,220 ----
***************
*** 290,296 ****
/*
* ProcessCatchupEvent
*
! * Respond to a catchup event (SIGUSR1) from another backend.
*
* This is called either directly from the SIGUSR1 signal handler,
* or the next time control reaches the outer idle loop (assuming
--- 286,293 ----
/*
* ProcessCatchupEvent
*
! * Respond to a catchup event (PROCSIG_CATCHUP_INTERRUPT) from another
! * backend.
*
* This is called either directly from the SIGUSR1 signal handler,
* or the next time control reaches the outer idle loop (assuming
diff -rcN base/src/backend/storage/ipc/sinvaladt.c new/src/backend/storage/ipc/sinvaladt.c
*** base/src/backend/storage/ipc/sinvaladt.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/storage/ipc/sinvaladt.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 21,26 ****
--- 21,27 ----
#include "storage/backendid.h"
#include "storage/ipc.h"
#include "storage/proc.h"
+ #include "storage/procsignal.h"
#include "storage/shmem.h"
#include "storage/sinvaladt.h"
#include "storage/spin.h"
***************
*** 138,143 ****
--- 139,145 ----
{
/* procPid is zero in an inactive ProcState array entry. */
pid_t procPid; /* PID of backend, for signaling */
+ BackendId backendId; /* backend ID, for signaling */
/* nextMsgNum is meaningless if procPid == 0 or resetState is true. */
int nextMsgNum; /* next message number to read */
bool resetState; /* backend needs to reset its state */
***************
*** 236,241 ****
--- 238,244 ----
for (i = 0; i < shmInvalBuffer->maxBackends; i++)
{
shmInvalBuffer->procState[i].procPid = 0; /* inactive */
+ shmInvalBuffer->procState[i].backendId = InvalidBackendId;
shmInvalBuffer->procState[i].nextMsgNum = 0; /* meaningless */
shmInvalBuffer->procState[i].resetState = false;
shmInvalBuffer->procState[i].signaled = false;
***************
*** 304,309 ****
--- 307,313 ----
/* mark myself active, with all extant messages already read */
stateP->procPid = MyProcPid;
+ stateP->backendId = MyBackendId;
stateP->nextMsgNum = segP->maxMsgNum;
stateP->resetState = false;
stateP->signaled = false;
***************
*** 342,347 ****
--- 346,352 ----
/* Mark myself inactive */
stateP->procPid = 0;
+ stateP->backendId = InvalidBackendId;
stateP->nextMsgNum = 0;
stateP->resetState = false;
stateP->signaled = false;
***************
*** 644,661 ****
segP->nextThreshold = (numMsgs / CLEANUP_QUANTUM + 1) * CLEANUP_QUANTUM;
/*
! * Lastly, signal anyone who needs a catchup interrupt. Since kill()
! * might not be fast, we don't want to hold locks while executing it.
*/
if (needSig)
{
! pid_t his_pid = needSig->procPid;
needSig->signaled = true;
LWLockRelease(SInvalReadLock);
LWLockRelease(SInvalWriteLock);
elog(DEBUG4, "sending sinval catchup signal to PID %d", (int) his_pid);
! kill(his_pid, SIGUSR1);
if (callerHasWriteLock)
LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE);
}
--- 649,668 ----
segP->nextThreshold = (numMsgs / CLEANUP_QUANTUM + 1) * CLEANUP_QUANTUM;
/*
! * Lastly, signal anyone who needs a catchup interrupt. Since
! * SendProcSignal() might not be fast, we don't want to hold locks while
! * executing it.
*/
if (needSig)
{
! pid_t his_pid = needSig->procPid;
! BackendId his_backendId = needSig->backendId;
needSig->signaled = true;
LWLockRelease(SInvalReadLock);
LWLockRelease(SInvalWriteLock);
elog(DEBUG4, "sending sinval catchup signal to PID %d", (int) his_pid);
! SendProcSignal(his_pid, PROCSIG_CATCHUP_INTERRUPT, his_backendId);
if (callerHasWriteLock)
LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE);
}
diff -rcN base/src/backend/tcop/postgres.c new/src/backend/tcop/postgres.c
*** base/src/backend/tcop/postgres.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/tcop/postgres.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 59,64 ****
--- 59,65 ----
#include "storage/bufmgr.h"
#include "storage/ipc.h"
#include "storage/proc.h"
+ #include "storage/procsignal.h"
#include "storage/sinval.h"
#include "tcop/fastpath.h"
#include "tcop/pquery.h"
***************
*** 3221,3227 ****
* of output during who-knows-what operation...
*/
pqsignal(SIGPIPE, SIG_IGN);
! pqsignal(SIGUSR1, CatchupInterruptHandler);
pqsignal(SIGUSR2, NotifyInterruptHandler);
pqsignal(SIGFPE, FloatExceptionHandler);
--- 3222,3228 ----
* of output during who-knows-what operation...
*/
pqsignal(SIGPIPE, SIG_IGN);
! pqsignal(SIGUSR1, procsignal_sigusr1_handler);
pqsignal(SIGUSR2, NotifyInterruptHandler);
pqsignal(SIGFPE, FloatExceptionHandler);
diff -rcN base/src/backend/utils/error/elog.c new/src/backend/utils/error/elog.c
*** base/src/backend/utils/error/elog.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/utils/error/elog.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 1807,1813 ****
break;
case 'v':
/* keep VXID format in sync with lockfuncs.c */
! if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
appendStringInfo(buf, "%d/%u",
MyProc->backendId, MyProc->lxid);
break;
--- 1807,1814 ----
break;
case 'v':
/* keep VXID format in sync with lockfuncs.c */
! if (MyProc != NULL &&
! MyProc->backendId >= 1 && MyProc->backendId <= MaxBackends)
appendStringInfo(buf, "%d/%u",
MyProc->backendId, MyProc->lxid);
break;
***************
*** 1952,1958 ****
/* Virtual transaction id */
/* keep VXID format in sync with lockfuncs.c */
! if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid);
appendStringInfoChar(&buf, ',');
--- 1953,1960 ----
/* Virtual transaction id */
/* keep VXID format in sync with lockfuncs.c */
! if (MyProc != NULL &&
! MyProc->backendId >= 1 && MyProc->backendId <= MaxBackends)
appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid);
appendStringInfoChar(&buf, ',');
diff -rcN base/src/backend/utils/init/postinit.c new/src/backend/utils/init/postinit.c
*** base/src/backend/utils/init/postinit.c 2009-06-30 15:02:41.000000000 +0900
--- new/src/backend/utils/init/postinit.c 2009-06-30 15:02:42.000000000 +0900
***************
*** 39,44 ****
--- 39,45 ----
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/procarray.h"
+ #include "storage/procsignal.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "utils/acl.h"
***************
*** 450,455 ****
--- 451,458 ----
if (MyBackendId > MaxBackends || MyBackendId <= 0)
elog(FATAL, "bad backend id: %d", MyBackendId);
+ ProcSignalInit();
+
/*
* bufmgr needs another initialization call too
*/
diff -rcN base/src/include/bootstrap/bootstrap.h new/src/include/bootstrap/bootstrap.h
*** base/src/include/bootstrap/bootstrap.h 2009-06-30 15:02:41.000000000 +0900
--- new/src/include/bootstrap/bootstrap.h 2009-06-30 15:02:42.000000000 +0900
***************
*** 70,76 ****
BootstrapProcess,
StartupProcess,
BgWriterProcess,
! WalWriterProcess
} AuxProcType;
#endif /* BOOTSTRAP_H */
--- 70,78 ----
BootstrapProcess,
StartupProcess,
BgWriterProcess,
! WalWriterProcess,
!
! NUM_AUXPROCTYPE
} AuxProcType;
#endif /* BOOTSTRAP_H */
diff -rcN base/src/include/storage/lock.h new/src/include/storage/lock.h
*** base/src/include/storage/lock.h 2009-06-30 15:02:41.000000000 +0900
--- new/src/include/storage/lock.h 2009-06-30 15:02:42.000000000 +0900
***************
*** 65,71 ****
#define InvalidLocalTransactionId 0
#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
#define VirtualTransactionIdIsValid(vxid) \
! (((vxid).backendId != InvalidBackendId) && \
LocalTransactionIdIsValid((vxid).localTransactionId))
#define VirtualTransactionIdEquals(vxid1, vxid2) \
((vxid1).backendId == (vxid2).backendId && \
--- 65,72 ----
#define InvalidLocalTransactionId 0
#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
#define VirtualTransactionIdIsValid(vxid) \
! (((vxid).backendId > InvalidBackendId) && \
! ((vxid).backendId <= MaxBackends) && \
LocalTransactionIdIsValid((vxid).localTransactionId))
#define VirtualTransactionIdEquals(vxid1, vxid2) \
((vxid1).backendId == (vxid2).backendId && \
diff -rcN base/src/include/storage/procsignal.h new/src/include/storage/procsignal.h
*** base/src/include/storage/procsignal.h 1970-01-01 09:00:00.000000000 +0900
--- new/src/include/storage/procsignal.h 2009-06-30 15:02:42.000000000 +0900
***************
*** 0 ****
--- 1,44 ----
+ /*-------------------------------------------------------------------------
+ *
+ * procsignal.h
+ * routines for signaling processes XXX
+ *
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+ #ifndef PROCSIGNAL_H
+ #define PROCSIGNAL_H
+
+ #include "storage/backendid.h"
+
+
+ /*
+ * 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;
+
+ /*
+ * prototypes for functions in procsignal.c
+ */
+ extern Size ProcSignalShmemSize(void);
+ extern void ProcSignalShmemInit(void);
+ extern void ProcSignalInit(void);
+ extern void SendProcSignal(pid_t pid, ProcSignalReason reason,
+ BackendId backendId);
+
+ extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
+
+ #endif /* PROCSIGNAL_H */
diff -rcN base/src/include/storage/sinval.h new/src/include/storage/sinval.h
*** base/src/include/storage/sinval.h 2009-06-30 15:02:41.000000000 +0900
--- new/src/include/storage/sinval.h 2009-06-30 15:02:42.000000000 +0900
***************
*** 89,96 ****
void (*invalFunction) (SharedInvalidationMessage *msg),
void (*resetFunction) (void));
! /* signal handler for catchup events (SIGUSR1) */
! extern void CatchupInterruptHandler(SIGNAL_ARGS);
/*
* enable/disable processing of catchup events directly from signal handler.
--- 89,96 ----
void (*invalFunction) (SharedInvalidationMessage *msg),
void (*resetFunction) (void));
! /* signal handler for catchup events (PROCSIG_CATCHUP_INTERRUPT) */
! extern void HandleCatchupInterrupt(void);
/*
* enable/disable processing of catchup events directly from signal handler.
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers