mirror of
https://github.com/postgres/postgres.git
synced 2025-09-06 13:46:51 +03:00
Add a default local latch for use in signal handlers.
To do so, move InitializeLatchSupport() into the new common process initialization functions, and add a new global variable MyLatch. MyLatch is usable as soon InitPostmasterChild() has been called (i.e. very early during startup). Initially it points to a process local latch that exists in all processes. InitProcess/InitAuxiliaryProcess then replaces that local latch with PGPROC->procLatch. During shutdown the reverse happens. This is primarily advantageous for two reasons: For one it simplifies dealing with the shared process latch, especially in signal handlers, because instead of having to check for MyProc, MyLatch can be used unconditionally. For another, a later patch that makes FEs/BE communication use latches, now can rely on the existence of a latch, even before having gone through InitProcess. Discussion: 20140927191243.GD5423@alap3.anarazel.de
This commit is contained in:
@@ -292,8 +292,8 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
|
||||
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
|
||||
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
|
||||
|
||||
if (set_latch_on_sigusr1 && MyProc != NULL)
|
||||
SetLatch(&MyProc->procLatch);
|
||||
if (set_latch_on_sigusr1)
|
||||
SetLatch(MyLatch);
|
||||
|
||||
latch_sigusr1_handler();
|
||||
|
||||
|
@@ -827,13 +827,13 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
|
||||
* at top of loop, because setting an already-set latch is much
|
||||
* cheaper than setting one that has been reset.
|
||||
*/
|
||||
WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0);
|
||||
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
||||
|
||||
/* An interrupt may have occurred while we were waiting. */
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
/* Reset the latch so we don't spin. */
|
||||
ResetLatch(&MyProc->procLatch);
|
||||
ResetLatch(MyLatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -924,13 +924,13 @@ shm_mq_receive_bytes(shm_mq *mq, Size bytes_needed, bool nowait,
|
||||
* loop, because setting an already-set latch is much cheaper than
|
||||
* setting one that has been reset.
|
||||
*/
|
||||
WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0);
|
||||
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
||||
|
||||
/* An interrupt may have occurred while we were waiting. */
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
/* Reset the latch so we don't spin. */
|
||||
ResetLatch(&MyProc->procLatch);
|
||||
ResetLatch(MyLatch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,13 +991,13 @@ shm_mq_wait_internal(volatile shm_mq *mq, PGPROC *volatile * ptr,
|
||||
}
|
||||
|
||||
/* Wait to be signalled. */
|
||||
WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0);
|
||||
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
||||
|
||||
/* An interrupt may have occurred while we were waiting. */
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
/* Reset the latch so we don't spin. */
|
||||
ResetLatch(&MyProc->procLatch);
|
||||
ResetLatch(MyLatch);
|
||||
}
|
||||
}
|
||||
PG_CATCH();
|
||||
|
@@ -290,13 +290,6 @@ InitProcess(void)
|
||||
if (MyProc != NULL)
|
||||
elog(ERROR, "you already exist");
|
||||
|
||||
/*
|
||||
* Initialize process-local latch support. This could fail if the kernel
|
||||
* is low on resources, and if so we want to exit cleanly before acquiring
|
||||
* any shared-memory resources.
|
||||
*/
|
||||
InitializeLatchSupport();
|
||||
|
||||
/*
|
||||
* Try to get a proc struct from the free list. If this fails, we must be
|
||||
* out of PGPROC structures (not to mention semaphores).
|
||||
@@ -391,10 +384,12 @@ InitProcess(void)
|
||||
SHMQueueElemInit(&(MyProc->syncRepLinks));
|
||||
|
||||
/*
|
||||
* Acquire ownership of the PGPROC's latch, so that we can use WaitLatch.
|
||||
* Note that there's no particular need to do ResetLatch here.
|
||||
* Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
|
||||
* on it. That allows us to repoint the process latch, which so far
|
||||
* points to process local one, to the shared one.
|
||||
*/
|
||||
OwnLatch(&MyProc->procLatch);
|
||||
SwitchToSharedLatch();
|
||||
|
||||
/*
|
||||
* We might be reusing a semaphore that belonged to a failed process. So
|
||||
@@ -474,13 +469,6 @@ InitAuxiliaryProcess(void)
|
||||
if (MyProc != NULL)
|
||||
elog(ERROR, "you already exist");
|
||||
|
||||
/*
|
||||
* Initialize process-local latch support. This could fail if the kernel
|
||||
* is low on resources, and if so we want to exit cleanly before acquiring
|
||||
* any shared-memory resources.
|
||||
*/
|
||||
InitializeLatchSupport();
|
||||
|
||||
/*
|
||||
* We use the ProcStructLock to protect assignment and releasing of
|
||||
* AuxiliaryProcs entries.
|
||||
@@ -547,10 +535,12 @@ InitAuxiliaryProcess(void)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Acquire ownership of the PGPROC's latch, so that we can use WaitLatch.
|
||||
* Note that there's no particular need to do ResetLatch here.
|
||||
* Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
|
||||
* on it. That allows us to repoint the process latch, which so far
|
||||
* points to process local one, to the shared one.
|
||||
*/
|
||||
OwnLatch(&MyProc->procLatch);
|
||||
SwitchToSharedLatch();
|
||||
|
||||
/*
|
||||
* We might be reusing a semaphore that belonged to a failed process. So
|
||||
@@ -800,10 +790,12 @@ ProcKill(int code, Datum arg)
|
||||
ReplicationSlotRelease();
|
||||
|
||||
/*
|
||||
* Clear MyProc first; then disown the process latch. This is so that
|
||||
* signal handlers won't try to clear the process latch after it's no
|
||||
* longer ours.
|
||||
* Reset MyLatch to the process local one. This is so that signal
|
||||
* handlers et al can continue using the latch after the shared latch
|
||||
* isn't ours anymore. After that clear MyProc and disown the shared
|
||||
* latch.
|
||||
*/
|
||||
SwitchBackToLocalLatch();
|
||||
proc = MyProc;
|
||||
MyProc = NULL;
|
||||
DisownLatch(&proc->procLatch);
|
||||
@@ -867,10 +859,12 @@ AuxiliaryProcKill(int code, Datum arg)
|
||||
LWLockReleaseAll();
|
||||
|
||||
/*
|
||||
* Clear MyProc first; then disown the process latch. This is so that
|
||||
* signal handlers won't try to clear the process latch after it's no
|
||||
* longer ours.
|
||||
* Reset MyLatch to the process local one. This is so that signal
|
||||
* handlers et al can continue using the latch after the shared latch
|
||||
* isn't ours anymore. After that clear MyProc and disown the shared
|
||||
* latch.
|
||||
*/
|
||||
SwitchBackToLocalLatch();
|
||||
proc = MyProc;
|
||||
MyProc = NULL;
|
||||
DisownLatch(&proc->procLatch);
|
||||
|
Reference in New Issue
Block a user