PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
latch.c File Reference
#include "postgres.h"
#include "miscadmin.h"
#include "port/atomics.h"
#include "storage/latch.h"
#include "storage/waiteventset.h"
#include "utils/resowner.h"
Include dependency graph for latch.c:

Go to the source code of this file.

Macros

#define LatchWaitSetLatchPos   0
 
#define LatchWaitSetPostmasterDeathPos   1
 

Functions

void InitializeLatchWaitSet (void)
 
void InitLatch (Latch *latch)
 
void InitSharedLatch (Latch *latch)
 
void OwnLatch (Latch *latch)
 
void DisownLatch (Latch *latch)
 
int WaitLatch (Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
 
int WaitLatchOrSocket (Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
 
void SetLatch (Latch *latch)
 
void ResetLatch (Latch *latch)
 

Variables

static WaitEventSetLatchWaitSet
 

Macro Definition Documentation

◆ LatchWaitSetLatchPos

#define LatchWaitSetLatchPos   0

Definition at line 31 of file latch.c.

◆ LatchWaitSetPostmasterDeathPos

#define LatchWaitSetPostmasterDeathPos   1

Definition at line 32 of file latch.c.

Function Documentation

◆ DisownLatch()

void DisownLatch ( Latch latch)

Definition at line 144 of file latch.c.

145{
146 Assert(latch->is_shared);
147 Assert(latch->owner_pid == MyProcPid);
148
149 latch->owner_pid = 0;
150}
int MyProcPid
Definition: globals.c:48
Assert(PointerIsAligned(start, uint64))
bool is_shared
Definition: latch.h:117
int owner_pid
Definition: latch.h:118

References Assert(), Latch::is_shared, MyProcPid, and Latch::owner_pid.

Referenced by AuxiliaryProcKill(), ProcKill(), and ShutdownWalRecovery().

◆ InitializeLatchWaitSet()

void InitializeLatchWaitSet ( void  )

Definition at line 35 of file latch.c.

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}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
bool IsUnderPostmaster
Definition: globals.c:121
struct Latch * MyLatch
Definition: globals.c:64
#define LatchWaitSetLatchPos
Definition: latch.c:31
static WaitEventSet * LatchWaitSet
Definition: latch.c:28
#define LatchWaitSetPostmasterDeathPos
Definition: latch.c:32
#define PGINVALID_SOCKET
Definition: port.h:31
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
Definition: waiteventset.c:569
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
Definition: waiteventset.c:363
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define WL_LATCH_SET
Definition: waiteventset.h:34

References AddWaitEventToSet(), Assert(), CreateWaitEventSet(), IsUnderPostmaster, LatchWaitSet, LatchWaitSetLatchPos, LatchWaitSetPostmasterDeathPos, MyLatch, PG_USED_FOR_ASSERTS_ONLY, PGINVALID_SOCKET, WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by InitPostmasterChild(), and InitStandaloneProcess().

◆ InitLatch()

void InitLatch ( Latch latch)

Definition at line 63 of file latch.c.

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}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
sig_atomic_t is_set
Definition: latch.h:115
sig_atomic_t maybe_sleeping
Definition: latch.h:116

References elog, ERROR, Latch::is_set, Latch::is_shared, Latch::maybe_sleeping, MyProcPid, and Latch::owner_pid.

Referenced by InitProcessLocalLatch().

◆ InitSharedLatch()

void InitSharedLatch ( Latch latch)

Definition at line 93 of file latch.c.

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}

References elog, ERROR, Latch::is_set, Latch::is_shared, Latch::maybe_sleeping, and Latch::owner_pid.

Referenced by InitProcGlobal(), and XLogRecoveryShmemInit().

◆ OwnLatch()

void OwnLatch ( Latch latch)

Definition at line 126 of file latch.c.

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}
#define PANIC
Definition: elog.h:42

References Assert(), elog, Latch::is_shared, MyProcPid, Latch::owner_pid, and PANIC.

Referenced by InitAuxiliaryProcess(), InitProcess(), and InitWalRecovery().

◆ ResetLatch()

void ResetLatch ( Latch latch)

Definition at line 372 of file latch.c.

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

References Assert(), Latch::is_set, Latch::maybe_sleeping, MyProcPid, Latch::owner_pid, and pg_memory_barrier.

Referenced by ApplyLauncherMain(), autoprewarm_main(), AutoVacLauncherMain(), BackgroundWriterMain(), CheckpointerMain(), CheckpointWriteDelay(), ConditionVariableTimedSleep(), copy_read_data(), do_pg_backup_stop(), ExecAppendAsyncEventWait(), gather_readnext(), IoWorkerMain(), lazy_truncate_heap(), libpqsrv_cancel(), libpqsrv_connect_internal(), libpqsrv_get_result(), LogicalParallelApplyLoop(), logicalrep_worker_stop_internal(), LogicalRepApplyLoop(), mq_putmessage(), pa_send_data(), pa_wait_for_xact_state(), pg_promote(), pg_sleep(), pg_wait_until_termination(), pgarch_MainLoop(), pgfdw_get_cleanup_result(), pq_check_connection(), ProcessPendingWrites(), ProcSleep(), ProcWaitForSignal(), recoveryApplyDelay(), secure_read(), secure_write(), ServerLoop(), shm_mq_receive_bytes(), shm_mq_send_bytes(), shm_mq_wait_internal(), ShutDownSlotSync(), summarizer_wait_for_wal(), SyncRepWaitForLSN(), SysLoggerMain(), test_shm_mq_pipelined(), throttle(), wait_for_relation_state_change(), wait_for_slot_activity(), wait_for_worker_state_change(), wait_for_workers_to_become_ready(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), WaitForReplicationWorkerAttach(), WaitForWALToBecomeAvailable(), WalRcvWaitForStartPosition(), WalReceiverMain(), WalSndLoop(), WalSndWaitForWal(), WalWriterMain(), and worker_spi_main().

◆ SetLatch()

void SetLatch ( Latch latch)

Definition at line 288 of file latch.c.

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}
void WakeupMyProc(void)
void WakeupOtherProc(int pid)

References Latch::is_set, Latch::maybe_sleeping, MyProcPid, Latch::owner_pid, pg_memory_barrier, WakeupMyProc(), and WakeupOtherProc().

Referenced by avl_sigusr2_handler(), CheckDeadLockAlert(), ClientCheckTimeoutHandler(), ConditionVariableBroadcast(), ConditionVariableSignal(), die(), ForwardSyncRequest(), handle_pm_child_exit_signal(), handle_pm_pmsignal_signal(), handle_pm_reload_request_signal(), handle_pm_shutdown_request_signal(), handle_sig_alarm(), HandleCatchupInterrupt(), HandleNotifyInterrupt(), HandleParallelApplyMessageInterrupt(), HandleParallelMessageInterrupt(), IdleInTransactionSessionTimeoutHandler(), IdleSessionTimeoutHandler(), IdleStatsUpdateTimeoutHandler(), IoWorkerMain(), logicalrep_worker_wakeup_ptr(), pgaio_worker_submit_internal(), pgarch_waken_stop(), PgArchWakeup(), ProcessClientReadInterrupt(), ProcessClientWriteInterrupt(), ProcessPendingWrites(), ProcSendSignal(), procsignal_sigusr1_handler(), ProcWakeup(), ReqShutdownXLOG(), RequestCheckpoint(), RequestXLogStreaming(), shm_mq_detach_internal(), shm_mq_inc_bytes_read(), shm_mq_send_bytes(), shm_mq_sendv(), shm_mq_set_receiver(), shm_mq_set_sender(), SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), sigUsr1Handler(), StatementCancelHandler(), StrategyGetBuffer(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepWakeQueue(), test_shm_mq_main(), TransactionTimeoutHandler(), WakeupRecovery(), WakeupWalSummarizer(), WalRcvForceReply(), WalSndLastCycleHandler(), WalSndWaitForWal(), and XLogSetAsyncXactLSN().

◆ WaitLatch()

int WaitLatch ( Latch latch,
int  wakeEvents,
long  timeout,
uint32  wait_event_info 
)

Definition at line 172 of file latch.c.

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}
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: waiteventset.c:655
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_POSTMASTER_DEATH
Definition: waiteventset.h:38

References Assert(), IsUnderPostmaster, LatchWaitSet, LatchWaitSetLatchPos, LatchWaitSetPostmasterDeathPos, ModifyWaitEvent(), WaitEventSetWait(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by ApplyLauncherMain(), autoprewarm_main(), AutoVacLauncherMain(), BackgroundWriterMain(), CheckpointerMain(), CheckpointWriteDelay(), ConditionVariableTimedSleep(), do_pg_backup_stop(), gather_readnext(), IoWorkerMain(), lazy_truncate_heap(), LogicalParallelApplyLoop(), logicalrep_worker_stop_internal(), mq_putmessage(), pa_send_data(), pa_wait_for_xact_state(), pg_promote(), pg_sleep(), pg_wait_until_termination(), pgarch_MainLoop(), ProcSleep(), ProcWaitForSignal(), recoveryApplyDelay(), RegisterSyncRequest(), shm_mq_receive_bytes(), shm_mq_send_bytes(), shm_mq_wait_internal(), ShutDownSlotSync(), summarizer_wait_for_wal(), SyncRepWaitForLSN(), test_shm_mq_pipelined(), throttle(), wait_for_relation_state_change(), wait_for_slot_activity(), wait_for_worker_state_change(), wait_for_workers_to_become_ready(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), WaitForReplicationWorkerAttach(), WaitForWALToBecomeAvailable(), WalRcvWaitForStartPosition(), WalSummarizerMain(), WalWriterMain(), and worker_spi_main().

◆ WaitLatchOrSocket()

int WaitLatchOrSocket ( Latch latch,
int  wakeEvents,
pgsocket  sock,
long  timeout,
uint32  wait_event_info 
)

Definition at line 221 of file latch.c.

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}
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
void FreeWaitEventSet(WaitEventSet *set)
Definition: waiteventset.c:480
#define WL_SOCKET_MASK
Definition: waiteventset.h:53

References AddWaitEventToSet(), Assert(), CreateWaitEventSet(), CurrentResourceOwner, FreeWaitEventSet(), IsUnderPostmaster, PGINVALID_SOCKET, WaitEventSetWait(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, WL_SOCKET_MASK, and WL_TIMEOUT.

Referenced by be_tls_open_server(), copy_read_data(), libpqsrv_cancel(), libpqsrv_connect_internal(), libpqsrv_get_result(), LogicalRepApplyLoop(), pgfdw_get_cleanup_result(), read_or_wait(), secure_open_gssapi(), and WalReceiverMain().

Variable Documentation

◆ LatchWaitSet

WaitEventSet* LatchWaitSet
static

Definition at line 28 of file latch.c.

Referenced by InitializeLatchWaitSet(), and WaitLatch().