1/*-------------------------------------------------------------------------
4 * Routines for inter-process latches
6 * The latch interface is a reliable replacement for the common pattern of
7 * using pg_usleep() or select() to wait until a signal arrives, where the
8 * signal handler sets a flag variable. See latch.h for more information
11 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
15 * src/backend/storage/ipc/latch.c
17 *-------------------------------------------------------------------------
27/* A common WaitEventSet used to implement WaitLatch() */
30/* The positions of the latch and PM death events in LatchWaitSet */
31 #define LatchWaitSetLatchPos 0
32 #define LatchWaitSetPostmasterDeathPos 1
41 /* Set up the WaitEventSet used by WaitLatch(). */
48 * WaitLatch will modify this to WL_EXIT_ON_PM_DEATH or
49 * WL_POSTMASTER_DEATH on each call.
60 * Initialize a process-local latch.
71 latch->event = CreateEvent(NULL, TRUE, FALSE, NULL);
72 if (latch->event == NULL)
73 elog(
ERROR,
"CreateEvent failed: error code %lu", GetLastError());
78 * Initialize a shared latch that can be set from other processes. The latch
79 * is initially owned by no-one; use OwnLatch to associate it with the
82 * InitSharedLatch needs to be called in postmaster before forking child
83 * processes, usually right after allocating the shared memory block
84 * containing the latch with ShmemInitStruct. (The Unix implementation
85 * doesn't actually require that, but the Windows one does.) Because of
86 * this restriction, we have no concurrency issues to worry about here.
88 * Note that other handles created in this module are never marked as
89 * inheritable. Thus we do not need to worry about cleaning up child
90 * process references to postmaster-private latches or WaitEventSets.
96 SECURITY_ATTRIBUTES
sa;
99 * Set up security attributes to specify that the events are inherited.
101 ZeroMemory(&
sa,
sizeof(
sa));
102 sa.nLength =
sizeof(
sa);
103 sa.bInheritHandle = TRUE;
105 latch->event = CreateEvent(&
sa, TRUE, FALSE, NULL);
106 if (latch->event == NULL)
107 elog(
ERROR,
"CreateEvent failed: error code %lu", GetLastError());
117 * Associate a shared latch with the current process, allowing it to
120 * Although there is a sanity check for latch-already-owned, we don't do
121 * any sort of locking here, meaning that we could fail to detect the error
122 * if two processes try to own the same latch at about the same time. If
123 * there is any risk of that, caller must provide an interlock to prevent it.
135 elog(
PANIC,
"latch already owned by PID %d", owner_pid);
141 * Disown a shared latch currently owned by the current process.
153 * Wait for a given latch to be set, or for postmaster death, or until timeout
154 * is exceeded. 'wakeEvents' is a bitmask that specifies which of those events
155 * to wait for. If the latch is already set (and WL_LATCH_SET is given), the
156 * function returns immediately.
158 * The "timeout" is given in milliseconds. It must be >= 0 if WL_TIMEOUT flag
159 * is given. Although it is declared as "long", we don't actually support
160 * timeouts longer than INT_MAX milliseconds. Note that some extra overhead
161 * is incurred when WL_TIMEOUT is given, so avoid using a timeout if possible.
163 * The latch must be owned by the current process, ie. it must be a
164 * process-local latch initialized with InitLatch, or a shared latch
165 * associated with the current process by calling OwnLatch.
167 * Returns bit mask indicating which condition(s) caused the wake-up. Note
168 * that if multiple wake-up conditions are true, there is no guarantee that
169 * we return all of them in one call, but we will return at least one.
177 /* Postmaster-managed callers must handle postmaster death somehow. */
183 * Some callers may have a latch other than MyLatch, or no latch at all,
184 * or want to handle postmaster death differently. It's cheap to assign
185 * those, so just do it every time.
199 wait_event_info) == 0)
206 * Like WaitLatch, but with an extra socket argument for WL_SOCKET_*
209 * When waiting on a socket, EOF and error conditions always cause the socket
210 * to be reported as readable/writable/connected, so that the caller can deal
211 * with the condition.
213 * wakeEvents must include either WL_EXIT_ON_PM_DEATH for automatic exit
214 * if the postmaster dies or WL_POSTMASTER_DEATH for a flag set in the
215 * return value if the postmaster dies. The latter is useful for rare cases
216 * where some behavior other than immediate exit is needed.
218 * NB: These days this is just a wrapper around the WaitEventSet API. When
219 * using a latch very frequently, consider creating a longer living
220 * WaitEventSet instead; that's more efficient.
224 long timeout,
uint32 wait_event_info)
240 /* Postmaster-managed callers must handle postmaster death somehow. */
278 * Sets a latch and wakes up anyone waiting on it.
280 * This is cheap if the latch is already set, otherwise not so much.
282 * NB: when calling this in a signal handler, be sure to save and restore
283 * errno around it. (That's standard practice in most signal handlers, of
284 * course, but we used to omit it in handlers that only set a flag.)
286 * NB: this function is called from critical sections and signal handlers so
287 * throwing an error is not a good idea.
299 * The memory barrier has to be placed here to ensure that any flag
300 * variables possibly changed by this process have been flushed to main
301 * memory, before we check/set is_set.
305 /* Quick exit if already set */
318 * See if anyone's waiting for the latch. It can be the current process if
319 * we're in a signal handler. We use the self-pipe or SIGURG to ourselves
320 * to wake up WaitEventSetWaitBlock() without races in that case. If it's
321 * another process, send a signal.
323 * Fetch owner_pid only once, in case the latch is concurrently getting
324 * owned or disowned. XXX: This assumes that pid_t is atomic, which isn't
325 * guaranteed to be true! In practice, the effective range of pid_t fits
326 * in a 32 bit integer, and so should be atomic. In the worst case, we
327 * might end up signaling the wrong process. Even then, you're very
328 * unlucky if a process with that bogus pid exists and belongs to
329 * Postgres; and PG database processes should handle excess SIGUSR1
330 * interrupts without a problem anyhow.
332 * Another sort of race condition that's possible here is for a new
333 * process to own the latch immediately after we look, so we don't signal
334 * it. This is okay so long as all callers of ResetLatch/WaitLatch follow
335 * the standard coding convention of waiting at the bottom of their loops,
336 * not the top, so that they'll correctly process latch-setting events
337 * that happen before they enter the loop.
350 * See if anyone's waiting for the latch. It can be the current process if
351 * we're in a signal handler.
353 * Use a local variable here just in case somebody changes the event field
354 * concurrently (which really should not happen).
356 handle = latch->event;
362 * Note that we silently ignore any errors. We might be in a signal
363 * handler or other critical path where it's not safe to call elog().
370 * Clear the latch. Calling WaitLatch after this will sleep, unless
371 * the latch is set again before the WaitLatch call.
376 /* Only the owner should reset the latch */
383 * Ensure that the write to is_set gets flushed to main memory before we
384 * examine any flag variables. Otherwise a concurrent SetLatch might
385 * falsely conclude that it needn't signal us, even though we have missed
386 * seeing some flag updates that SetLatch was supposed to inform us of.
#define pg_memory_barrier()
#define PG_USED_FOR_ASSERTS_ONLY
Assert(PointerIsAligned(start, uint64))
void InitializeLatchWaitSet(void)
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
#define LatchWaitSetLatchPos
void OwnLatch(Latch *latch)
void DisownLatch(Latch *latch)
void InitSharedLatch(Latch *latch)
static WaitEventSet * LatchWaitSet
void SetLatch(Latch *latch)
void InitLatch(Latch *latch)
#define LatchWaitSetPostmasterDeathPos
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
ResourceOwner CurrentResourceOwner
sig_atomic_t maybe_sleeping
void WakeupOtherProc(int pid)
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
void FreeWaitEventSet(WaitEventSet *set)
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
#define WL_EXIT_ON_PM_DEATH
#define WL_POSTMASTER_DEATH