mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
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.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 @@
|
||||
#include "storage/backendid.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/sinvaladt.h"
|
||||
#include "storage/spin.h"
|
||||
@@ -136,9 +137,9 @@
|
||||
/* Per-backend state in shared invalidation structure */
|
||||
typedef struct ProcState
|
||||
{
|
||||
/* procPid is zero in an inactive ProcState array entry. */
|
||||
pid_t procPid; /* PID of backend, for signaling */
|
||||
/* nextMsgNum is meaningless if procPid == 0 or resetState is true. */
|
||||
/* proc is NULL in an inactive ProcState array entry. */
|
||||
PGPROC *proc; /* PGPROC entry of backend, for signaling */
|
||||
/* nextMsgNum is meaningless if proc == NULL or resetState is true. */
|
||||
int nextMsgNum; /* next message number to read */
|
||||
bool resetState; /* backend needs to reset its state */
|
||||
bool signaled; /* backend has been sent catchup signal */
|
||||
@@ -235,7 +236,7 @@ CreateSharedInvalidationState(void)
|
||||
/* Mark all backends inactive, and initialize nextLXID */
|
||||
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].resetState = false;
|
||||
shmInvalBuffer->procState[i].signaled = false;
|
||||
@@ -266,7 +267,7 @@ SharedInvalBackendInit(void)
|
||||
/* Look for a free entry in the procState array */
|
||||
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];
|
||||
break;
|
||||
@@ -278,7 +279,7 @@ SharedInvalBackendInit(void)
|
||||
if (segP->lastBackend < segP->maxBackends)
|
||||
{
|
||||
stateP = &segP->procState[segP->lastBackend];
|
||||
Assert(stateP->procPid == 0);
|
||||
Assert(stateP->proc == NULL);
|
||||
segP->lastBackend++;
|
||||
}
|
||||
else
|
||||
@@ -303,7 +304,7 @@ SharedInvalBackendInit(void)
|
||||
nextLocalTransactionId = stateP->nextLXID;
|
||||
|
||||
/* mark myself active, with all extant messages already read */
|
||||
stateP->procPid = MyProcPid;
|
||||
stateP->proc = MyProc;
|
||||
stateP->nextMsgNum = segP->maxMsgNum;
|
||||
stateP->resetState = false;
|
||||
stateP->signaled = false;
|
||||
@@ -341,7 +342,7 @@ CleanupInvalidationState(int status, Datum arg)
|
||||
stateP->nextLXID = nextLocalTransactionId;
|
||||
|
||||
/* Mark myself inactive */
|
||||
stateP->procPid = 0;
|
||||
stateP->proc = NULL;
|
||||
stateP->nextMsgNum = 0;
|
||||
stateP->resetState = false;
|
||||
stateP->signaled = false;
|
||||
@@ -349,7 +350,7 @@ CleanupInvalidationState(int status, Datum arg)
|
||||
/* Recompute index of last active backend */
|
||||
for (i = segP->lastBackend; i > 0; i--)
|
||||
{
|
||||
if (segP->procState[i - 1].procPid != 0)
|
||||
if (segP->procState[i - 1].proc != NULL)
|
||||
break;
|
||||
}
|
||||
segP->lastBackend = i;
|
||||
@@ -374,7 +375,7 @@ BackendIdIsActive(int backendID)
|
||||
{
|
||||
ProcState *stateP = &segP->procState[backendID - 1];
|
||||
|
||||
result = (stateP->procPid != 0);
|
||||
result = (stateP->proc != NULL);
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
@@ -590,7 +591,7 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
|
||||
int n = stateP->nextMsgNum;
|
||||
|
||||
/* Ignore if inactive or already in reset state */
|
||||
if (stateP->procPid == 0 || stateP->resetState)
|
||||
if (stateP->proc == NULL || stateP->resetState)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -644,18 +645,20 @@ SICleanupQueue(bool callerHasWriteLock, int minFree)
|
||||
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.
|
||||
* 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;
|
||||
PGPROC *his_proc = needSig->proc;
|
||||
|
||||
needSig->signaled = true;
|
||||
LWLockRelease(SInvalReadLock);
|
||||
LWLockRelease(SInvalWriteLock);
|
||||
elog(DEBUG4, "sending sinval catchup signal to PID %d", (int) his_pid);
|
||||
kill(his_pid, SIGUSR1);
|
||||
elog(DEBUG4, "sending sinval catchup signal to PID %d",
|
||||
(int) his_proc->pid);
|
||||
SendProcSignal(his_proc, PROCSIG_CATCHUP_INTERRUPT);
|
||||
if (callerHasWriteLock)
|
||||
LWLockAcquire(SInvalWriteLock, LW_EXCLUSIVE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user