PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
latch.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * latch.c
4 * Routines for inter-process latches
5 *
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
9 * on how to use them.
10 *
11 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
13 *
14 * IDENTIFICATION
15 * src/backend/storage/ipc/latch.c
16 *
17 *-------------------------------------------------------------------------
18 */
19#include "postgres.h"
20
21#include "miscadmin.h"
22#include "port/atomics.h"
23#include "storage/latch.h"
25#include "utils/resowner.h"
26
27/* A common WaitEventSet used to implement WaitLatch() */
29
30/* The positions of the latch and PM death events in LatchWaitSet */
31#define LatchWaitSetLatchPos 0
32#define LatchWaitSetPostmasterDeathPos 1
33
34void
36{
37 int latch_pos PG_USED_FOR_ASSERTS_ONLY;
38
39 Assert(LatchWaitSet == NULL);
40
41 /* Set up the WaitEventSet used by WaitLatch(). */
44 MyLatch, NULL);
45 Assert(latch_pos == LatchWaitSetLatchPos);
46
47 /*
48 * WaitLatch will modify this to WL_EXIT_ON_PM_DEATH or
49 * WL_POSTMASTER_DEATH on each call.
50 */
52 {
54 PGINVALID_SOCKET, NULL, NULL);
56 }
57}
58
59/*
60 * Initialize a process-local latch.
61 */
62void
64{
65 latch->is_set = false;
66 latch->maybe_sleeping = false;
67 latch->owner_pid = MyProcPid;
68 latch->is_shared = false;
69
70#ifdef WIN32
71 latch->event = CreateEvent(NULL, TRUE, FALSE, NULL);
72 if (latch->event == NULL)
73 elog(ERROR, "CreateEvent failed: error code %lu", GetLastError());
74#endif /* WIN32 */
75}
76
77/*
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
80 * current process.
81 *
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.
87 *
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.
91 */
92void
94{
95#ifdef WIN32
96 SECURITY_ATTRIBUTES sa;
97
98 /*
99 * Set up security attributes to specify that the events are inherited.
100 */
101 ZeroMemory(&sa, sizeof(sa));
102 sa.nLength = sizeof(sa);
103 sa.bInheritHandle = TRUE;
104
105 latch->event = CreateEvent(&sa, TRUE, FALSE, NULL);
106 if (latch->event == NULL)
107 elog(ERROR, "CreateEvent failed: error code %lu", GetLastError());
108#endif
109
110 latch->is_set = false;
111 latch->maybe_sleeping = false;
112 latch->owner_pid = 0;
113 latch->is_shared = true;
114}
115
116/*
117 * Associate a shared latch with the current process, allowing it to
118 * wait on the latch.
119 *
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.
124 */
125void
127{
128 int owner_pid;
129
130 /* Sanity checks */
131 Assert(latch->is_shared);
132
133 owner_pid = latch->owner_pid;
134 if (owner_pid != 0)
135 elog(PANIC, "latch already owned by PID %d", owner_pid);
136
137 latch->owner_pid = MyProcPid;
138}
139
140/*
141 * Disown a shared latch currently owned by the current process.
142 */
143void
145{
146 Assert(latch->is_shared);
147 Assert(latch->owner_pid == MyProcPid);
148
149 latch->owner_pid = 0;
150}
151
152/*
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.
157 *
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.
162 *
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.
166 *
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.
170 */
171int
172WaitLatch(Latch *latch, int wakeEvents, long timeout,
173 uint32 wait_event_info)
174{
175 WaitEvent event;
176
177 /* Postmaster-managed callers must handle postmaster death somehow. */
179 (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
180 (wakeEvents & WL_POSTMASTER_DEATH));
181
182 /*
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.
186 */
187 if (!(wakeEvents & WL_LATCH_SET))
188 latch = NULL;
191 (wakeEvents & (WL_EXIT_ON_PM_DEATH | WL_POSTMASTER_DEATH)),
192 NULL);
193
195 (wakeEvents & WL_TIMEOUT) ? timeout : -1,
196 &event, 1,
197 wait_event_info) == 0)
198 return WL_TIMEOUT;
199 else
200 return event.events;
201}
202
203/*
204 * Like WaitLatch, but with an extra socket argument for WL_SOCKET_*
205 * conditions.
206 *
207 * When waiting on a socket, EOF and error conditions always cause the socket
208 * to be reported as readable/writable/connected, so that the caller can deal
209 * with the condition.
210 *
211 * wakeEvents must include either WL_EXIT_ON_PM_DEATH for automatic exit
212 * if the postmaster dies or WL_POSTMASTER_DEATH for a flag set in the
213 * return value if the postmaster dies. The latter is useful for rare cases
214 * where some behavior other than immediate exit is needed.
215 *
216 * NB: These days this is just a wrapper around the WaitEventSet API. When
217 * using a latch very frequently, consider creating a longer living
218 * WaitEventSet instead; that's more efficient.
219 */
220int
221WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock,
222 long timeout, uint32 wait_event_info)
223{
224 int ret = 0;
225 int rc;
226 WaitEvent event;
228
229 if (wakeEvents & WL_TIMEOUT)
230 Assert(timeout >= 0);
231 else
232 timeout = -1;
233
234 if (wakeEvents & WL_LATCH_SET)
236 latch, NULL);
237
238 /* Postmaster-managed callers must handle postmaster death somehow. */
240 (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
241 (wakeEvents & WL_POSTMASTER_DEATH));
242
243 if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
245 NULL, NULL);
246
247 if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
249 NULL, NULL);
250
251 if (wakeEvents & WL_SOCKET_MASK)
252 {
253 int ev;
254
255 ev = wakeEvents & WL_SOCKET_MASK;
256 AddWaitEventToSet(set, ev, sock, NULL, NULL);
257 }
258
259 rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
260
261 if (rc == 0)
262 ret |= WL_TIMEOUT;
263 else
264 {
265 ret |= event.events & (WL_LATCH_SET |
268 }
269
270 FreeWaitEventSet(set);
271
272 return ret;
273}
274
275/*
276 * Sets a latch and wakes up anyone waiting on it.
277 *
278 * This is cheap if the latch is already set, otherwise not so much.
279 *
280 * NB: when calling this in a signal handler, be sure to save and restore
281 * errno around it. (That's standard practice in most signal handlers, of
282 * course, but we used to omit it in handlers that only set a flag.)
283 *
284 * NB: this function is called from critical sections and signal handlers so
285 * throwing an error is not a good idea.
286 */
287void
289{
290#ifndef WIN32
291 pid_t owner_pid;
292#else
293 HANDLE handle;
294#endif
295
296 /*
297 * The memory barrier has to be placed here to ensure that any flag
298 * variables possibly changed by this process have been flushed to main
299 * memory, before we check/set is_set.
300 */
302
303 /* Quick exit if already set */
304 if (latch->is_set)
305 return;
306
307 latch->is_set = true;
308
310 if (!latch->maybe_sleeping)
311 return;
312
313#ifndef WIN32
314
315 /*
316 * See if anyone's waiting for the latch. It can be the current process if
317 * we're in a signal handler. We use the self-pipe or SIGURG to ourselves
318 * to wake up WaitEventSetWaitBlock() without races in that case. If it's
319 * another process, send a signal.
320 *
321 * Fetch owner_pid only once, in case the latch is concurrently getting
322 * owned or disowned. XXX: This assumes that pid_t is atomic, which isn't
323 * guaranteed to be true! In practice, the effective range of pid_t fits
324 * in a 32 bit integer, and so should be atomic. In the worst case, we
325 * might end up signaling the wrong process. Even then, you're very
326 * unlucky if a process with that bogus pid exists and belongs to
327 * Postgres; and PG database processes should handle excess SIGUSR1
328 * interrupts without a problem anyhow.
329 *
330 * Another sort of race condition that's possible here is for a new
331 * process to own the latch immediately after we look, so we don't signal
332 * it. This is okay so long as all callers of ResetLatch/WaitLatch follow
333 * the standard coding convention of waiting at the bottom of their loops,
334 * not the top, so that they'll correctly process latch-setting events
335 * that happen before they enter the loop.
336 */
337 owner_pid = latch->owner_pid;
338 if (owner_pid == 0)
339 return;
340 else if (owner_pid == MyProcPid)
341 WakeupMyProc();
342 else
343 WakeupOtherProc(owner_pid);
344
345#else
346
347 /*
348 * See if anyone's waiting for the latch. It can be the current process if
349 * we're in a signal handler.
350 *
351 * Use a local variable here just in case somebody changes the event field
352 * concurrently (which really should not happen).
353 */
354 handle = latch->event;
355 if (handle)
356 {
357 SetEvent(handle);
358
359 /*
360 * Note that we silently ignore any errors. We might be in a signal
361 * handler or other critical path where it's not safe to call elog().
362 */
363 }
364#endif
365}
366
367/*
368 * Clear the latch. Calling WaitLatch after this will sleep, unless
369 * the latch is set again before the WaitLatch call.
370 */
371void
373{
374 /* Only the owner should reset the latch */
375 Assert(latch->owner_pid == MyProcPid);
376 Assert(latch->maybe_sleeping == false);
377
378 latch->is_set = false;
379
380 /*
381 * Ensure that the write to is_set gets flushed to main memory before we
382 * examine any flag variables. Otherwise a concurrent SetLatch might
383 * falsely conclude that it needn't signal us, even though we have missed
384 * seeing some flag updates that SetLatch was supposed to inform us of.
385 */
387}
#define pg_memory_barrier()
Definition: atomics.h:143
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
uint32_t uint32
Definition: c.h:502
#define PANIC
Definition: elog.h:42
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
int MyProcPid
Definition: globals.c:48
bool IsUnderPostmaster
Definition: globals.c:121
struct Latch * MyLatch
Definition: globals.c:64
Assert(PointerIsAligned(start, uint64))
void InitializeLatchWaitSet(void)
Definition: latch.c:35
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:221
#define LatchWaitSetLatchPos
Definition: latch.c:31
void OwnLatch(Latch *latch)
Definition: latch.c:126
void DisownLatch(Latch *latch)
Definition: latch.c:144
void InitSharedLatch(Latch *latch)
Definition: latch.c:93
static WaitEventSet * LatchWaitSet
Definition: latch.c:28
void SetLatch(Latch *latch)
Definition: latch.c:288
void InitLatch(Latch *latch)
Definition: latch.c:63
#define LatchWaitSetPostmasterDeathPos
Definition: latch.c:32
void ResetLatch(Latch *latch)
Definition: latch.c:372
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
int pgsocket
Definition: port.h:29
#define PGINVALID_SOCKET
Definition: port.h:31
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
Definition: latch.h:114
sig_atomic_t is_set
Definition: latch.h:115
sig_atomic_t maybe_sleeping
Definition: latch.h:116
bool is_shared
Definition: latch.h:117
int owner_pid
Definition: latch.h:118
void WakeupMyProc(void)
void WakeupOtherProc(int pid)
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: waiteventset.c:655
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
Definition: waiteventset.c:569
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
void FreeWaitEventSet(WaitEventSet *set)
Definition: waiteventset.c:480
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
Definition: waiteventset.c:363
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define WL_LATCH_SET
Definition: waiteventset.h:34
#define WL_POSTMASTER_DEATH
Definition: waiteventset.h:38
#define WL_SOCKET_MASK
Definition: waiteventset.h:53