LCOV - code coverage report
Current view: top level - src/backend/storage/ipc - latch.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 72 75 96.0 %
Date: 2025-04-01 15:15:16 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14