{
WaitLSNProcInfo *procInfo = &waitLSN->procInfos[MyProcNumber];
+ LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
+
Assert(!procInfo->inHeap);
procInfo->procnum = MyProcNumber;
procInfo->waitLSN = lsn;
- LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
-
pairingheap_add(&waitLSN->waitersHeap, &procInfo->phNode);
procInfo->inHeap = true;
updateMinWaitedLSN();
void
WaitLSNCleanup(void)
{
+ /*
+ * We do a fast-path check of the 'inHeap' flag without the lock. This
+ * flag is set to true only by the process itself. So, it's only possible
+ * to get a false positive. But that will be eliminated by a recheck
+ * inside deleteLSNWaiter().
+ */
if (waitLSN->procInfos[MyProcNumber].inHeap)
deleteLSNWaiter();
}
/*
* The minimum LSN value some process is waiting for. Used for the
* fast-path checking if we need to wake up any waiters after replaying a
- * WAL record.
+ * WAL record. Could be read lock-less. Update protected by WaitLSNLock.
*/
pg_atomic_uint64 minWaitedLSN;
*/
pairingheap waitersHeap;
- /* An array with per-process information, indexed by the process number */
+ /*
+ * An array with per-process information, indexed by the process number.
+ * Protected by WaitLSNLock.
+ */
WaitLSNProcInfo procInfos[FLEXIBLE_ARRAY_MEMBER];
} WaitLSNState;