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 42854 : 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 42854 : LatchWaitSet = CreateWaitEventSet(NULL, 2);
43 42854 : 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 42854 : if (IsUnderPostmaster)
52 : {
53 42422 : latch_pos = AddWaitEventToSet(LatchWaitSet, WL_EXIT_ON_PM_DEATH,
54 : PGINVALID_SOCKET, NULL, NULL);
55 : Assert(latch_pos == LatchWaitSetPostmasterDeathPos);
56 : }
57 42854 : }
58 :
59 : /*
60 : * Initialize a process-local latch.
61 : */
62 : void
63 44520 : InitLatch(Latch *latch)
64 : {
65 44520 : latch->is_set = false;
66 44520 : latch->maybe_sleeping = false;
67 44520 : latch->owner_pid = MyProcPid;
68 44520 : 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 44520 : }
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 268484 : 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 268484 : latch->is_set = false;
111 268484 : latch->maybe_sleeping = false;
112 268484 : latch->owner_pid = 0;
113 268484 : latch->is_shared = true;
114 268484 : }
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 42492 : OwnLatch(Latch *latch)
127 : {
128 : int owner_pid;
129 :
130 : /* Sanity checks */
131 : Assert(latch->is_shared);
132 :
133 42492 : owner_pid = latch->owner_pid;
134 42492 : if (owner_pid != 0)
135 0 : elog(PANIC, "latch already owned by PID %d", owner_pid);
136 :
137 42492 : latch->owner_pid = MyProcPid;
138 42492 : }
139 :
140 : /*
141 : * Disown a shared latch currently owned by the current process.
142 : */
143 : void
144 42378 : DisownLatch(Latch *latch)
145 : {
146 : Assert(latch->is_shared);
147 : Assert(latch->owner_pid == MyProcPid);
148 :
149 42378 : latch->owner_pid = 0;
150 42378 : }
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 2079436 : 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 2079436 : if (!(wakeEvents & WL_LATCH_SET))
188 112 : latch = NULL;
189 2079436 : ModifyWaitEvent(LatchWaitSet, LatchWaitSetLatchPos, WL_LATCH_SET, latch);
190 2079436 : ModifyWaitEvent(LatchWaitSet, LatchWaitSetPostmasterDeathPos,
191 2079436 : (wakeEvents & (WL_EXIT_ON_PM_DEATH | WL_POSTMASTER_DEATH)),
192 : NULL);
193 :
194 2079436 : if (WaitEventSetWait(LatchWaitSet,
195 2079436 : (wakeEvents & WL_TIMEOUT) ? timeout : -1,
196 : &event, 1,
197 : wait_event_info) == 0)
198 45308 : return WL_TIMEOUT;
199 : else
200 2034076 : 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 : */
220 : int
221 121022 : WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock,
222 : long timeout, uint32 wait_event_info)
223 : {
224 121022 : int ret = 0;
225 : int rc;
226 : WaitEvent event;
227 121022 : WaitEventSet *set = CreateWaitEventSet(CurrentResourceOwner, 3);
228 :
229 121022 : if (wakeEvents & WL_TIMEOUT)
230 : Assert(timeout >= 0);
231 : else
232 28350 : timeout = -1;
233 :
234 121022 : if (wakeEvents & WL_LATCH_SET)
235 120750 : AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
236 : latch, NULL);
237 :
238 : /* Postmaster-managed callers must handle postmaster death somehow. */
239 : Assert(!IsUnderPostmaster ||
240 : (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
241 : (wakeEvents & WL_POSTMASTER_DEATH));
242 :
243 121022 : if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
244 0 : AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
245 : NULL, NULL);
246 :
247 121022 : if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
248 121022 : AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
249 : NULL, NULL);
250 :
251 121022 : if (wakeEvents & WL_SOCKET_MASK)
252 : {
253 : int ev;
254 :
255 121022 : ev = wakeEvents & WL_SOCKET_MASK;
256 121022 : AddWaitEventToSet(set, ev, sock, NULL, NULL);
257 : }
258 :
259 121022 : rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
260 :
261 121022 : if (rc == 0)
262 624 : ret |= WL_TIMEOUT;
263 : else
264 : {
265 120398 : ret |= event.events & (WL_LATCH_SET |
266 : WL_POSTMASTER_DEATH |
267 : WL_SOCKET_MASK);
268 : }
269 :
270 121022 : FreeWaitEventSet(set);
271 :
272 121022 : 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 : */
287 : void
288 2889482 : SetLatch(Latch *latch)
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 : */
301 2889482 : pg_memory_barrier();
302 :
303 : /* Quick exit if already set */
304 2889482 : if (latch->is_set)
305 326838 : return;
306 :
307 2562644 : latch->is_set = true;
308 :
309 2562644 : pg_memory_barrier();
310 2562644 : if (!latch->maybe_sleeping)
311 185560 : 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 2377084 : owner_pid = latch->owner_pid;
338 2377084 : if (owner_pid == 0)
339 0 : return;
340 2377084 : else if (owner_pid == MyProcPid)
341 239842 : WakeupMyProc();
342 : else
343 2137242 : 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 : */
371 : void
372 4343478 : ResetLatch(Latch *latch)
373 : {
374 : /* Only the owner should reset the latch */
375 : Assert(latch->owner_pid == MyProcPid);
376 : Assert(latch->maybe_sleeping == false);
377 :
378 4343478 : 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 : */
386 4343478 : pg_memory_barrier();
387 4343478 : }
|