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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers