aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlog.c5
-rw-r--r--src/backend/commands/user.c7
-rw-r--r--src/backend/postmaster/postmaster.c208
-rw-r--r--src/backend/storage/ipc/Makefile4
-rw-r--r--src/backend/storage/ipc/ipci.c8
-rw-r--r--src/backend/storage/ipc/pmsignal.c86
-rw-r--r--src/backend/storage/ipc/sinvaladt.c18
-rw-r--r--src/include/storage/pmsignal.h39
8 files changed, 254 insertions, 121 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index c0bfe968d25..e5c2f7d7582 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.80 2001/10/28 06:25:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.81 2001/11/04 19:55:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,6 +35,7 @@
#include "catalog/pg_control.h"
#include "storage/bufpage.h"
#include "storage/lwlock.h"
+#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/sinval.h"
#include "storage/spin.h"
@@ -1048,7 +1049,7 @@ XLogWrite(XLogwrtRqst WriteRqst)
{
if (XLOG_DEBUG)
elog(DEBUG, "XLogWrite: time for a checkpoint, signaling postmaster");
- kill(getppid(), SIGUSR1);
+ SendPostmasterSignal(PMSIGNAL_DO_CHECKPOINT);
}
}
LWLockRelease(ControlFileLock);
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 3897a5c75ec..9b95ecad274 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.88 2001/11/02 18:39:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.89 2001/11/04 19:55:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,7 +15,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <signal.h>
#include <unistd.h>
#include "access/heapam.h"
@@ -27,6 +26,7 @@
#include "commands/user.h"
#include "libpq/crypt.h"
#include "miscadmin.h"
+#include "storage/pmsignal.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
@@ -180,8 +180,7 @@ write_password_file(Relation rel)
/*
* Signal the postmaster to reload its password-file cache.
*/
- if (IsUnderPostmaster)
- kill(getppid(), SIGHUP);
+ SendPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE);
}
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 2c96486cd06..ae8e5a6fe15 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.254 2001/11/02 18:39:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.255 2001/11/04 19:55:31 tgl Exp $
*
* NOTES
*
@@ -98,6 +98,7 @@
#include "nodes/nodes.h"
#include "storage/fd.h"
#include "storage/ipc.h"
+#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "access/xlog.h"
#include "tcop/tcopprot.h"
@@ -155,9 +156,6 @@ int MaxBackends = DEF_MAXBACKENDS;
static char *progname = (char *) NULL;
-/* flag to indicate that SIGHUP arrived during server loop */
-static volatile bool got_SIGHUP = false;
-
/*
* Default Values
*/
@@ -239,7 +237,8 @@ static void reset_shared(unsigned short port);
static void SIGHUP_handler(SIGNAL_ARGS);
static void pmdie(SIGNAL_ARGS);
static void reaper(SIGNAL_ARGS);
-static void schedule_checkpoint(SIGNAL_ARGS);
+static void sigusr1_handler(SIGNAL_ARGS);
+static void dummy_handler(SIGNAL_ARGS);
static void CleanupProc(int pid, int exitstatus);
static int DoBackend(Port *port);
static void ExitPostmaster(int status);
@@ -722,9 +721,8 @@ PostmasterMain(int argc, char *argv[])
pqsignal(SIGTERM, pmdie); /* wait for children and ShutdownDataBase */
pqsignal(SIGALRM, SIG_IGN); /* ignored */
pqsignal(SIGPIPE, SIG_IGN); /* ignored */
- pqsignal(SIGUSR1, schedule_checkpoint); /* start a background
- * checkpoint */
- pqsignal(SIGUSR2, pmdie); /* send SIGUSR2, don't die */
+ pqsignal(SIGUSR1, sigusr1_handler); /* message from child process */
+ pqsignal(SIGUSR2, dummy_handler); /* unused, reserve for children */
pqsignal(SIGCHLD, reaper); /* handle child termination */
pqsignal(SIGTTIN, SIG_IGN); /* ignored */
pqsignal(SIGTTOU, SIG_IGN); /* ignored */
@@ -867,8 +865,19 @@ ServerLoop(void)
Port *port;
fd_set rmask,
wmask;
- struct timeval *timeout = NULL;
- struct timeval timeout_tv;
+ struct timeval timeout;
+
+ /*
+ * The timeout for the select() below is normally set on the basis
+ * of the time to the next checkpoint. However, if for some reason
+ * we don't have a next-checkpoint time, time out after 60 seconds.
+ * This keeps checkpoint scheduling from locking up when we get new
+ * connection requests infrequently (since we are likely to detect
+ * checkpoint completion just after enabling signals below, after
+ * we've already made the decision about how long to wait this time).
+ */
+ timeout.tv_sec = 60;
+ timeout.tv_usec = 0;
if (CheckPointPID == 0 && checkpointed &&
Shutdown == NoShutdown && !FatalError && random_seed != 0)
@@ -878,12 +887,9 @@ ServerLoop(void)
if (CheckPointTimeout + checkpointed > now)
{
/*
- * Not time for checkpoint yet, so set a timeout for
- * select
+ * Not time for checkpoint yet, so set select timeout
*/
- timeout_tv.tv_sec = CheckPointTimeout + checkpointed - now;
- timeout_tv.tv_usec = 0;
- timeout = &timeout_tv;
+ timeout.tv_sec = CheckPointTimeout + checkpointed - now;
}
else
{
@@ -895,7 +901,10 @@ ServerLoop(void)
* delay
*/
if (CheckPointPID == 0)
- checkpointed = now - (9 * CheckPointTimeout) / 10;
+ {
+ timeout.tv_sec = CheckPointTimeout / 10;
+ checkpointed = now + timeout.tv_sec - CheckPointTimeout;
+ }
}
}
@@ -907,32 +916,22 @@ ServerLoop(void)
PG_SETMASK(&UnBlockSig);
- if (select(nSockets, &rmask, &wmask, (fd_set *) NULL, timeout) < 0)
+ if (select(nSockets, &rmask, &wmask, (fd_set *) NULL, &timeout) < 0)
{
PG_SETMASK(&BlockSig);
if (errno == EINTR || errno == EWOULDBLOCK)
continue;
- elog(DEBUG, "ServerLoop: select failed: %s", strerror(errno));
+ elog(DEBUG, "ServerLoop: select failed: %m");
return STATUS_ERROR;
}
/*
- * Block all signals until we wait again
+ * Block all signals until we wait again. (This makes it safe
+ * for our signal handlers to do nontrivial work.)
*/
PG_SETMASK(&BlockSig);
/*
- * Respond to signals, if needed
- */
- if (got_SIGHUP)
- {
- got_SIGHUP = false;
- ProcessConfigFile(PGC_SIGHUP);
- load_hba_and_ident();
- load_password_cache();
- }
-
- /*
* Select a random seed at the time of first receiving a request.
*/
while (random_seed == 0)
@@ -1382,10 +1381,13 @@ SIGHUP_handler(SIGNAL_ARGS)
if (Shutdown <= SmartShutdown)
{
- got_SIGHUP = true;
SignalChildren(SIGHUP);
+ ProcessConfigFile(PGC_SIGHUP);
+ load_hba_and_ident();
}
+ PG_SETMASK(&UnBlockSig);
+
errno = save_errno;
}
@@ -1406,20 +1408,6 @@ pmdie(SIGNAL_ARGS)
switch (postgres_signal_arg)
{
- case SIGUSR2:
-
- /*
- * Send SIGUSR2 to all children (AsyncNotifyHandler)
- */
- if (Shutdown > SmartShutdown)
- {
- errno = save_errno;
- return;
- }
- SignalChildren(SIGUSR2);
- errno = save_errno;
- return;
-
case SIGTERM:
/*
@@ -1428,27 +1416,18 @@ pmdie(SIGNAL_ARGS)
* Wait for children to end their work and ShutdownDataBase.
*/
if (Shutdown >= SmartShutdown)
- {
- errno = save_errno;
- return;
- }
+ break;
Shutdown = SmartShutdown;
elog(DEBUG, "smart shutdown request");
if (DLGetHead(BackendList)) /* let reaper() handle this */
- {
- errno = save_errno;
- return;
- }
+ break;
/*
* No children left. Shutdown data base system.
*/
if (StartupPID > 0 || FatalError) /* let reaper() handle
* this */
- {
- errno = save_errno;
- return;
- }
+ break;
if (ShutdownPID > 0)
{
elog(REALLYFATAL, "shutdown process %d already running",
@@ -1457,8 +1436,7 @@ pmdie(SIGNAL_ARGS)
}
ShutdownPID = ShutdownDataBase();
- errno = save_errno;
- return;
+ break;
case SIGINT:
@@ -1469,10 +1447,7 @@ pmdie(SIGNAL_ARGS)
* and exit) and ShutdownDataBase when they are gone.
*/
if (Shutdown >= FastShutdown)
- {
- errno = save_errno;
- return;
- }
+ break;
elog(DEBUG, "fast shutdown request");
if (DLGetHead(BackendList)) /* let reaper() handle this */
{
@@ -1482,14 +1457,12 @@ pmdie(SIGNAL_ARGS)
elog(DEBUG, "aborting any active transactions");
SignalChildren(SIGTERM);
}
- errno = save_errno;
- return;
+ break;
}
if (Shutdown > NoShutdown)
{
Shutdown = FastShutdown;
- errno = save_errno;
- return;
+ break;
}
Shutdown = FastShutdown;
@@ -1498,10 +1471,7 @@ pmdie(SIGNAL_ARGS)
*/
if (StartupPID > 0 || FatalError) /* let reaper() handle
* this */
- {
- errno = save_errno;
- return;
- }
+ break;
if (ShutdownPID > 0)
{
elog(REALLYFATAL, "shutdown process %d already running",
@@ -1510,8 +1480,7 @@ pmdie(SIGNAL_ARGS)
}
ShutdownPID = ShutdownDataBase();
- errno = save_errno;
- return;
+ break;
case SIGQUIT:
@@ -1528,11 +1497,13 @@ pmdie(SIGNAL_ARGS)
kill(StartupPID, SIGQUIT);
if (DLGetHead(BackendList))
SignalChildren(SIGQUIT);
+ ExitPostmaster(0);
break;
}
- /* exit postmaster */
- ExitPostmaster(0);
+ PG_SETMASK(&UnBlockSig);
+
+ errno = save_errno;
}
/*
@@ -1542,10 +1513,8 @@ static void
reaper(SIGNAL_ARGS)
{
int save_errno = errno;
-
#ifdef HAVE_WAITPID
int status; /* backend exit status */
-
#else
union wait status; /* backend exit status */
#endif
@@ -1553,8 +1522,6 @@ reaper(SIGNAL_ARGS)
int pid; /* process id of dead backend */
PG_SETMASK(&BlockSig);
- /* It's not really necessary to reset the handler each time is it? */
- pqsignal(SIGCHLD, reaper);
if (DebugLvl)
elog(DEBUG, "reaping dead processes");
@@ -1640,8 +1607,7 @@ reaper(SIGNAL_ARGS)
CheckPointPID = 0;
checkpointed = time(NULL);
- errno = save_errno;
- return;
+ goto reaper_done;
}
CleanupProc(pid, exitstatus);
@@ -1654,35 +1620,29 @@ reaper(SIGNAL_ARGS)
* StartupDataBase.
*/
if (DLGetHead(BackendList) || StartupPID > 0 || ShutdownPID > 0)
- {
- errno = save_errno;
- return;
- }
+ goto reaper_done;
elog(DEBUG, "all server processes terminated; reinitializing shared memory and semaphores");
shmem_exit(0);
reset_shared(PostPortNumber);
StartupPID = StartupDataBase();
- errno = save_errno;
- return;
+
+ goto reaper_done;
}
if (Shutdown > NoShutdown)
{
if (DLGetHead(BackendList))
- {
- errno = save_errno;
- return;
- }
+ goto reaper_done;
if (StartupPID > 0 || ShutdownPID > 0)
- {
- errno = save_errno;
- return;
- }
+ goto reaper_done;
ShutdownPID = ShutdownDataBase();
}
+reaper_done:
+ PG_SETMASK(&UnBlockSig);
+
errno = save_errno;
}
@@ -2260,27 +2220,71 @@ ExitPostmaster(int status)
proc_exit(status);
}
-/* Request to schedule a checkpoint (no-op if one is currently running) */
+/*
+ * sigusr1_handler - handle signal conditions from child processes
+ */
static void
-schedule_checkpoint(SIGNAL_ARGS)
+sigusr1_handler(SIGNAL_ARGS)
{
int save_errno = errno;
PG_SETMASK(&BlockSig);
- /* Ignore request if checkpointing is currently disabled */
- if (CheckPointPID == 0 && checkpointed &&
- Shutdown == NoShutdown && !FatalError && random_seed != 0)
+ if (CheckPostmasterSignal(PMSIGNAL_DO_CHECKPOINT))
{
- CheckPointPID = CheckPointDataBase();
- /* note: if fork fails, CheckPointPID stays 0; nothing happens */
+ /*
+ * Request to schedule a checkpoint
+ *
+ * Ignore request if checkpoint is already running or
+ * checkpointing is currently disabled
+ */
+ if (CheckPointPID == 0 && checkpointed &&
+ Shutdown == NoShutdown && !FatalError && random_seed != 0)
+ {
+ CheckPointPID = CheckPointDataBase();
+ /* note: if fork fails, CheckPointPID stays 0; nothing happens */
+ }
+ }
+
+ if (CheckPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE))
+ {
+ /*
+ * Password file has changed.
+ */
+ load_password_cache();
}
+ if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN))
+ {
+ /*
+ * Send SIGUSR2 to all children (triggers AsyncNotifyHandler).
+ * See storage/ipc/sinvaladt.c for the use of this.
+ */
+ if (Shutdown == NoShutdown)
+ SignalChildren(SIGUSR2);
+ }
+
+ PG_SETMASK(&UnBlockSig);
+
errno = save_errno;
}
/*
+ * Dummy signal handler
+ *
+ * We use this for signals that we don't actually use in the postmaster,
+ * but we do use in backends. If we SIG_IGN such signals in the postmaster,
+ * then a newly started backend might drop a signal that arrives before it's
+ * able to reconfigure its signal processing. (See notes in postgres.c.)
+ */
+static void
+dummy_handler(SIGNAL_ARGS)
+{
+}
+
+
+/*
* CharRemap: given an int in range 0..61, produce textual encoding of it
* per crypt(3) conventions.
*/
diff --git a/src/backend/storage/ipc/Makefile b/src/backend/storage/ipc/Makefile
index 585ae7f6eff..960097b1d18 100644
--- a/src/backend/storage/ipc/Makefile
+++ b/src/backend/storage/ipc/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for storage/ipc
#
-# $Header: /cvsroot/pgsql/src/backend/storage/ipc/Makefile,v 1.16 2001/09/27 19:10:02 tgl Exp $
+# $Header: /cvsroot/pgsql/src/backend/storage/ipc/Makefile,v 1.17 2001/11/04 19:55:31 tgl Exp $
#
subdir = src/backend/storage/ipc
@@ -15,7 +15,7 @@ override CFLAGS+= -fno-inline
endif
endif
-OBJS = ipc.o ipci.o shmem.o shmqueue.o sinval.o sinvaladt.o
+OBJS = ipc.o ipci.o pmsignal.o shmem.o shmqueue.o sinval.o sinvaladt.o
all: SUBSYS.o
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index cf841a614d3..9b178883fe4 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.44 2001/10/25 05:49:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.45 2001/11/04 19:55:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +23,7 @@
#include "storage/freespace.h"
#include "storage/lmgr.h"
#include "storage/lwlock.h"
+#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/sinval.h"
#include "storage/spin.h"
@@ -121,4 +122,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int maxBackends)
* Set up free-space map
*/
InitFreeSpaceMap();
+
+ /*
+ * Set up child-to-postmaster signaling mechanism
+ */
+ PMSignalInit();
}
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
new file mode 100644
index 00000000000..38c5d730c7f
--- /dev/null
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -0,0 +1,86 @@
+/*-------------------------------------------------------------------------
+ *
+ * pmsignal.c
+ * routines for signaling the postmaster from its child processes
+ *
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/pmsignal.c,v 1.1 2001/11/04 19:55:31 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include <signal.h>
+#include <unistd.h>
+
+#include "miscadmin.h"
+#include "storage/pmsignal.h"
+#include "storage/shmem.h"
+
+
+/*
+ * The postmaster is signaled by its children by sending SIGUSR1. 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
+ * postmaster will observe it only once.)
+ *
+ * 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.
+ */
+
+static volatile sig_atomic_t * PMSignalFlags;
+
+
+/*
+ * PMSignalInit - initialize during shared-memory creation
+ */
+void
+PMSignalInit(void)
+{
+ /* Should be called only once */
+ Assert(!PMSignalFlags);
+
+ PMSignalFlags = (sig_atomic_t *)
+ ShmemAlloc(NUM_PMSIGNALS * sizeof(sig_atomic_t));
+
+ MemSet(PMSignalFlags, 0, NUM_PMSIGNALS * sizeof(sig_atomic_t));
+}
+
+/*
+ * SendPostmasterSignal - signal the postmaster from a child process
+ */
+void
+SendPostmasterSignal(PMSignalReason reason)
+{
+ /* If called in a standalone backend, do nothing */
+ if (!IsUnderPostmaster)
+ return;
+ /* Atomically set the proper flag */
+ PMSignalFlags[reason] = true;
+ /* Send signal to postmaster (assume it is our direct parent) */
+ kill(getppid(), SIGUSR1);
+}
+
+/*
+ * CheckPostmasterSignal - check to see if a particular reason has been
+ * signaled, and clear the signal flag. Should be called by postmaster
+ * after receiving SIGUSR1.
+ */
+bool
+CheckPostmasterSignal(PMSignalReason reason)
+{
+ /* Careful here --- don't clear flag if we haven't seen it set */
+ if (PMSignalFlags[reason])
+ {
+ PMSignalFlags[reason] = false;
+ return true;
+ }
+ return false;
+}
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index d05a651097f..35931f00a14 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -8,17 +8,15 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.41 2001/09/29 04:02:24 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.42 2001/11/04 19:55:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include <signal.h>
-#include <unistd.h>
-
#include "miscadmin.h"
#include "storage/backendid.h"
+#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/sinvaladt.h"
@@ -205,11 +203,11 @@ SIInsertDataEntry(SISeg *segP, SharedInvalidationMessage *data)
/*
* Try to prevent table overflow. When the table is 70% full send a
- * SIGUSR2 (ordinarily a NOTIFY signal) to the postmaster, which will
- * send it back to all the backends. This will force idle backends to
- * execute a transaction to look through pg_listener for NOTIFY
- * messages, and as a byproduct of the transaction start they will
- * read SI entries.
+ * WAKEN_CHILDREN request to the postmaster. The postmaster will send
+ * a SIGUSR2 signal (ordinarily a NOTIFY signal) to all the backends.
+ * This will force idle backends to execute a transaction to look through
+ * pg_listener for NOTIFY messages, and as a byproduct of the transaction
+ * start they will read SI entries.
*
* This should never happen if all the backends are actively executing
* queries, but if a backend is sitting idle then it won't be starting
@@ -222,7 +220,7 @@ SIInsertDataEntry(SISeg *segP, SharedInvalidationMessage *data)
{
if (DebugLvl >= 1)
elog(DEBUG, "SIInsertDataEntry: table is 70%% full, signaling postmaster");
- kill(getppid(), SIGUSR2);
+ SendPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN);
}
/*
diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h
new file mode 100644
index 00000000000..f86c06656ef
--- /dev/null
+++ b/src/include/storage/pmsignal.h
@@ -0,0 +1,39 @@
+/*-------------------------------------------------------------------------
+ *
+ * pmsignal.h
+ * routines for signaling the postmaster from its child processes
+ *
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: pmsignal.h,v 1.1 2001/11/04 19:55:31 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PMSIGNAL_H
+#define PMSIGNAL_H
+
+/*
+ * Reasons for signaling the postmaster. We can cope with simultaneous
+ * signals for different reasons. If the same reason is signaled multiple
+ * times in quick succession, however, the postmaster is likely to observe
+ * only one notification of it. This is okay for the present uses.
+ */
+typedef enum
+{
+ PMSIGNAL_DO_CHECKPOINT, /* request to start a checkpoint */
+ PMSIGNAL_PASSWORD_CHANGE, /* pg_pwd file has changed */
+ PMSIGNAL_WAKEN_CHILDREN, /* send a NOTIFY signal to all backends */
+
+ NUM_PMSIGNALS /* Must be last value of enum! */
+} PMSignalReason;
+
+/*
+ * prototypes for functions in pmsignal.c
+ */
+extern void PMSignalInit(void);
+extern void SendPostmasterSignal(PMSignalReason reason);
+extern bool CheckPostmasterSignal(PMSignalReason reason);
+
+#endif /* PMSIGNAL_H */