PostgreSQL Source Code git master
Data Structures | Typedefs | Functions
latch.h File Reference
#include <signal.h>
#include "storage/waiteventset.h"
Include dependency graph for latch.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct   Latch
 

Typedefs

typedef struct Latch  Latch
 

Functions

void  InitLatch (Latch *latch)
 
void  InitSharedLatch (Latch *latch)
 
void  OwnLatch (Latch *latch)
 
void  DisownLatch (Latch *latch)
 
void  SetLatch (Latch *latch)
 
void  ResetLatch (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  InitializeLatchWaitSet (void)
 

Typedef Documentation

Latch

typedef struct Latch Latch

Function Documentation

DisownLatch()

void DisownLatch ( Latchlatch )

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:47
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:223
bool IsUnderPostmaster
Definition: globals.c:120
struct Latch * MyLatch
Definition: globals.c:63
#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:570
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
Definition: waiteventset.c:364
#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 ( Latchlatch )

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 ( Latchlatch )

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}
Definition: preproc-init.c:83

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

Referenced by InitProcGlobal(), and XLogRecoveryShmemInit().

OwnLatch()

void OwnLatch ( Latchlatch )

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 ( Latchlatch )

Definition at line 374 of file latch.c.

375{
376 /* Only the owner should reset the latch */
377 Assert(latch->owner_pid == MyProcPid);
378 Assert(latch->maybe_sleeping == false);
379
380 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 */
389}
#define pg_memory_barrier()
Definition: atomics.h:141

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 ( Latchlatch )

Definition at line 290 of file latch.c.

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 */
304
305 /* Quick exit if already set */
306 if (latch->is_set)
307 return;
308
309 latch->is_set = true;
310
312 if (!latch->maybe_sleeping)
313 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 owner_pid = latch->owner_pid;
340 if (owner_pid == 0)
341 return;
342 else if (owner_pid == MyProcPid)
343 WakeupMyProc();
344 else
345 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}
void WakeupMyProc(void)
Definition: waiteventset.c:2020
void WakeupOtherProc(int pid)
Definition: waiteventset.c:2033

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(), WaitForReplicationWorkerAttach(), WakeupRecovery(), WakeupWalSummarizer(), WalRcvForceReply(), WalSndLastCycleHandler(), WalSndWaitForWal(), and XLogSetAsyncXactLSN().

WaitLatch()

int WaitLatch ( Latchlatch,
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;
190
193 (wakeEvents & (WL_EXIT_ON_PM_DEATH | WL_POSTMASTER_DEATH)),
194 NULL);
195
197 (wakeEvents & WL_TIMEOUT) ? timeout : -1,
198 &event, 1,
199 wait_event_info) == 0)
200 return WL_TIMEOUT;
201 else
202 return event.events;
203}
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: waiteventset.c:656
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: waiteventset.c:1038
#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 ( Latchlatch,
int  wakeEvents,
pgsocket  sock,
long  timeout,
uint32  wait_event_info 
)

Definition at line 223 of file latch.c.

225{
226 int ret = 0;
227 int rc;
228 WaitEvent event;
230
231 if (wakeEvents & WL_TIMEOUT)
232 Assert(timeout >= 0);
233 else
234 timeout = -1;
235
236 if (wakeEvents & WL_LATCH_SET)
238 latch, NULL);
239
240 /* Postmaster-managed callers must handle postmaster death somehow. */
242 (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
243 (wakeEvents & WL_POSTMASTER_DEATH));
244
245 if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
247 NULL, NULL);
248
249 if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
251 NULL, NULL);
252
253 if (wakeEvents & WL_SOCKET_MASK)
254 {
255 int ev;
256
257 ev = wakeEvents & WL_SOCKET_MASK;
258 AddWaitEventToSet(set, ev, sock, NULL, NULL);
259 }
260
261 rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
262
263 if (rc == 0)
264 ret |= WL_TIMEOUT;
265 else
266 {
267 ret |= event.events & (WL_LATCH_SET |
270 }
271
272 FreeWaitEventSet(set);
273
274 return ret;
275}
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
void FreeWaitEventSet(WaitEventSet *set)
Definition: waiteventset.c:481
#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().

AltStyle によって変換されたページ (->オリジナル) /