Line data Source code
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"
24 : #include "storage/waiteventset.h"
25 : #include "utils/resowner.h"
26 :
27 : /* A common WaitEventSet used to implement WaitLatch() */
28 : static WaitEventSet *LatchWaitSet;
29 :
30 : /* The positions of the latch and PM death events in LatchWaitSet */
31 : #define LatchWaitSetLatchPos 0
32 : #define LatchWaitSetPostmasterDeathPos 1
33 :
34 : void
35 43658 : InitializeLatchWaitSet(void)
36 : {
37 : int latch_pos PG_USED_FOR_ASSERTS_ONLY;
38 :
39 : Assert(LatchWaitSet == NULL);
40 :
41 : /* Set up the WaitEventSet used by WaitLatch(). */
42 43658 : LatchWaitSet = CreateWaitEventSet(NULL, 2);
43 43658 : latch_pos = AddWaitEventToSet(LatchWaitSet, WL_LATCH_SET, PGINVALID_SOCKET,
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 : */
51 43658 : if (IsUnderPostmaster)
52 : {
53 43178 : latch_pos = AddWaitEventToSet(LatchWaitSet, WL_EXIT_ON_PM_DEATH,
54 : PGINVALID_SOCKET, NULL, NULL);
55 : Assert(latch_pos == LatchWaitSetPostmasterDeathPos);
56 : }
57 43658 : }
58 :
59 : /*
60 : * Initialize a process-local latch.
61 : */
62 : void
63 45406 : InitLatch(Latch *latch)
64 : {
65 45406 : latch->is_set = false;
66 45406 : latch->maybe_sleeping = false;
67 45406 : latch->owner_pid = MyProcPid;
68 45406 : 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 45406 : }
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 : */
92 : void
93 284174 : InitSharedLatch(Latch *latch)
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 284174 : latch->is_set = false;
111 284174 : latch->maybe_sleeping = false;
112 284174 : latch->owner_pid = 0;
113 284174 : latch->is_shared = true;
114 284174 : }
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 : */
125 : void
126 42802 : OwnLatch(Latch *latch)
127 : {
128 : int owner_pid;
129 :
130 : /* Sanity checks */
131 : Assert(latch->is_shared);
132 :
133 42802 : owner_pid = latch->owner_pid;
134 42802 : if (owner_pid != 0)
135 0 : elog(PANIC, "latch already owned by PID %d", owner_pid);
136 :
137 42802 : latch->owner_pid = MyProcPid;
138 42802 : }
139 :
140 : /*
141 : * Disown a shared latch currently owned by the current process.
142 : */
143 : void
144 42682 : DisownLatch(Latch *latch)
145 : {
146 : Assert(latch->is_shared);
147 : Assert(latch->owner_pid == MyProcPid);
148 :
149 42682 : latch->owner_pid = 0;
150 42682 : }
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 : */
171 : int
172 2028572 : WaitLatch(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. */
178 : Assert(!IsUnderPostmaster ||
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 2028572 : if (!(wakeEvents & WL_LATCH_SET))
188 340 : latch = NULL;
189 2028572 : ModifyWaitEvent(LatchWaitSet, LatchWaitSetLatchPos, WL_LATCH_SET, latch);
190 :
191 2028572 : if (IsUnderPostmaster)
192 2028572 : ModifyWaitEvent(LatchWaitSet, LatchWaitSetPostmasterDeathPos,
193 2028572 : (wakeEvents & (WL_EXIT_ON_PM_DEATH | WL_POSTMASTER_DEATH)),
194 : NULL);
195 :
196 2028572 : if (WaitEventSetWait(LatchWaitSet,
197 2028572 : (wakeEvents & WL_TIMEOUT) ? timeout : -1,
198 : &event, 1,
199 : wait_event_info) == 0)
200 65878 : return WL_TIMEOUT;
201 : else
202 1962636 : return event.events;
203 : }
204 :
205 : /*
206 : * Like WaitLatch, but with an extra socket argument for WL_SOCKET_*
207 : * conditions.
208 : *
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.
212 : *
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.
217 : *
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.
221 : */
222 : int
223 232582 : WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock,
224 : long timeout, uint32 wait_event_info)
225 : {
226 232582 : int ret = 0;
227 : int rc;
228 : WaitEvent event;
229 232582 : WaitEventSet *set = CreateWaitEventSet(CurrentResourceOwner, 3);
230 :
231 232582 : if (wakeEvents & WL_TIMEOUT)
232 : Assert(timeout >= 0);
233 : else
234 29294 : timeout = -1;
235 :
236 232582 : if (wakeEvents & WL_LATCH_SET)
237 232344 : AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
238 : latch, NULL);
239 :
240 : /* Postmaster-managed callers must handle postmaster death somehow. */
241 : Assert(!IsUnderPostmaster ||
242 : (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
243 : (wakeEvents & WL_POSTMASTER_DEATH));
244 :
245 232582 : if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
246 0 : AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
247 : NULL, NULL);
248 :
249 232582 : if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
250 232582 : AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
251 : NULL, NULL);
252 :
253 232582 : if (wakeEvents & WL_SOCKET_MASK)
254 : {
255 : int ev;
256 :
257 232582 : ev = wakeEvents & WL_SOCKET_MASK;
258 232582 : AddWaitEventToSet(set, ev, sock, NULL, NULL);
259 : }
260 :
261 232582 : rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
262 :
263 232582 : if (rc == 0)
264 552 : ret |= WL_TIMEOUT;
265 : else
266 : {
267 232030 : ret |= event.events & (WL_LATCH_SET |
268 : WL_POSTMASTER_DEATH |
269 : WL_SOCKET_MASK);
270 : }
271 :
272 232582 : FreeWaitEventSet(set);
273 :
274 232582 : return ret;
275 : }
276 :
277 : /*
278 : * Sets a latch and wakes up anyone waiting on it.
279 : *
280 : * This is cheap if the latch is already set, otherwise not so much.
281 : *
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.)
285 : *
286 : * NB: this function is called from critical sections and signal handlers so
287 : * throwing an error is not a good idea.
288 : */
289 : void
290 2917804 : SetLatch(Latch *latch)
291 : {
292 : #ifndef WIN32
293 : pid_t owner_pid;
294 : #else
295 : HANDLE handle;
296 : #endif
297 :
298 : /*
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.
302 : */
303 2917804 : pg_memory_barrier();
304 :
305 : /* Quick exit if already set */
306 2917804 : if (latch->is_set)
307 374286 : return;
308 :
309 2543518 : latch->is_set = true;
310 :
311 2543518 : pg_memory_barrier();
312 2543518 : if (!latch->maybe_sleeping)
313 147656 : return;
314 :
315 : #ifndef WIN32
316 :
317 : /*
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.
322 : *
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.
331 : *
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.
338 : */
339 2395862 : owner_pid = latch->owner_pid;
340 2395862 : if (owner_pid == 0)
341 0 : return;
342 2395862 : else if (owner_pid == MyProcPid)
343 272202 : WakeupMyProc();
344 : else
345 2123660 : WakeupOtherProc(owner_pid);
346 :
347 : #else
348 :
349 : /*
350 : * See if anyone's waiting for the latch. It can be the current process if
351 : * we're in a signal handler.
352 : *
353 : * Use a local variable here just in case somebody changes the event field
354 : * concurrently (which really should not happen).
355 : */
356 : handle = latch->event;
357 : if (handle)
358 : {
359 : SetEvent(handle);
360 :
361 : /*
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().
364 : */
365 : }
366 : #endif
367 : }
368 :
369 : /*
370 : * Clear the latch. Calling WaitLatch after this will sleep, unless
371 : * the latch is set again before the WaitLatch call.
372 : */
373 : void
374 3794878 : ResetLatch(Latch *latch)
375 : {
376 : /* Only the owner should reset the latch */
377 : Assert(latch->owner_pid == MyProcPid);
378 : Assert(latch->maybe_sleeping == false);
379 :
380 3794878 : latch->is_set = false;
381 :
382 : /*
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.
387 : */
388 3794878 : pg_memory_barrier();
389 3794878 : }
|