LCOV - code coverage report
Current view: top level - src/backend/storage/lmgr - proc.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 79.7 % 735 586
Test Date: 2026-01-26 10:56:24 Functions: 82.1 % 28 23
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 46.0 % 415 191

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * proc.c
       4                 :             :  *        routines to manage per-process shared memory data structure
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/storage/lmgr/proc.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : /*
      16                 :             :  * Interface (a):
      17                 :             :  *              JoinWaitQueue(), ProcSleep(), ProcWakeup()
      18                 :             :  *
      19                 :             :  * Waiting for a lock causes the backend to be put to sleep.  Whoever releases
      20                 :             :  * the lock wakes the process up again (and gives it an error code so it knows
      21                 :             :  * whether it was awoken on an error condition).
      22                 :             :  *
      23                 :             :  * Interface (b):
      24                 :             :  *
      25                 :             :  * ProcReleaseLocks -- frees the locks associated with current transaction
      26                 :             :  *
      27                 :             :  * ProcKill -- destroys the shared memory state (and locks)
      28                 :             :  * associated with the process.
      29                 :             :  */
      30                 :             : #include "postgres.h"
      31                 :             : 
      32                 :             : #include <signal.h>
      33                 :             : #include <unistd.h>
      34                 :             : #include <sys/time.h>
      35                 :             : 
      36                 :             : #include "access/transam.h"
      37                 :             : #include "access/twophase.h"
      38                 :             : #include "access/xlogutils.h"
      39                 :             : #include "access/xlogwait.h"
      40                 :             : #include "miscadmin.h"
      41                 :             : #include "pgstat.h"
      42                 :             : #include "postmaster/autovacuum.h"
      43                 :             : #include "replication/slotsync.h"
      44                 :             : #include "replication/syncrep.h"
      45                 :             : #include "storage/condition_variable.h"
      46                 :             : #include "storage/ipc.h"
      47                 :             : #include "storage/lmgr.h"
      48                 :             : #include "storage/pmsignal.h"
      49                 :             : #include "storage/proc.h"
      50                 :             : #include "storage/procarray.h"
      51                 :             : #include "storage/procsignal.h"
      52                 :             : #include "storage/spin.h"
      53                 :             : #include "storage/standby.h"
      54                 :             : #include "utils/timeout.h"
      55                 :             : #include "utils/timestamp.h"
      56                 :             : 
      57                 :             : /* GUC variables */
      58                 :             : int                     DeadlockTimeout = 1000;
      59                 :             : int                     StatementTimeout = 0;
      60                 :             : int                     LockTimeout = 0;
      61                 :             : int                     IdleInTransactionSessionTimeout = 0;
      62                 :             : int                     TransactionTimeout = 0;
      63                 :             : int                     IdleSessionTimeout = 0;
      64                 :             : bool            log_lock_waits = true;
      65                 :             : 
      66                 :             : /* Pointer to this process's PGPROC struct, if any */
      67                 :             : PGPROC     *MyProc = NULL;
      68                 :             : 
      69                 :             : /*
      70                 :             :  * This spinlock protects the freelist of recycled PGPROC structures.
      71                 :             :  * We cannot use an LWLock because the LWLock manager depends on already
      72                 :             :  * having a PGPROC and a wait semaphore!  But these structures are touched
      73                 :             :  * relatively infrequently (only at backend startup or shutdown) and not for
      74                 :             :  * very long, so a spinlock is okay.
      75                 :             :  */
      76                 :             : NON_EXEC_STATIC slock_t *ProcStructLock = NULL;
      77                 :             : 
      78                 :             : /* Pointers to shared-memory structures */
      79                 :             : PROC_HDR   *ProcGlobal = NULL;
      80                 :             : NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL;
      81                 :             : PGPROC     *PreparedXactProcs = NULL;
      82                 :             : 
      83                 :             : static DeadLockState deadlock_state = DS_NOT_YET_CHECKED;
      84                 :             : 
      85                 :             : /* Is a deadlock check pending? */
      86                 :             : static volatile sig_atomic_t got_deadlock_timeout;
      87                 :             : 
      88                 :             : static void RemoveProcFromArray(int code, Datum arg);
      89                 :             : static void ProcKill(int code, Datum arg);
      90                 :             : static void AuxiliaryProcKill(int code, Datum arg);
      91                 :             : static void CheckDeadLock(void);
      92                 :             : 
      93                 :             : 
      94                 :             : /*
      95                 :             :  * Report shared-memory space needed by PGPROC.
      96                 :             :  */
      97                 :             : static Size
      98                 :          15 : PGProcShmemSize(void)
      99                 :             : {
     100                 :          15 :         Size            size = 0;
     101                 :          30 :         Size            TotalProcs =
     102                 :          15 :                 add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
     103                 :             : 
     104                 :          15 :         size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
     105                 :          15 :         size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
     106                 :          15 :         size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
     107                 :          15 :         size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
     108                 :             : 
     109                 :          30 :         return size;
     110                 :          15 : }
     111                 :             : 
     112                 :             : /*
     113                 :             :  * Report shared-memory space needed by Fast-Path locks.
     114                 :             :  */
     115                 :             : static Size
     116                 :          15 : FastPathLockShmemSize(void)
     117                 :             : {
     118                 :          15 :         Size            size = 0;
     119                 :          30 :         Size            TotalProcs =
     120                 :          15 :                 add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
     121                 :          15 :         Size            fpLockBitsSize,
     122                 :             :                                 fpRelIdSize;
     123                 :             : 
     124                 :             :         /*
     125                 :             :          * Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
     126                 :             :          * nicely aligned in each backend.
     127                 :             :          */
     128                 :          15 :         fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
     129                 :          15 :         fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
     130                 :             : 
     131                 :          15 :         size = add_size(size, mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
     132                 :             : 
     133                 :          30 :         return size;
     134                 :          15 : }
     135                 :             : 
     136                 :             : /*
     137                 :             :  * Report shared-memory space needed by InitProcGlobal.
     138                 :             :  */
     139                 :             : Size
     140                 :           9 : ProcGlobalShmemSize(void)
     141                 :             : {
     142                 :           9 :         Size            size = 0;
     143                 :             : 
     144                 :             :         /* ProcGlobal */
     145                 :           9 :         size = add_size(size, sizeof(PROC_HDR));
     146                 :           9 :         size = add_size(size, sizeof(slock_t));
     147                 :             : 
     148                 :           9 :         size = add_size(size, PGSemaphoreShmemSize(ProcGlobalSemas()));
     149                 :           9 :         size = add_size(size, PGProcShmemSize());
     150                 :           9 :         size = add_size(size, FastPathLockShmemSize());
     151                 :             : 
     152                 :          18 :         return size;
     153                 :           9 : }
     154                 :             : 
     155                 :             : /*
     156                 :             :  * Report number of semaphores needed by InitProcGlobal.
     157                 :             :  */
     158                 :             : int
     159                 :          18 : ProcGlobalSemas(void)
     160                 :             : {
     161                 :             :         /*
     162                 :             :          * We need a sema per backend (including autovacuum), plus one for each
     163                 :             :          * auxiliary process.
     164                 :             :          */
     165                 :          18 :         return MaxBackends + NUM_AUXILIARY_PROCS;
     166                 :             : }
     167                 :             : 
     168                 :             : /*
     169                 :             :  * InitProcGlobal -
     170                 :             :  *        Initialize the global process table during postmaster or standalone
     171                 :             :  *        backend startup.
     172                 :             :  *
     173                 :             :  *        We also create all the per-process semaphores we will need to support
     174                 :             :  *        the requested number of backends.  We used to allocate semaphores
     175                 :             :  *        only when backends were actually started up, but that is bad because
     176                 :             :  *        it lets Postgres fail under load --- a lot of Unix systems are
     177                 :             :  *        (mis)configured with small limits on the number of semaphores, and
     178                 :             :  *        running out when trying to start another backend is a common failure.
     179                 :             :  *        So, now we grab enough semaphores to support the desired max number
     180                 :             :  *        of backends immediately at initialization --- if the sysadmin has set
     181                 :             :  *        MaxConnections, max_worker_processes, max_wal_senders, or
     182                 :             :  *        autovacuum_worker_slots higher than his kernel will support, he'll
     183                 :             :  *        find out sooner rather than later.
     184                 :             :  *
     185                 :             :  *        Another reason for creating semaphores here is that the semaphore
     186                 :             :  *        implementation typically requires us to create semaphores in the
     187                 :             :  *        postmaster, not in backends.
     188                 :             :  *
     189                 :             :  * Note: this is NOT called by individual backends under a postmaster,
     190                 :             :  * not even in the EXEC_BACKEND case.  The ProcGlobal and AuxiliaryProcs
     191                 :             :  * pointers must be propagated specially for EXEC_BACKEND operation.
     192                 :             :  */
     193                 :             : void
     194                 :           6 : InitProcGlobal(void)
     195                 :             : {
     196                 :           6 :         PGPROC     *procs;
     197                 :           6 :         int                     i,
     198                 :             :                                 j;
     199                 :           6 :         bool            found;
     200                 :           6 :         uint32          TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
     201                 :             : 
     202                 :             :         /* Used for setup of per-backend fast-path slots. */
     203                 :           6 :         char       *fpPtr,
     204                 :             :                            *fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
     205                 :           6 :         Size            fpLockBitsSize,
     206                 :             :                                 fpRelIdSize;
     207                 :           6 :         Size            requestSize;
     208                 :           6 :         char       *ptr;
     209                 :             : 
     210                 :             :         /* Create the ProcGlobal shared structure */
     211                 :           6 :         ProcGlobal = (PROC_HDR *)
     212                 :           6 :                 ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
     213         [ +  - ]:           6 :         Assert(!found);
     214                 :             : 
     215                 :             :         /*
     216                 :             :          * Initialize the data structures.
     217                 :             :          */
     218                 :           6 :         ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
     219                 :           6 :         dlist_init(&ProcGlobal->freeProcs);
     220                 :           6 :         dlist_init(&ProcGlobal->autovacFreeProcs);
     221                 :           6 :         dlist_init(&ProcGlobal->bgworkerFreeProcs);
     222                 :           6 :         dlist_init(&ProcGlobal->walsenderFreeProcs);
     223                 :           6 :         ProcGlobal->startupBufferPinWaitBufId = -1;
     224                 :           6 :         ProcGlobal->walwriterProc = INVALID_PROC_NUMBER;
     225                 :           6 :         ProcGlobal->checkpointerProc = INVALID_PROC_NUMBER;
     226                 :           6 :         pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER);
     227                 :           6 :         pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
     228                 :             : 
     229                 :             :         /*
     230                 :             :          * Create and initialize all the PGPROC structures we'll need.  There are
     231                 :             :          * six separate consumers: (1) normal backends, (2) autovacuum workers and
     232                 :             :          * special workers, (3) background workers, (4) walsenders, (5) auxiliary
     233                 :             :          * processes, and (6) prepared transactions.  (For largely-historical
     234                 :             :          * reasons, we combine autovacuum and special workers into one category
     235                 :             :          * with a single freelist.)  Each PGPROC structure is dedicated to exactly
     236                 :             :          * one of these purposes, and they do not move between groups.
     237                 :             :          */
     238                 :           6 :         requestSize = PGProcShmemSize();
     239                 :             : 
     240                 :           6 :         ptr = ShmemInitStruct("PGPROC structures",
     241                 :           6 :                                                   requestSize,
     242                 :             :                                                   &found);
     243                 :             : 
     244   [ +  -  +  +  :           6 :         MemSet(ptr, 0, requestSize);
          +  -  +  -  #  
                      # ]
     245                 :             : 
     246                 :           6 :         procs = (PGPROC *) ptr;
     247                 :           6 :         ptr = ptr + TotalProcs * sizeof(PGPROC);
     248                 :             : 
     249                 :           6 :         ProcGlobal->allProcs = procs;
     250                 :             :         /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
     251                 :           6 :         ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
     252                 :             : 
     253                 :             :         /*
     254                 :             :          * Allocate arrays mirroring PGPROC fields in a dense manner. See
     255                 :             :          * PROC_HDR.
     256                 :             :          *
     257                 :             :          * XXX: It might make sense to increase padding for these arrays, given
     258                 :             :          * how hotly they are accessed.
     259                 :             :          */
     260                 :           6 :         ProcGlobal->xids = (TransactionId *) ptr;
     261                 :           6 :         ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->xids));
     262                 :             : 
     263                 :           6 :         ProcGlobal->subxidStates = (XidCacheStatus *) ptr;
     264                 :           6 :         ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->subxidStates));
     265                 :             : 
     266                 :           6 :         ProcGlobal->statusFlags = (uint8 *) ptr;
     267                 :           6 :         ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
     268                 :             : 
     269                 :             :         /* make sure wer didn't overflow */
     270         [ +  - ]:           6 :         Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
     271                 :             : 
     272                 :             :         /*
     273                 :             :          * Allocate arrays for fast-path locks. Those are variable-length, so
     274                 :             :          * can't be included in PGPROC directly. We allocate a separate piece of
     275                 :             :          * shared memory and then divide that between backends.
     276                 :             :          */
     277                 :           6 :         fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
     278                 :           6 :         fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
     279                 :             : 
     280                 :           6 :         requestSize = FastPathLockShmemSize();
     281                 :             : 
     282                 :           6 :         fpPtr = ShmemInitStruct("Fast-Path Lock Array",
     283                 :           6 :                                                         requestSize,
     284                 :             :                                                         &found);
     285                 :             : 
     286   [ +  -  +  -  :           6 :         MemSet(fpPtr, 0, requestSize);
          +  -  +  -  #  
                      # ]
     287                 :             : 
     288                 :             :         /* For asserts checking we did not overflow. */
     289                 :           6 :         fpEndPtr = fpPtr + requestSize;
     290                 :             : 
     291                 :             :         /* Reserve space for semaphores. */
     292                 :           6 :         PGReserveSemaphores(ProcGlobalSemas());
     293                 :             : 
     294         [ +  + ]:        1042 :         for (i = 0; i < TotalProcs; i++)
     295                 :             :         {
     296                 :        1036 :                 PGPROC     *proc = &procs[i];
     297                 :             : 
     298                 :             :                 /* Common initialization for all PGPROCs, regardless of type. */
     299                 :             : 
     300                 :             :                 /*
     301                 :             :                  * Set the fast-path lock arrays, and move the pointer. We interleave
     302                 :             :                  * the two arrays, to (hopefully) get some locality for each backend.
     303                 :             :                  */
     304                 :        1036 :                 proc->fpLockBits = (uint64 *) fpPtr;
     305                 :        1036 :                 fpPtr += fpLockBitsSize;
     306                 :             : 
     307                 :        1036 :                 proc->fpRelId = (Oid *) fpPtr;
     308                 :        1036 :                 fpPtr += fpRelIdSize;
     309                 :             : 
     310         [ +  - ]:        1036 :                 Assert(fpPtr <= fpEndPtr);
     311                 :             : 
     312                 :             :                 /*
     313                 :             :                  * Set up per-PGPROC semaphore, latch, and fpInfoLock.  Prepared xact
     314                 :             :                  * dummy PGPROCs don't need these though - they're never associated
     315                 :             :                  * with a real process
     316                 :             :                  */
     317         [ +  + ]:        1036 :                 if (i < MaxBackends + NUM_AUXILIARY_PROCS)
     318                 :             :                 {
     319                 :        1034 :                         proc->sem = PGSemaphoreCreate();
     320                 :        1034 :                         InitSharedLatch(&(proc->procLatch));
     321                 :        1034 :                         LWLockInitialize(&(proc->fpInfoLock), LWTRANCHE_LOCK_FASTPATH);
     322                 :        1034 :                 }
     323                 :             : 
     324                 :             :                 /*
     325                 :             :                  * Newly created PGPROCs for normal backends, autovacuum workers,
     326                 :             :                  * special workers, bgworkers, and walsenders must be queued up on the
     327                 :             :                  * appropriate free list.  Because there can only ever be a small,
     328                 :             :                  * fixed number of auxiliary processes, no free list is used in that
     329                 :             :                  * case; InitAuxiliaryProcess() instead uses a linear search.  PGPROCs
     330                 :             :                  * for prepared transactions are added to a free list by
     331                 :             :                  * TwoPhaseShmemInit().
     332                 :             :                  */
     333         [ +  + ]:        1036 :                 if (i < MaxConnections)
     334                 :             :                 {
     335                 :             :                         /* PGPROC for normal backend, add to freeProcs list */
     336                 :         600 :                         dlist_push_tail(&ProcGlobal->freeProcs, &proc->links);
     337                 :         600 :                         proc->procgloballist = &ProcGlobal->freeProcs;
     338                 :         600 :                 }
     339         [ +  + ]:         436 :                 else if (i < MaxConnections + autovacuum_worker_slots + NUM_SPECIAL_WORKER_PROCS)
     340                 :             :                 {
     341                 :             :                         /* PGPROC for AV or special worker, add to autovacFreeProcs list */
     342                 :         108 :                         dlist_push_tail(&ProcGlobal->autovacFreeProcs, &proc->links);
     343                 :         108 :                         proc->procgloballist = &ProcGlobal->autovacFreeProcs;
     344                 :         108 :                 }
     345         [ +  + ]:         328 :                 else if (i < MaxConnections + autovacuum_worker_slots + NUM_SPECIAL_WORKER_PROCS + max_worker_processes)
     346                 :             :                 {
     347                 :             :                         /* PGPROC for bgworker, add to bgworkerFreeProcs list */
     348                 :          48 :                         dlist_push_tail(&ProcGlobal->bgworkerFreeProcs, &proc->links);
     349                 :          48 :                         proc->procgloballist = &ProcGlobal->bgworkerFreeProcs;
     350                 :          48 :                 }
     351         [ +  + ]:         280 :                 else if (i < MaxBackends)
     352                 :             :                 {
     353                 :             :                         /* PGPROC for walsender, add to walsenderFreeProcs list */
     354                 :          50 :                         dlist_push_tail(&ProcGlobal->walsenderFreeProcs, &proc->links);
     355                 :          50 :                         proc->procgloballist = &ProcGlobal->walsenderFreeProcs;
     356                 :          50 :                 }
     357                 :             : 
     358                 :             :                 /* Initialize myProcLocks[] shared memory queues. */
     359         [ +  + ]:       17612 :                 for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
     360                 :       16576 :                         dlist_init(&(proc->myProcLocks[j]));
     361                 :             : 
     362                 :             :                 /* Initialize lockGroupMembers list. */
     363                 :        1036 :                 dlist_init(&proc->lockGroupMembers);
     364                 :             : 
     365                 :             :                 /*
     366                 :             :                  * Initialize the atomic variables, otherwise, it won't be safe to
     367                 :             :                  * access them for backends that aren't currently in use.
     368                 :             :                  */
     369                 :        1036 :                 pg_atomic_init_u32(&(proc->procArrayGroupNext), INVALID_PROC_NUMBER);
     370                 :        1036 :                 pg_atomic_init_u32(&(proc->clogGroupNext), INVALID_PROC_NUMBER);
     371                 :        1036 :                 pg_atomic_init_u64(&(proc->waitStart), 0);
     372                 :        1036 :         }
     373                 :             : 
     374                 :             :         /* Should have consumed exactly the expected amount of fast-path memory. */
     375         [ +  - ]:           6 :         Assert(fpPtr == fpEndPtr);
     376                 :             : 
     377                 :             :         /*
     378                 :             :          * Save pointers to the blocks of PGPROC structures reserved for auxiliary
     379                 :             :          * processes and prepared transactions.
     380                 :             :          */
     381                 :           6 :         AuxiliaryProcs = &procs[MaxBackends];
     382                 :           6 :         PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS];
     383                 :             : 
     384                 :             :         /* Create ProcStructLock spinlock, too */
     385                 :           6 :         ProcStructLock = (slock_t *) ShmemInitStruct("ProcStructLock spinlock",
     386                 :             :                                                                                                  sizeof(slock_t),
     387                 :             :                                                                                                  &found);
     388                 :           6 :         SpinLockInit(ProcStructLock);
     389                 :           6 : }
     390                 :             : 
     391                 :             : /*
     392                 :             :  * InitProcess -- initialize a per-process PGPROC entry for this backend
     393                 :             :  */
     394                 :             : void
     395                 :         798 : InitProcess(void)
     396                 :             : {
     397                 :         798 :         dlist_head *procgloballist;
     398                 :             : 
     399                 :             :         /*
     400                 :             :          * ProcGlobal should be set up already (if we are a backend, we inherit
     401                 :             :          * this by fork() or EXEC_BACKEND mechanism from the postmaster).
     402                 :             :          */
     403         [ +  - ]:         798 :         if (ProcGlobal == NULL)
     404   [ #  #  #  # ]:           0 :                 elog(PANIC, "proc header uninitialized");
     405                 :             : 
     406         [ +  - ]:         798 :         if (MyProc != NULL)
     407   [ #  #  #  # ]:           0 :                 elog(ERROR, "you already exist");
     408                 :             : 
     409                 :             :         /*
     410                 :             :          * Before we start accessing the shared memory in a serious way, mark
     411                 :             :          * ourselves as an active postmaster child; this is so that the postmaster
     412                 :             :          * can detect it if we exit without cleaning up.
     413                 :             :          */
     414         [ +  + ]:         798 :         if (IsUnderPostmaster)
     415                 :         796 :                 RegisterPostmasterChildActive();
     416                 :             : 
     417                 :             :         /*
     418                 :             :          * Decide which list should supply our PGPROC.  This logic must match the
     419                 :             :          * way the freelists were constructed in InitProcGlobal().
     420                 :             :          */
     421   [ +  +  +  +  :         798 :         if (AmAutoVacuumWorkerProcess() || AmSpecialWorkerProcess())
                   -  + ]
     422                 :           2 :                 procgloballist = &ProcGlobal->autovacFreeProcs;
     423         [ +  + ]:         796 :         else if (AmBackgroundWorkerProcess())
     424                 :         479 :                 procgloballist = &ProcGlobal->bgworkerFreeProcs;
     425         [ -  + ]:         317 :         else if (AmWalSenderProcess())
     426                 :           0 :                 procgloballist = &ProcGlobal->walsenderFreeProcs;
     427                 :             :         else
     428                 :         317 :                 procgloballist = &ProcGlobal->freeProcs;
     429                 :             : 
     430                 :             :         /*
     431                 :             :          * Try to get a proc struct from the appropriate free list.  If this
     432                 :             :          * fails, we must be out of PGPROC structures (not to mention semaphores).
     433                 :             :          *
     434                 :             :          * While we are holding the ProcStructLock, also copy the current shared
     435                 :             :          * estimate of spins_per_delay to local storage.
     436                 :             :          */
     437         [ +  + ]:         798 :         SpinLockAcquire(ProcStructLock);
     438                 :             : 
     439                 :         798 :         set_spins_per_delay(ProcGlobal->spins_per_delay);
     440                 :             : 
     441         [ +  - ]:         798 :         if (!dlist_is_empty(procgloballist))
     442                 :             :         {
     443                 :         798 :                 MyProc = dlist_container(PGPROC, links, dlist_pop_head_node(procgloballist));
     444                 :         798 :                 SpinLockRelease(ProcStructLock);
     445                 :         798 :         }
     446                 :             :         else
     447                 :             :         {
     448                 :             :                 /*
     449                 :             :                  * If we reach here, all the PGPROCs are in use.  This is one of the
     450                 :             :                  * possible places to detect "too many backends", so give the standard
     451                 :             :                  * error message.  XXX do we need to give a different failure message
     452                 :             :                  * in the autovacuum case?
     453                 :             :                  */
     454                 :           0 :                 SpinLockRelease(ProcStructLock);
     455         [ #  # ]:           0 :                 if (AmWalSenderProcess())
     456   [ #  #  #  # ]:           0 :                         ereport(FATAL,
     457                 :             :                                         (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
     458                 :             :                                          errmsg("number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
     459                 :             :                                                         max_wal_senders)));
     460   [ #  #  #  # ]:           0 :                 ereport(FATAL,
     461                 :             :                                 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
     462                 :             :                                  errmsg("sorry, too many clients already")));
     463                 :             :         }
     464                 :         798 :         MyProcNumber = GetNumberFromPGProc(MyProc);
     465                 :             : 
     466                 :             :         /*
     467                 :             :          * Cross-check that the PGPROC is of the type we expect; if this were not
     468                 :             :          * the case, it would get returned to the wrong list.
     469                 :             :          */
     470         [ +  - ]:         798 :         Assert(MyProc->procgloballist == procgloballist);
     471                 :             : 
     472                 :             :         /*
     473                 :             :          * Initialize all fields of MyProc, except for those previously
     474                 :             :          * initialized by InitProcGlobal.
     475                 :             :          */
     476                 :         798 :         dlist_node_init(&MyProc->links);
     477                 :         798 :         MyProc->waitStatus = PROC_WAIT_STATUS_OK;
     478                 :         798 :         MyProc->fpVXIDLock = false;
     479                 :         798 :         MyProc->fpLocalTransactionId = InvalidLocalTransactionId;
     480                 :         798 :         MyProc->xid = InvalidTransactionId;
     481                 :         798 :         MyProc->xmin = InvalidTransactionId;
     482                 :         798 :         MyProc->pid = MyProcPid;
     483                 :         798 :         MyProc->vxid.procNumber = MyProcNumber;
     484                 :         798 :         MyProc->vxid.lxid = InvalidLocalTransactionId;
     485                 :             :         /* databaseId and roleId will be filled in later */
     486                 :         798 :         MyProc->databaseId = InvalidOid;
     487                 :         798 :         MyProc->roleId = InvalidOid;
     488                 :         798 :         MyProc->tempNamespaceId = InvalidOid;
     489                 :         798 :         MyProc->isRegularBackend = AmRegularBackendProcess();
     490                 :         798 :         MyProc->delayChkptFlags = 0;
     491                 :         798 :         MyProc->statusFlags = 0;
     492                 :             :         /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
     493         [ +  + ]:         798 :         if (AmAutoVacuumWorkerProcess())
     494                 :           1 :                 MyProc->statusFlags |= PROC_IS_AUTOVACUUM;
     495                 :         798 :         MyProc->lwWaiting = LW_WS_NOT_WAITING;
     496                 :         798 :         MyProc->lwWaitMode = 0;
     497                 :         798 :         MyProc->waitLock = NULL;
     498                 :         798 :         MyProc->waitProcLock = NULL;
     499                 :         798 :         pg_atomic_write_u64(&MyProc->waitStart, 0);
     500                 :             : #ifdef USE_ASSERT_CHECKING
     501                 :             :         {
     502                 :         798 :                 int                     i;
     503                 :             : 
     504                 :             :                 /* Last process should have released all locks. */
     505         [ +  + ]:       13566 :                 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
     506         [ +  - ]:       12768 :                         Assert(dlist_is_empty(&(MyProc->myProcLocks[i])));
     507                 :         798 :         }
     508                 :             : #endif
     509                 :         798 :         MyProc->recoveryConflictPending = false;
     510                 :             : 
     511                 :             :         /* Initialize fields for sync rep */
     512                 :         798 :         MyProc->waitLSN = 0;
     513                 :         798 :         MyProc->syncRepState = SYNC_REP_NOT_WAITING;
     514                 :         798 :         dlist_node_init(&MyProc->syncRepLinks);
     515                 :             : 
     516                 :             :         /* Initialize fields for group XID clearing. */
     517                 :         798 :         MyProc->procArrayGroupMember = false;
     518                 :         798 :         MyProc->procArrayGroupMemberXid = InvalidTransactionId;
     519         [ +  - ]:         798 :         Assert(pg_atomic_read_u32(&MyProc->procArrayGroupNext) == INVALID_PROC_NUMBER);
     520                 :             : 
     521                 :             :         /* Check that group locking fields are in a proper initial state. */
     522         [ +  - ]:         798 :         Assert(MyProc->lockGroupLeader == NULL);
     523         [ +  - ]:         798 :         Assert(dlist_is_empty(&MyProc->lockGroupMembers));
     524                 :             : 
     525                 :             :         /* Initialize wait event information. */
     526                 :         798 :         MyProc->wait_event_info = 0;
     527                 :             : 
     528                 :             :         /* Initialize fields for group transaction status update. */
     529                 :         798 :         MyProc->clogGroupMember = false;
     530                 :         798 :         MyProc->clogGroupMemberXid = InvalidTransactionId;
     531                 :         798 :         MyProc->clogGroupMemberXidStatus = TRANSACTION_STATUS_IN_PROGRESS;
     532                 :         798 :         MyProc->clogGroupMemberPage = -1;
     533                 :         798 :         MyProc->clogGroupMemberLsn = InvalidXLogRecPtr;
     534         [ +  - ]:         798 :         Assert(pg_atomic_read_u32(&MyProc->clogGroupNext) == INVALID_PROC_NUMBER);
     535                 :             : 
     536                 :             :         /*
     537                 :             :          * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
     538                 :             :          * on it.  That allows us to repoint the process latch, which so far
     539                 :             :          * points to process local one, to the shared one.
     540                 :             :          */
     541                 :         798 :         OwnLatch(&MyProc->procLatch);
     542                 :         798 :         SwitchToSharedLatch();
     543                 :             : 
     544                 :             :         /* now that we have a proc, report wait events to shared memory */
     545                 :         798 :         pgstat_set_wait_event_storage(&MyProc->wait_event_info);
     546                 :             : 
     547                 :             :         /*
     548                 :             :          * We might be reusing a semaphore that belonged to a failed process. So
     549                 :             :          * be careful and reinitialize its value here.  (This is not strictly
     550                 :             :          * necessary anymore, but seems like a good idea for cleanliness.)
     551                 :             :          */
     552                 :         798 :         PGSemaphoreReset(MyProc->sem);
     553                 :             : 
     554                 :             :         /*
     555                 :             :          * Arrange to clean up at backend exit.
     556                 :             :          */
     557                 :         798 :         on_shmem_exit(ProcKill, 0);
     558                 :             : 
     559                 :             :         /*
     560                 :             :          * Now that we have a PGPROC, we could try to acquire locks, so initialize
     561                 :             :          * local state needed for LWLocks, and the deadlock checker.
     562                 :             :          */
     563                 :         798 :         InitLWLockAccess();
     564                 :         798 :         InitDeadLockChecking();
     565                 :             : 
     566                 :             : #ifdef EXEC_BACKEND
     567                 :             : 
     568                 :             :         /*
     569                 :             :          * Initialize backend-local pointers to all the shared data structures.
     570                 :             :          * (We couldn't do this until now because it needs LWLocks.)
     571                 :             :          */
     572                 :             :         if (IsUnderPostmaster)
     573                 :             :                 AttachSharedMemoryStructs();
     574                 :             : #endif
     575                 :         798 : }
     576                 :             : 
     577                 :             : /*
     578                 :             :  * InitProcessPhase2 -- make MyProc visible in the shared ProcArray.
     579                 :             :  *
     580                 :             :  * This is separate from InitProcess because we can't acquire LWLocks until
     581                 :             :  * we've created a PGPROC, but in the EXEC_BACKEND case ProcArrayAdd won't
     582                 :             :  * work until after we've done AttachSharedMemoryStructs.
     583                 :             :  */
     584                 :             : void
     585                 :         798 : InitProcessPhase2(void)
     586                 :             : {
     587         [ +  - ]:         798 :         Assert(MyProc != NULL);
     588                 :             : 
     589                 :             :         /*
     590                 :             :          * Add our PGPROC to the PGPROC array in shared memory.
     591                 :             :          */
     592                 :         798 :         ProcArrayAdd(MyProc);
     593                 :             : 
     594                 :             :         /*
     595                 :             :          * Arrange to clean that up at backend exit.
     596                 :             :          */
     597                 :         798 :         on_shmem_exit(RemoveProcFromArray, 0);
     598                 :         798 : }
     599                 :             : 
     600                 :             : /*
     601                 :             :  * InitAuxiliaryProcess -- create a PGPROC entry for an auxiliary process
     602                 :             :  *
     603                 :             :  * This is called by bgwriter and similar processes so that they will have a
     604                 :             :  * MyProc value that's real enough to let them wait for LWLocks.  The PGPROC
     605                 :             :  * and sema that are assigned are one of the extra ones created during
     606                 :             :  * InitProcGlobal.
     607                 :             :  *
     608                 :             :  * Auxiliary processes are presently not expected to wait for real (lockmgr)
     609                 :             :  * locks, so we need not set up the deadlock checker.  They are never added
     610                 :             :  * to the ProcArray or the sinval messaging mechanism, either.  They also
     611                 :             :  * don't get a VXID assigned, since this is only useful when we actually
     612                 :             :  * hold lockmgr locks.
     613                 :             :  *
     614                 :             :  * Startup process however uses locks but never waits for them in the
     615                 :             :  * normal backend sense. Startup process also takes part in sinval messaging
     616                 :             :  * as a sendOnly process, so never reads messages from sinval queue. So
     617                 :             :  * Startup process does have a VXID and does show up in pg_locks.
     618                 :             :  */
     619                 :             : void
     620                 :           8 : InitAuxiliaryProcess(void)
     621                 :             : {
     622                 :           8 :         PGPROC     *auxproc;
     623                 :           8 :         int                     proctype;
     624                 :             : 
     625                 :             :         /*
     626                 :             :          * ProcGlobal should be set up already (if we are a backend, we inherit
     627                 :             :          * this by fork() or EXEC_BACKEND mechanism from the postmaster).
     628                 :             :          */
     629         [ +  - ]:           8 :         if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
     630   [ #  #  #  # ]:           0 :                 elog(PANIC, "proc header uninitialized");
     631                 :             : 
     632         [ +  - ]:           8 :         if (MyProc != NULL)
     633   [ #  #  #  # ]:           0 :                 elog(ERROR, "you already exist");
     634                 :             : 
     635         [ -  + ]:           8 :         if (IsUnderPostmaster)
     636                 :           8 :                 RegisterPostmasterChildActive();
     637                 :             : 
     638                 :             :         /*
     639                 :             :          * We use the ProcStructLock to protect assignment and releasing of
     640                 :             :          * AuxiliaryProcs entries.
     641                 :             :          *
     642                 :             :          * While we are holding the ProcStructLock, also copy the current shared
     643                 :             :          * estimate of spins_per_delay to local storage.
     644                 :             :          */
     645         [ +  + ]:           8 :         SpinLockAcquire(ProcStructLock);
     646                 :             : 
     647                 :           8 :         set_spins_per_delay(ProcGlobal->spins_per_delay);
     648                 :             : 
     649                 :             :         /*
     650                 :             :          * Find a free auxproc ... *big* trouble if there isn't one ...
     651                 :             :          */
     652         [ -  + ]:          33 :         for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
     653                 :             :         {
     654                 :          33 :                 auxproc = &AuxiliaryProcs[proctype];
     655         [ +  + ]:          33 :                 if (auxproc->pid == 0)
     656                 :           8 :                         break;
     657                 :          25 :         }
     658         [ +  - ]:           8 :         if (proctype >= NUM_AUXILIARY_PROCS)
     659                 :             :         {
     660                 :           0 :                 SpinLockRelease(ProcStructLock);
     661   [ #  #  #  # ]:           0 :                 elog(FATAL, "all AuxiliaryProcs are in use");
     662                 :           0 :         }
     663                 :             : 
     664                 :             :         /* Mark auxiliary proc as in use by me */
     665                 :             :         /* use volatile pointer to prevent code rearrangement */
     666                 :           8 :         ((volatile PGPROC *) auxproc)->pid = MyProcPid;
     667                 :             : 
     668                 :           8 :         SpinLockRelease(ProcStructLock);
     669                 :             : 
     670                 :           8 :         MyProc = auxproc;
     671                 :           8 :         MyProcNumber = GetNumberFromPGProc(MyProc);
     672                 :             : 
     673                 :             :         /*
     674                 :             :          * Initialize all fields of MyProc, except for those previously
     675                 :             :          * initialized by InitProcGlobal.
     676                 :             :          */
     677                 :           8 :         dlist_node_init(&MyProc->links);
     678                 :           8 :         MyProc->waitStatus = PROC_WAIT_STATUS_OK;
     679                 :           8 :         MyProc->fpVXIDLock = false;
     680                 :           8 :         MyProc->fpLocalTransactionId = InvalidLocalTransactionId;
     681                 :           8 :         MyProc->xid = InvalidTransactionId;
     682                 :           8 :         MyProc->xmin = InvalidTransactionId;
     683                 :           8 :         MyProc->vxid.procNumber = INVALID_PROC_NUMBER;
     684                 :           8 :         MyProc->vxid.lxid = InvalidLocalTransactionId;
     685                 :           8 :         MyProc->databaseId = InvalidOid;
     686                 :           8 :         MyProc->roleId = InvalidOid;
     687                 :           8 :         MyProc->tempNamespaceId = InvalidOid;
     688                 :           8 :         MyProc->isRegularBackend = false;
     689                 :           8 :         MyProc->delayChkptFlags = 0;
     690                 :           8 :         MyProc->statusFlags = 0;
     691                 :           8 :         MyProc->lwWaiting = LW_WS_NOT_WAITING;
     692                 :           8 :         MyProc->lwWaitMode = 0;
     693                 :           8 :         MyProc->waitLock = NULL;
     694                 :           8 :         MyProc->waitProcLock = NULL;
     695                 :           8 :         pg_atomic_write_u64(&MyProc->waitStart, 0);
     696                 :             : #ifdef USE_ASSERT_CHECKING
     697                 :             :         {
     698                 :           8 :                 int                     i;
     699                 :             : 
     700                 :             :                 /* Last process should have released all locks. */
     701         [ +  + ]:         136 :                 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
     702         [ +  - ]:         128 :                         Assert(dlist_is_empty(&(MyProc->myProcLocks[i])));
     703                 :           8 :         }
     704                 :             : #endif
     705                 :             : 
     706                 :             :         /*
     707                 :             :          * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
     708                 :             :          * on it.  That allows us to repoint the process latch, which so far
     709                 :             :          * points to process local one, to the shared one.
     710                 :             :          */
     711                 :           8 :         OwnLatch(&MyProc->procLatch);
     712                 :           8 :         SwitchToSharedLatch();
     713                 :             : 
     714                 :             :         /* now that we have a proc, report wait events to shared memory */
     715                 :           8 :         pgstat_set_wait_event_storage(&MyProc->wait_event_info);
     716                 :             : 
     717                 :             :         /* Check that group locking fields are in a proper initial state. */
     718         [ +  - ]:           8 :         Assert(MyProc->lockGroupLeader == NULL);
     719         [ +  - ]:           8 :         Assert(dlist_is_empty(&MyProc->lockGroupMembers));
     720                 :             : 
     721                 :             :         /*
     722                 :             :          * We might be reusing a semaphore that belonged to a failed process. So
     723                 :             :          * be careful and reinitialize its value here.  (This is not strictly
     724                 :             :          * necessary anymore, but seems like a good idea for cleanliness.)
     725                 :             :          */
     726                 :           8 :         PGSemaphoreReset(MyProc->sem);
     727                 :             : 
     728                 :             :         /*
     729                 :             :          * Arrange to clean up at process exit.
     730                 :             :          */
     731                 :           8 :         on_shmem_exit(AuxiliaryProcKill, Int32GetDatum(proctype));
     732                 :             : 
     733                 :             :         /*
     734                 :             :          * Now that we have a PGPROC, we could try to acquire lightweight locks.
     735                 :             :          * Initialize local state needed for them.  (Heavyweight locks cannot be
     736                 :             :          * acquired in aux processes.)
     737                 :             :          */
     738                 :           8 :         InitLWLockAccess();
     739                 :             : 
     740                 :             : #ifdef EXEC_BACKEND
     741                 :             : 
     742                 :             :         /*
     743                 :             :          * Initialize backend-local pointers to all the shared data structures.
     744                 :             :          * (We couldn't do this until now because it needs LWLocks.)
     745                 :             :          */
     746                 :             :         if (IsUnderPostmaster)
     747                 :             :                 AttachSharedMemoryStructs();
     748                 :             : #endif
     749                 :           8 : }
     750                 :             : 
     751                 :             : /*
     752                 :             :  * Used from bufmgr to share the value of the buffer that Startup waits on,
     753                 :             :  * or to reset the value to "not waiting" (-1). This allows processing
     754                 :             :  * of recovery conflicts for buffer pins. Set is made before backends look
     755                 :             :  * at this value, so locking not required, especially since the set is
     756                 :             :  * an atomic integer set operation.
     757                 :             :  */
     758                 :             : void
     759                 :           0 : SetStartupBufferPinWaitBufId(int bufid)
     760                 :             : {
     761                 :             :         /* use volatile pointer to prevent code rearrangement */
     762                 :           0 :         volatile PROC_HDR *procglobal = ProcGlobal;
     763                 :             : 
     764                 :           0 :         procglobal->startupBufferPinWaitBufId = bufid;
     765                 :           0 : }
     766                 :             : 
     767                 :             : /*
     768                 :             :  * Used by backends when they receive a request to check for buffer pin waits.
     769                 :             :  */
     770                 :             : int
     771                 :           0 : GetStartupBufferPinWaitBufId(void)
     772                 :             : {
     773                 :             :         /* use volatile pointer to prevent code rearrangement */
     774                 :           0 :         volatile PROC_HDR *procglobal = ProcGlobal;
     775                 :             : 
     776                 :           0 :         return procglobal->startupBufferPinWaitBufId;
     777                 :           0 : }
     778                 :             : 
     779                 :             : /*
     780                 :             :  * Check whether there are at least N free PGPROC objects.  If false is
     781                 :             :  * returned, *nfree will be set to the number of free PGPROC objects.
     782                 :             :  * Otherwise, *nfree will be set to n.
     783                 :             :  *
     784                 :             :  * Note: this is designed on the assumption that N will generally be small.
     785                 :             :  */
     786                 :             : bool
     787                 :           0 : HaveNFreeProcs(int n, int *nfree)
     788                 :             : {
     789                 :           0 :         dlist_iter      iter;
     790                 :             : 
     791         [ #  # ]:           0 :         Assert(n > 0);
     792         [ #  # ]:           0 :         Assert(nfree);
     793                 :             : 
     794         [ #  # ]:           0 :         SpinLockAcquire(ProcStructLock);
     795                 :             : 
     796                 :           0 :         *nfree = 0;
     797   [ #  #  #  # ]:           0 :         dlist_foreach(iter, &ProcGlobal->freeProcs)
     798                 :             :         {
     799                 :           0 :                 (*nfree)++;
     800         [ #  # ]:           0 :                 if (*nfree == n)
     801                 :           0 :                         break;
     802                 :           0 :         }
     803                 :             : 
     804                 :           0 :         SpinLockRelease(ProcStructLock);
     805                 :             : 
     806                 :           0 :         return (*nfree == n);
     807                 :           0 : }
     808                 :             : 
     809                 :             : /*
     810                 :             :  * Cancel any pending wait for lock, when aborting a transaction, and revert
     811                 :             :  * any strong lock count acquisition for a lock being acquired.
     812                 :             :  *
     813                 :             :  * (Normally, this would only happen if we accept a cancel/die
     814                 :             :  * interrupt while waiting; but an ereport(ERROR) before or during the lock
     815                 :             :  * wait is within the realm of possibility, too.)
     816                 :             :  */
     817                 :             : void
     818                 :       66115 : LockErrorCleanup(void)
     819                 :             : {
     820                 :       66115 :         LOCALLOCK  *lockAwaited;
     821                 :       66115 :         LWLock     *partitionLock;
     822                 :       66115 :         DisableTimeoutParams timeouts[2];
     823                 :             : 
     824                 :       66115 :         HOLD_INTERRUPTS();
     825                 :             : 
     826                 :       66115 :         AbortStrongLockAcquire();
     827                 :             : 
     828                 :             :         /* Nothing to do if we weren't waiting for a lock */
     829                 :       66115 :         lockAwaited = GetAwaitedLock();
     830         [ +  + ]:       66115 :         if (lockAwaited == NULL)
     831                 :             :         {
     832         [ +  - ]:       66114 :                 RESUME_INTERRUPTS();
     833                 :       66114 :                 return;
     834                 :             :         }
     835                 :             : 
     836                 :             :         /*
     837                 :             :          * Turn off the deadlock and lock timeout timers, if they are still
     838                 :             :          * running (see ProcSleep).  Note we must preserve the LOCK_TIMEOUT
     839                 :             :          * indicator flag, since this function is executed before
     840                 :             :          * ProcessInterrupts when responding to SIGINT; else we'd lose the
     841                 :             :          * knowledge that the SIGINT came from a lock timeout and not an external
     842                 :             :          * source.
     843                 :             :          */
     844                 :           1 :         timeouts[0].id = DEADLOCK_TIMEOUT;
     845                 :           1 :         timeouts[0].keep_indicator = false;
     846                 :           1 :         timeouts[1].id = LOCK_TIMEOUT;
     847                 :           1 :         timeouts[1].keep_indicator = true;
     848                 :           1 :         disable_timeouts(timeouts, 2);
     849                 :             : 
     850                 :             :         /* Unlink myself from the wait queue, if on it (might not be anymore!) */
     851                 :           1 :         partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
     852                 :           1 :         LWLockAcquire(partitionLock, LW_EXCLUSIVE);
     853                 :             : 
     854         [ -  + ]:           1 :         if (!dlist_node_is_detached(&MyProc->links))
     855                 :             :         {
     856                 :             :                 /* We could not have been granted the lock yet */
     857                 :           1 :                 RemoveFromWaitQueue(MyProc, lockAwaited->hashcode);
     858                 :           1 :         }
     859                 :             :         else
     860                 :             :         {
     861                 :             :                 /*
     862                 :             :                  * Somebody kicked us off the lock queue already.  Perhaps they
     863                 :             :                  * granted us the lock, or perhaps they detected a deadlock. If they
     864                 :             :                  * did grant us the lock, we'd better remember it in our local lock
     865                 :             :                  * table.
     866                 :             :                  */
     867         [ #  # ]:           0 :                 if (MyProc->waitStatus == PROC_WAIT_STATUS_OK)
     868                 :           0 :                         GrantAwaitedLock();
     869                 :             :         }
     870                 :             : 
     871                 :           1 :         ResetAwaitedLock();
     872                 :             : 
     873                 :           1 :         LWLockRelease(partitionLock);
     874                 :             : 
     875         [ +  - ]:           1 :         RESUME_INTERRUPTS();
     876         [ -  + ]:       66115 : }
     877                 :             : 
     878                 :             : 
     879                 :             : /*
     880                 :             :  * ProcReleaseLocks() -- release locks associated with current transaction
     881                 :             :  *                      at main transaction commit or abort
     882                 :             :  *
     883                 :             :  * At main transaction commit, we release standard locks except session locks.
     884                 :             :  * At main transaction abort, we release all locks including session locks.
     885                 :             :  *
     886                 :             :  * Advisory locks are released only if they are transaction-level;
     887                 :             :  * session-level holds remain, whether this is a commit or not.
     888                 :             :  *
     889                 :             :  * At subtransaction commit, we don't release any locks (so this func is not
     890                 :             :  * needed at all); we will defer the releasing to the parent transaction.
     891                 :             :  * At subtransaction abort, we release all locks held by the subtransaction;
     892                 :             :  * this is implemented by retail releasing of the locks under control of
     893                 :             :  * the ResourceOwner mechanism.
     894                 :             :  */
     895                 :             : void
     896                 :       57914 : ProcReleaseLocks(bool isCommit)
     897                 :             : {
     898         [ +  - ]:       57914 :         if (!MyProc)
     899                 :           0 :                 return;
     900                 :             :         /* If waiting, get off wait queue (should only be needed after error) */
     901                 :       57914 :         LockErrorCleanup();
     902                 :             :         /* Release standard locks, including session-level if aborting */
     903                 :       57914 :         LockReleaseAll(DEFAULT_LOCKMETHOD, !isCommit);
     904                 :             :         /* Release transaction-level advisory locks */
     905                 :       57914 :         LockReleaseAll(USER_LOCKMETHOD, false);
     906                 :       57914 : }
     907                 :             : 
     908                 :             : 
     909                 :             : /*
     910                 :             :  * RemoveProcFromArray() -- Remove this process from the shared ProcArray.
     911                 :             :  */
     912                 :             : static void
     913                 :         798 : RemoveProcFromArray(int code, Datum arg)
     914                 :             : {
     915         [ +  - ]:         798 :         Assert(MyProc != NULL);
     916                 :         798 :         ProcArrayRemove(MyProc, InvalidTransactionId);
     917                 :         798 : }
     918                 :             : 
     919                 :             : /*
     920                 :             :  * ProcKill() -- Destroy the per-proc data structure for
     921                 :             :  *              this process. Release any of its held LW locks.
     922                 :             :  */
     923                 :             : static void
     924                 :         798 : ProcKill(int code, Datum arg)
     925                 :             : {
     926                 :         798 :         PGPROC     *proc;
     927                 :         798 :         dlist_head *procgloballist;
     928                 :             : 
     929         [ +  - ]:         798 :         Assert(MyProc != NULL);
     930                 :             : 
     931                 :             :         /* not safe if forked by system(), etc. */
     932         [ +  - ]:         798 :         if (MyProc->pid != (int) getpid())
     933   [ #  #  #  # ]:           0 :                 elog(PANIC, "ProcKill() called in child process");
     934                 :             : 
     935                 :             :         /* Make sure we're out of the sync rep lists */
     936                 :         798 :         SyncRepCleanupAtProcExit();
     937                 :             : 
     938                 :             : #ifdef USE_ASSERT_CHECKING
     939                 :             :         {
     940                 :         798 :                 int                     i;
     941                 :             : 
     942                 :             :                 /* Last process should have released all locks. */
     943         [ +  + ]:       13566 :                 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
     944         [ +  - ]:       12768 :                         Assert(dlist_is_empty(&(MyProc->myProcLocks[i])));
     945                 :         798 :         }
     946                 :             : #endif
     947                 :             : 
     948                 :             :         /*
     949                 :             :          * Release any LW locks I am holding.  There really shouldn't be any, but
     950                 :             :          * it's cheap to check again before we cut the knees off the LWLock
     951                 :             :          * facility by releasing our PGPROC ...
     952                 :             :          */
     953                 :         798 :         LWLockReleaseAll();
     954                 :             : 
     955                 :             :         /*
     956                 :             :          * Cleanup waiting for LSN if any.
     957                 :             :          */
     958                 :         798 :         WaitLSNCleanup();
     959                 :             : 
     960                 :             :         /* Cancel any pending condition variable sleep, too */
     961                 :         798 :         ConditionVariableCancelSleep();
     962                 :             : 
     963                 :             :         /*
     964                 :             :          * Detach from any lock group of which we are a member.  If the leader
     965                 :             :          * exits before all other group members, its PGPROC will remain allocated
     966                 :             :          * until the last group process exits; that process must return the
     967                 :             :          * leader's PGPROC to the appropriate list.
     968                 :             :          */
     969         [ +  + ]:         798 :         if (MyProc->lockGroupLeader != NULL)
     970                 :             :         {
     971                 :         499 :                 PGPROC     *leader = MyProc->lockGroupLeader;
     972                 :         499 :                 LWLock     *leader_lwlock = LockHashPartitionLockByProc(leader);
     973                 :             : 
     974                 :         499 :                 LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
     975         [ +  - ]:         499 :                 Assert(!dlist_is_empty(&leader->lockGroupMembers));
     976                 :         499 :                 dlist_delete(&MyProc->lockGroupLink);
     977         [ +  + ]:         499 :                 if (dlist_is_empty(&leader->lockGroupMembers))
     978                 :             :                 {
     979                 :          22 :                         leader->lockGroupLeader = NULL;
     980         [ +  - ]:          22 :                         if (leader != MyProc)
     981                 :             :                         {
     982                 :           0 :                                 procgloballist = leader->procgloballist;
     983                 :             : 
     984                 :             :                                 /* Leader exited first; return its PGPROC. */
     985         [ #  # ]:           0 :                                 SpinLockAcquire(ProcStructLock);
     986                 :           0 :                                 dlist_push_head(procgloballist, &leader->links);
     987                 :           0 :                                 SpinLockRelease(ProcStructLock);
     988                 :           0 :                         }
     989                 :          22 :                 }
     990         [ +  - ]:         477 :                 else if (leader != MyProc)
     991                 :         477 :                         MyProc->lockGroupLeader = NULL;
     992                 :         499 :                 LWLockRelease(leader_lwlock);
     993                 :         499 :         }
     994                 :             : 
     995                 :             :         /*
     996                 :             :          * Reset MyLatch to the process local one.  This is so that signal
     997                 :             :          * handlers et al can continue using the latch after the shared latch
     998                 :             :          * isn't ours anymore.
     999                 :             :          *
    1000                 :             :          * Similarly, stop reporting wait events to MyProc->wait_event_info.
    1001                 :             :          *
    1002                 :             :          * After that clear MyProc and disown the shared latch.
    1003                 :             :          */
    1004                 :         798 :         SwitchBackToLocalLatch();
    1005                 :         798 :         pgstat_reset_wait_event_storage();
    1006                 :             : 
    1007                 :         798 :         proc = MyProc;
    1008                 :         798 :         MyProc = NULL;
    1009                 :         798 :         MyProcNumber = INVALID_PROC_NUMBER;
    1010                 :         798 :         DisownLatch(&proc->procLatch);
    1011                 :             : 
    1012                 :             :         /* Mark the proc no longer in use */
    1013                 :         798 :         proc->pid = 0;
    1014                 :         798 :         proc->vxid.procNumber = INVALID_PROC_NUMBER;
    1015                 :         798 :         proc->vxid.lxid = InvalidTransactionId;
    1016                 :             : 
    1017                 :         798 :         procgloballist = proc->procgloballist;
    1018         [ -  + ]:         798 :         SpinLockAcquire(ProcStructLock);
    1019                 :             : 
    1020                 :             :         /*
    1021                 :             :          * If we're still a member of a locking group, that means we're a leader
    1022                 :             :          * which has somehow exited before its children.  The last remaining child
    1023                 :             :          * will release our PGPROC.  Otherwise, release it now.
    1024                 :             :          */
    1025         [ -  + ]:         798 :         if (proc->lockGroupLeader == NULL)
    1026                 :             :         {
    1027                 :             :                 /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
    1028         [ +  - ]:         798 :                 Assert(dlist_is_empty(&proc->lockGroupMembers));
    1029                 :             : 
    1030                 :             :                 /* Return PGPROC structure (and semaphore) to appropriate freelist */
    1031                 :         798 :                 dlist_push_tail(procgloballist, &proc->links);
    1032                 :         798 :         }
    1033                 :             : 
    1034                 :             :         /* Update shared estimate of spins_per_delay */
    1035                 :         798 :         ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);
    1036                 :             : 
    1037                 :         798 :         SpinLockRelease(ProcStructLock);
    1038                 :         798 : }
    1039                 :             : 
    1040                 :             : /*
    1041                 :             :  * AuxiliaryProcKill() -- Cut-down version of ProcKill for auxiliary
    1042                 :             :  *              processes (bgwriter, etc).  The PGPROC and sema are not released, only
    1043                 :             :  *              marked as not-in-use.
    1044                 :             :  */
    1045                 :             : static void
    1046                 :           8 : AuxiliaryProcKill(int code, Datum arg)
    1047                 :             : {
    1048                 :           8 :         int                     proctype = DatumGetInt32(arg);
    1049                 :           8 :         PGPROC     *auxproc PG_USED_FOR_ASSERTS_ONLY;
    1050                 :           8 :         PGPROC     *proc;
    1051                 :             : 
    1052         [ +  - ]:           8 :         Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
    1053                 :             : 
    1054                 :             :         /* not safe if forked by system(), etc. */
    1055         [ +  - ]:           8 :         if (MyProc->pid != (int) getpid())
    1056   [ #  #  #  # ]:           0 :                 elog(PANIC, "AuxiliaryProcKill() called in child process");
    1057                 :             : 
    1058                 :           8 :         auxproc = &AuxiliaryProcs[proctype];
    1059                 :             : 
    1060         [ +  - ]:           8 :         Assert(MyProc == auxproc);
    1061                 :             : 
    1062                 :             :         /* Release any LW locks I am holding (see notes above) */
    1063                 :           8 :         LWLockReleaseAll();
    1064                 :             : 
    1065                 :             :         /* Cancel any pending condition variable sleep, too */
    1066                 :           8 :         ConditionVariableCancelSleep();
    1067                 :             : 
    1068                 :             :         /* look at the equivalent ProcKill() code for comments */
    1069                 :           8 :         SwitchBackToLocalLatch();
    1070                 :           8 :         pgstat_reset_wait_event_storage();
    1071                 :             : 
    1072                 :           8 :         proc = MyProc;
    1073                 :           8 :         MyProc = NULL;
    1074                 :           8 :         MyProcNumber = INVALID_PROC_NUMBER;
    1075                 :           8 :         DisownLatch(&proc->procLatch);
    1076                 :             : 
    1077         [ -  + ]:           8 :         SpinLockAcquire(ProcStructLock);
    1078                 :             : 
    1079                 :             :         /* Mark auxiliary proc no longer in use */
    1080                 :           8 :         proc->pid = 0;
    1081                 :           8 :         proc->vxid.procNumber = INVALID_PROC_NUMBER;
    1082                 :           8 :         proc->vxid.lxid = InvalidTransactionId;
    1083                 :             : 
    1084                 :             :         /* Update shared estimate of spins_per_delay */
    1085                 :           8 :         ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);
    1086                 :             : 
    1087                 :           8 :         SpinLockRelease(ProcStructLock);
    1088                 :           8 : }
    1089                 :             : 
    1090                 :             : /*
    1091                 :             :  * AuxiliaryPidGetProc -- get PGPROC for an auxiliary process
    1092                 :             :  * given its PID
    1093                 :             :  *
    1094                 :             :  * Returns NULL if not found.
    1095                 :             :  */
    1096                 :             : PGPROC *
    1097                 :          33 : AuxiliaryPidGetProc(int pid)
    1098                 :             : {
    1099                 :          33 :         PGPROC     *result = NULL;
    1100                 :          33 :         int                     index;
    1101                 :             : 
    1102         [ +  + ]:          33 :         if (pid == 0)                           /* never match dummy PGPROCs */
    1103                 :           1 :                 return NULL;
    1104                 :             : 
    1105         [ -  + ]:         109 :         for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
    1106                 :             :         {
    1107                 :         109 :                 PGPROC     *proc = &AuxiliaryProcs[index];
    1108                 :             : 
    1109         [ +  + ]:         109 :                 if (proc->pid == pid)
    1110                 :             :                 {
    1111                 :          32 :                         result = proc;
    1112                 :          32 :                         break;
    1113                 :             :                 }
    1114      [ -  +  + ]:         109 :         }
    1115                 :          32 :         return result;
    1116                 :          33 : }
    1117                 :             : 
    1118                 :             : 
    1119                 :             : /*
    1120                 :             :  * JoinWaitQueue -- join the wait queue on the specified lock
    1121                 :             :  *
    1122                 :             :  * It's not actually guaranteed that we need to wait when this function is
    1123                 :             :  * called, because it could be that when we try to find a position at which
    1124                 :             :  * to insert ourself into the wait queue, we discover that we must be inserted
    1125                 :             :  * ahead of everyone who wants a lock that conflict with ours. In that case,
    1126                 :             :  * we get the lock immediately. Because of this, it's sensible for this function
    1127                 :             :  * to have a dontWait argument, despite the name.
    1128                 :             :  *
    1129                 :             :  * On entry, the caller has already set up LOCK and PROCLOCK entries to
    1130                 :             :  * reflect that we have "requested" the lock.  The caller is responsible for
    1131                 :             :  * cleaning that up, if we end up not joining the queue after all.
    1132                 :             :  *
    1133                 :             :  * The lock table's partition lock must be held at entry, and is still held
    1134                 :             :  * at exit.  The caller must release it before calling ProcSleep().
    1135                 :             :  *
    1136                 :             :  * Result is one of the following:
    1137                 :             :  *
    1138                 :             :  *  PROC_WAIT_STATUS_OK       - lock was immediately granted
    1139                 :             :  *  PROC_WAIT_STATUS_WAITING  - joined the wait queue; call ProcSleep()
    1140                 :             :  *  PROC_WAIT_STATUS_ERROR    - immediate deadlock was detected, or would
    1141                 :             :  *                              need to wait and dontWait == true
    1142                 :             :  *
    1143                 :             :  * NOTES: The process queue is now a priority queue for locking.
    1144                 :             :  */
    1145                 :             : ProcWaitStatus
    1146                 :          57 : JoinWaitQueue(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
    1147                 :             : {
    1148                 :          57 :         LOCKMODE        lockmode = locallock->tag.mode;
    1149                 :          57 :         LOCK       *lock = locallock->lock;
    1150                 :          57 :         PROCLOCK   *proclock = locallock->proclock;
    1151                 :          57 :         uint32          hashcode = locallock->hashcode;
    1152                 :          57 :         LWLock     *partitionLock PG_USED_FOR_ASSERTS_ONLY = LockHashPartitionLock(hashcode);
    1153                 :          57 :         dclist_head *waitQueue = &lock->waitProcs;
    1154                 :          57 :         PGPROC     *insert_before = NULL;
    1155                 :          57 :         LOCKMASK        myProcHeldLocks;
    1156                 :          57 :         LOCKMASK        myHeldLocks;
    1157                 :          57 :         bool            early_deadlock = false;
    1158                 :          57 :         PGPROC     *leader = MyProc->lockGroupLeader;
    1159                 :             : 
    1160         [ +  - ]:          57 :         Assert(LWLockHeldByMeInMode(partitionLock, LW_EXCLUSIVE));
    1161                 :             : 
    1162                 :             :         /*
    1163                 :             :          * Set bitmask of locks this process already holds on this object.
    1164                 :             :          */
    1165                 :          57 :         myHeldLocks = MyProc->heldLocks = proclock->holdMask;
    1166                 :             : 
    1167                 :             :         /*
    1168                 :             :          * Determine which locks we're already holding.
    1169                 :             :          *
    1170                 :             :          * If group locking is in use, locks held by members of my locking group
    1171                 :             :          * need to be included in myHeldLocks.  This is not required for relation
    1172                 :             :          * extension lock which conflict among group members. However, including
    1173                 :             :          * them in myHeldLocks will give group members the priority to get those
    1174                 :             :          * locks as compared to other backends which are also trying to acquire
    1175                 :             :          * those locks.  OTOH, we can avoid giving priority to group members for
    1176                 :             :          * that kind of locks, but there doesn't appear to be a clear advantage of
    1177                 :             :          * the same.
    1178                 :             :          */
    1179                 :          57 :         myProcHeldLocks = proclock->holdMask;
    1180                 :          57 :         myHeldLocks = myProcHeldLocks;
    1181         [ +  + ]:          57 :         if (leader != NULL)
    1182                 :             :         {
    1183                 :           1 :                 dlist_iter      iter;
    1184                 :             : 
    1185   [ +  -  +  + ]:           3 :                 dlist_foreach(iter, &lock->procLocks)
    1186                 :             :                 {
    1187                 :           2 :                         PROCLOCK   *otherproclock;
    1188                 :             : 
    1189                 :           2 :                         otherproclock = dlist_container(PROCLOCK, lockLink, iter.cur);
    1190                 :             : 
    1191         [ +  + ]:           2 :                         if (otherproclock->groupLeader == leader)
    1192                 :           1 :                                 myHeldLocks |= otherproclock->holdMask;
    1193                 :           2 :                 }
    1194                 :           1 :         }
    1195                 :             : 
    1196                 :             :         /*
    1197                 :             :          * Determine where to add myself in the wait queue.
    1198                 :             :          *
    1199                 :             :          * Normally I should go at the end of the queue.  However, if I already
    1200                 :             :          * hold locks that conflict with the request of any previous waiter, put
    1201                 :             :          * myself in the queue just in front of the first such waiter. This is not
    1202                 :             :          * a necessary step, since deadlock detection would move me to before that
    1203                 :             :          * waiter anyway; but it's relatively cheap to detect such a conflict
    1204                 :             :          * immediately, and avoid delaying till deadlock timeout.
    1205                 :             :          *
    1206                 :             :          * Special case: if I find I should go in front of some waiter, check to
    1207                 :             :          * see if I conflict with already-held locks or the requests before that
    1208                 :             :          * waiter.  If not, then just grant myself the requested lock immediately.
    1209                 :             :          * This is the same as the test for immediate grant in LockAcquire, except
    1210                 :             :          * we are only considering the part of the wait queue before my insertion
    1211                 :             :          * point.
    1212                 :             :          */
    1213   [ +  +  -  + ]:          57 :         if (myHeldLocks != 0 && !dclist_is_empty(waitQueue))
    1214                 :             :         {
    1215                 :          14 :                 LOCKMASK        aheadRequests = 0;
    1216                 :          14 :                 dlist_iter      iter;
    1217                 :             : 
    1218   [ +  -  -  + ]:          14 :                 dclist_foreach(iter, waitQueue)
    1219                 :             :                 {
    1220                 :          14 :                         PGPROC     *proc = dlist_container(PGPROC, links, iter.cur);
    1221                 :             : 
    1222                 :             :                         /*
    1223                 :             :                          * If we're part of the same locking group as this waiter, its
    1224                 :             :                          * locks neither conflict with ours nor contribute to
    1225                 :             :                          * aheadRequests.
    1226                 :             :                          */
    1227   [ -  +  #  # ]:          14 :                         if (leader != NULL && leader == proc->lockGroupLeader)
    1228                 :           0 :                                 continue;
    1229                 :             : 
    1230                 :             :                         /* Must he wait for me? */
    1231         [ +  - ]:          14 :                         if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
    1232                 :             :                         {
    1233                 :             :                                 /* Must I wait for him ? */
    1234         [ -  + ]:          14 :                                 if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
    1235                 :             :                                 {
    1236                 :             :                                         /*
    1237                 :             :                                          * Yes, so we have a deadlock.  Easiest way to clean up
    1238                 :             :                                          * correctly is to call RemoveFromWaitQueue(), but we
    1239                 :             :                                          * can't do that until we are *on* the wait queue. So, set
    1240                 :             :                                          * a flag to check below, and break out of loop.  Also,
    1241                 :             :                                          * record deadlock info for later message.
    1242                 :             :                                          */
    1243                 :           0 :                                         RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
    1244                 :           0 :                                         early_deadlock = true;
    1245                 :           0 :                                         break;
    1246                 :             :                                 }
    1247                 :             :                                 /* I must go before this waiter.  Check special case. */
    1248   [ +  -  -  + ]:          14 :                                 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
    1249                 :          28 :                                         !LockCheckConflicts(lockMethodTable, lockmode, lock,
    1250                 :          14 :                                                                                 proclock))
    1251                 :             :                                 {
    1252                 :             :                                         /* Skip the wait and just grant myself the lock. */
    1253                 :          14 :                                         GrantLock(lock, proclock, lockmode);
    1254                 :          14 :                                         return PROC_WAIT_STATUS_OK;
    1255                 :             :                                 }
    1256                 :             : 
    1257                 :             :                                 /* Put myself into wait queue before conflicting process */
    1258                 :           0 :                                 insert_before = proc;
    1259                 :           0 :                                 break;
    1260                 :             :                         }
    1261                 :             :                         /* Nope, so advance to next waiter */
    1262                 :           0 :                         aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
    1263   [ -  -  +  - ]:          14 :                 }
    1264         [ +  - ]:          14 :         }
    1265                 :             : 
    1266                 :             :         /*
    1267                 :             :          * If we detected deadlock, give up without waiting.  This must agree with
    1268                 :             :          * CheckDeadLock's recovery code.
    1269                 :             :          */
    1270         [ -  + ]:          43 :         if (early_deadlock)
    1271                 :           0 :                 return PROC_WAIT_STATUS_ERROR;
    1272                 :             : 
    1273                 :             :         /*
    1274                 :             :          * At this point we know that we'd really need to sleep. If we've been
    1275                 :             :          * commanded not to do that, bail out.
    1276                 :             :          */
    1277         [ -  + ]:          43 :         if (dontWait)
    1278                 :           0 :                 return PROC_WAIT_STATUS_ERROR;
    1279                 :             : 
    1280                 :             :         /*
    1281                 :             :          * Insert self into queue, at the position determined above.
    1282                 :             :          */
    1283         [ -  + ]:          43 :         if (insert_before)
    1284                 :           0 :                 dclist_insert_before(waitQueue, &insert_before->links, &MyProc->links);
    1285                 :             :         else
    1286                 :          43 :                 dclist_push_tail(waitQueue, &MyProc->links);
    1287                 :             : 
    1288                 :          43 :         lock->waitMask |= LOCKBIT_ON(lockmode);
    1289                 :             : 
    1290                 :             :         /* Set up wait information in PGPROC object, too */
    1291                 :          43 :         MyProc->heldLocks = myProcHeldLocks;
    1292                 :          43 :         MyProc->waitLock = lock;
    1293                 :          43 :         MyProc->waitProcLock = proclock;
    1294                 :          43 :         MyProc->waitLockMode = lockmode;
    1295                 :             : 
    1296                 :          43 :         MyProc->waitStatus = PROC_WAIT_STATUS_WAITING;
    1297                 :             : 
    1298                 :          43 :         return PROC_WAIT_STATUS_WAITING;
    1299                 :          57 : }
    1300                 :             : 
    1301                 :             : /*
    1302                 :             :  * ProcSleep -- put process to sleep waiting on lock
    1303                 :             :  *
    1304                 :             :  * This must be called when JoinWaitQueue() returns PROC_WAIT_STATUS_WAITING.
    1305                 :             :  * Returns after the lock has been granted, or if a deadlock is detected.  Can
    1306                 :             :  * also bail out with ereport(ERROR), if some other error condition, or a
    1307                 :             :  * timeout or cancellation is triggered.
    1308                 :             :  *
    1309                 :             :  * Result is one of the following:
    1310                 :             :  *
    1311                 :             :  *  PROC_WAIT_STATUS_OK      - lock was granted
    1312                 :             :  *  PROC_WAIT_STATUS_ERROR   - a deadlock was detected
    1313                 :             :  */
    1314                 :             : ProcWaitStatus
    1315                 :          43 : ProcSleep(LOCALLOCK *locallock)
    1316                 :             : {
    1317                 :          43 :         LOCKMODE        lockmode = locallock->tag.mode;
    1318                 :          43 :         LOCK       *lock = locallock->lock;
    1319                 :          43 :         uint32          hashcode = locallock->hashcode;
    1320                 :          43 :         LWLock     *partitionLock = LockHashPartitionLock(hashcode);
    1321                 :          43 :         TimestampTz standbyWaitStart = 0;
    1322                 :          43 :         bool            allow_autovacuum_cancel = true;
    1323                 :          43 :         bool            logged_recovery_conflict = false;
    1324                 :          43 :         ProcWaitStatus myWaitStatus;
    1325                 :             : 
    1326                 :             :         /* The caller must've armed the on-error cleanup mechanism */
    1327         [ +  - ]:          43 :         Assert(GetAwaitedLock() == locallock);
    1328         [ +  - ]:          43 :         Assert(!LWLockHeldByMe(partitionLock));
    1329                 :             : 
    1330                 :             :         /*
    1331                 :             :          * Now that we will successfully clean up after an ereport, it's safe to
    1332                 :             :          * check to see if there's a buffer pin deadlock against the Startup
    1333                 :             :          * process.  Of course, that's only necessary if we're doing Hot Standby
    1334                 :             :          * and are not the Startup process ourselves.
    1335                 :             :          */
    1336   [ -  +  #  # ]:          43 :         if (RecoveryInProgress() && !InRecovery)
    1337                 :           0 :                 CheckRecoveryConflictDeadlock();
    1338                 :             : 
    1339                 :             :         /* Reset deadlock_state before enabling the timeout handler */
    1340                 :          43 :         deadlock_state = DS_NOT_YET_CHECKED;
    1341                 :          43 :         got_deadlock_timeout = false;
    1342                 :             : 
    1343                 :             :         /*
    1344                 :             :          * Set timer so we can wake up after awhile and check for a deadlock. If a
    1345                 :             :          * deadlock is detected, the handler sets MyProc->waitStatus =
    1346                 :             :          * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
    1347                 :             :          * rather than success.
    1348                 :             :          *
    1349                 :             :          * By delaying the check until we've waited for a bit, we can avoid
    1350                 :             :          * running the rather expensive deadlock-check code in most cases.
    1351                 :             :          *
    1352                 :             :          * If LockTimeout is set, also enable the timeout for that.  We can save a
    1353                 :             :          * few cycles by enabling both timeout sources in one call.
    1354                 :             :          *
    1355                 :             :          * If InHotStandby we set lock waits slightly later for clarity with other
    1356                 :             :          * code.
    1357                 :             :          */
    1358         [ -  + ]:          43 :         if (!InHotStandby)
    1359                 :             :         {
    1360         [ -  + ]:          43 :                 if (LockTimeout > 0)
    1361                 :             :                 {
    1362                 :           0 :                         EnableTimeoutParams timeouts[2];
    1363                 :             : 
    1364                 :           0 :                         timeouts[0].id = DEADLOCK_TIMEOUT;
    1365                 :           0 :                         timeouts[0].type = TMPARAM_AFTER;
    1366                 :           0 :                         timeouts[0].delay_ms = DeadlockTimeout;
    1367                 :           0 :                         timeouts[1].id = LOCK_TIMEOUT;
    1368                 :           0 :                         timeouts[1].type = TMPARAM_AFTER;
    1369                 :           0 :                         timeouts[1].delay_ms = LockTimeout;
    1370                 :           0 :                         enable_timeouts(timeouts, 2);
    1371                 :           0 :                 }
    1372                 :             :                 else
    1373                 :          43 :                         enable_timeout_after(DEADLOCK_TIMEOUT, DeadlockTimeout);
    1374                 :             : 
    1375                 :             :                 /*
    1376                 :             :                  * Use the current time obtained for the deadlock timeout timer as
    1377                 :             :                  * waitStart (i.e., the time when this process started waiting for the
    1378                 :             :                  * lock). Since getting the current time newly can cause overhead, we
    1379                 :             :                  * reuse the already-obtained time to avoid that overhead.
    1380                 :             :                  *
    1381                 :             :                  * Note that waitStart is updated without holding the lock table's
    1382                 :             :                  * partition lock, to avoid the overhead by additional lock
    1383                 :             :                  * acquisition. This can cause "waitstart" in pg_locks to become NULL
    1384                 :             :                  * for a very short period of time after the wait started even though
    1385                 :             :                  * "granted" is false. This is OK in practice because we can assume
    1386                 :             :                  * that users are likely to look at "waitstart" when waiting for the
    1387                 :             :                  * lock for a long time.
    1388                 :             :                  */
    1389                 :          86 :                 pg_atomic_write_u64(&MyProc->waitStart,
    1390                 :          43 :                                                         get_timeout_start_time(DEADLOCK_TIMEOUT));
    1391                 :          43 :         }
    1392         [ #  # ]:           0 :         else if (log_recovery_conflict_waits)
    1393                 :             :         {
    1394                 :             :                 /*
    1395                 :             :                  * Set the wait start timestamp if logging is enabled and in hot
    1396                 :             :                  * standby.
    1397                 :             :                  */
    1398                 :           0 :                 standbyWaitStart = GetCurrentTimestamp();
    1399                 :           0 :         }
    1400                 :             : 
    1401                 :             :         /*
    1402                 :             :          * If somebody wakes us between LWLockRelease and WaitLatch, the latch
    1403                 :             :          * will not wait. But a set latch does not necessarily mean that the lock
    1404                 :             :          * is free now, as there are many other sources for latch sets than
    1405                 :             :          * somebody releasing the lock.
    1406                 :             :          *
    1407                 :             :          * We process interrupts whenever the latch has been set, so cancel/die
    1408                 :             :          * interrupts are processed quickly. This means we must not mind losing
    1409                 :             :          * control to a cancel/die interrupt here.  We don't, because we have no
    1410                 :             :          * shared-state-change work to do after being granted the lock (the
    1411                 :             :          * grantor did it all).  We do have to worry about canceling the deadlock
    1412                 :             :          * timeout and updating the locallock table, but if we lose control to an
    1413                 :             :          * error, LockErrorCleanup will fix that up.
    1414                 :             :          */
    1415                 :          43 :         do
    1416                 :             :         {
    1417         [ -  + ]:          49 :                 if (InHotStandby)
    1418                 :             :                 {
    1419                 :           0 :                         bool            maybe_log_conflict =
    1420         [ #  # ]:           0 :                                 (standbyWaitStart != 0 && !logged_recovery_conflict);
    1421                 :             : 
    1422                 :             :                         /* Set a timer and wait for that or for the lock to be granted */
    1423                 :           0 :                         ResolveRecoveryConflictWithLock(locallock->tag.lock,
    1424                 :           0 :                                                                                         maybe_log_conflict);
    1425                 :             : 
    1426                 :             :                         /*
    1427                 :             :                          * Emit the log message if the startup process is waiting longer
    1428                 :             :                          * than deadlock_timeout for recovery conflict on lock.
    1429                 :             :                          */
    1430         [ #  # ]:           0 :                         if (maybe_log_conflict)
    1431                 :             :                         {
    1432                 :           0 :                                 TimestampTz now = GetCurrentTimestamp();
    1433                 :             : 
    1434   [ #  #  #  # ]:           0 :                                 if (TimestampDifferenceExceeds(standbyWaitStart, now,
    1435                 :           0 :                                                                                            DeadlockTimeout))
    1436                 :             :                                 {
    1437                 :           0 :                                         VirtualTransactionId *vxids;
    1438                 :           0 :                                         int                     cnt;
    1439                 :             : 
    1440                 :           0 :                                         vxids = GetLockConflicts(&locallock->tag.lock,
    1441                 :             :                                                                                          AccessExclusiveLock, &cnt);
    1442                 :             : 
    1443                 :             :                                         /*
    1444                 :             :                                          * Log the recovery conflict and the list of PIDs of
    1445                 :             :                                          * backends holding the conflicting lock. Note that we do
    1446                 :             :                                          * logging even if there are no such backends right now
    1447                 :             :                                          * because the startup process here has already waited
    1448                 :             :                                          * longer than deadlock_timeout.
    1449                 :             :                                          */
    1450                 :           0 :                                         LogRecoveryConflict(PROCSIG_RECOVERY_CONFLICT_LOCK,
    1451                 :           0 :                                                                                 standbyWaitStart, now,
    1452         [ #  # ]:           0 :                                                                                 cnt > 0 ? vxids : NULL, true);
    1453                 :           0 :                                         logged_recovery_conflict = true;
    1454                 :           0 :                                 }
    1455                 :           0 :                         }
    1456                 :           0 :                 }
    1457                 :             :                 else
    1458                 :             :                 {
    1459                 :          98 :                         (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
    1460                 :          49 :                                                          PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
    1461                 :          49 :                         ResetLatch(MyLatch);
    1462                 :             :                         /* check for deadlocks first, as that's probably log-worthy */
    1463         [ +  + ]:          49 :                         if (got_deadlock_timeout)
    1464                 :             :                         {
    1465                 :           2 :                                 CheckDeadLock();
    1466                 :           2 :                                 got_deadlock_timeout = false;
    1467                 :           2 :                         }
    1468         [ +  + ]:          49 :                         CHECK_FOR_INTERRUPTS();
    1469                 :             :                 }
    1470                 :             : 
    1471                 :             :                 /*
    1472                 :             :                  * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
    1473                 :             :                  * else asynchronously.  Read it just once per loop to prevent
    1474                 :             :                  * surprising behavior (such as missing log messages).
    1475                 :             :                  */
    1476                 :          49 :                 myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
    1477                 :             : 
    1478                 :             :                 /*
    1479                 :             :                  * If we are not deadlocked, but are waiting on an autovacuum-induced
    1480                 :             :                  * task, send a signal to interrupt it.
    1481                 :             :                  */
    1482   [ -  +  #  # ]:          49 :                 if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
    1483                 :             :                 {
    1484                 :           0 :                         PGPROC     *autovac = GetBlockingAutoVacuumPgproc();
    1485                 :           0 :                         uint8           statusFlags;
    1486                 :           0 :                         uint8           lockmethod_copy;
    1487                 :           0 :                         LOCKTAG         locktag_copy;
    1488                 :             : 
    1489                 :             :                         /*
    1490                 :             :                          * Grab info we need, then release lock immediately.  Note this
    1491                 :             :                          * coding means that there is a tiny chance that the process
    1492                 :             :                          * terminates its current transaction and starts a different one
    1493                 :             :                          * before we have a change to send the signal; the worst possible
    1494                 :             :                          * consequence is that a for-wraparound vacuum is canceled.  But
    1495                 :             :                          * that could happen in any case unless we were to do kill() with
    1496                 :             :                          * the lock held, which is much more undesirable.
    1497                 :             :                          */
    1498                 :           0 :                         LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
    1499                 :           0 :                         statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
    1500                 :           0 :                         lockmethod_copy = lock->tag.locktag_lockmethodid;
    1501                 :           0 :                         locktag_copy = lock->tag;
    1502                 :           0 :                         LWLockRelease(ProcArrayLock);
    1503                 :             : 
    1504                 :             :                         /*
    1505                 :             :                          * Only do it if the worker is not working to protect against Xid
    1506                 :             :                          * wraparound.
    1507                 :             :                          */
    1508   [ #  #  #  # ]:           0 :                         if ((statusFlags & PROC_IS_AUTOVACUUM) &&
    1509                 :           0 :                                 !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
    1510                 :             :                         {
    1511                 :           0 :                                 int                     pid = autovac->pid;
    1512                 :             : 
    1513                 :             :                                 /* report the case, if configured to do so */
    1514         [ #  # ]:           0 :                                 if (message_level_is_interesting(DEBUG1))
    1515                 :             :                                 {
    1516                 :           0 :                                         StringInfoData locktagbuf;
    1517                 :           0 :                                         StringInfoData logbuf;  /* errdetail for server log */
    1518                 :             : 
    1519                 :           0 :                                         initStringInfo(&locktagbuf);
    1520                 :           0 :                                         initStringInfo(&logbuf);
    1521                 :           0 :                                         DescribeLockTag(&locktagbuf, &locktag_copy);
    1522                 :           0 :                                         appendStringInfo(&logbuf,
    1523                 :             :                                                                          "Process %d waits for %s on %s.",
    1524                 :           0 :                                                                          MyProcPid,
    1525                 :           0 :                                                                          GetLockmodeName(lockmethod_copy, lockmode),
    1526                 :           0 :                                                                          locktagbuf.data);
    1527                 :             : 
    1528   [ #  #  #  # ]:           0 :                                         ereport(DEBUG1,
    1529                 :             :                                                         (errmsg_internal("sending cancel to blocking autovacuum PID %d",
    1530                 :             :                                                                                          pid),
    1531                 :             :                                                          errdetail_log("%s", logbuf.data)));
    1532                 :             : 
    1533                 :           0 :                                         pfree(locktagbuf.data);
    1534                 :           0 :                                         pfree(logbuf.data);
    1535                 :           0 :                                 }
    1536                 :             : 
    1537                 :             :                                 /* send the autovacuum worker Back to Old Kent Road */
    1538         [ #  # ]:           0 :                                 if (kill(pid, SIGINT) < 0)
    1539                 :             :                                 {
    1540                 :             :                                         /*
    1541                 :             :                                          * There's a race condition here: once we release the
    1542                 :             :                                          * ProcArrayLock, it's possible for the autovac worker to
    1543                 :             :                                          * close up shop and exit before we can do the kill().
    1544                 :             :                                          * Therefore, we do not whinge about no-such-process.
    1545                 :             :                                          * Other errors such as EPERM could conceivably happen if
    1546                 :             :                                          * the kernel recycles the PID fast enough, but such cases
    1547                 :             :                                          * seem improbable enough that it's probably best to issue
    1548                 :             :                                          * a warning if we see some other errno.
    1549                 :             :                                          */
    1550         [ #  # ]:           0 :                                         if (errno != ESRCH)
    1551   [ #  #  #  # ]:           0 :                                                 ereport(WARNING,
    1552                 :             :                                                                 (errmsg("could not send signal to process %d: %m",
    1553                 :             :                                                                                 pid)));
    1554                 :           0 :                                 }
    1555                 :           0 :                         }
    1556                 :             : 
    1557                 :             :                         /* prevent signal from being sent again more than once */
    1558                 :           0 :                         allow_autovacuum_cancel = false;
    1559                 :           0 :                 }
    1560                 :             : 
    1561                 :             :                 /*
    1562                 :             :                  * If awoken after the deadlock check interrupt has run, and
    1563                 :             :                  * log_lock_waits is on, then report about the wait.
    1564                 :             :                  */
    1565   [ +  -  +  + ]:          49 :                 if (log_lock_waits && deadlock_state != DS_NOT_YET_CHECKED)
    1566                 :             :                 {
    1567                 :           4 :                         StringInfoData buf,
    1568                 :             :                                                 lock_waiters_sbuf,
    1569                 :             :                                                 lock_holders_sbuf;
    1570                 :           4 :                         const char *modename;
    1571                 :           4 :                         long            secs;
    1572                 :           4 :                         int                     usecs;
    1573                 :           4 :                         long            msecs;
    1574                 :           4 :                         int                     lockHoldersNum = 0;
    1575                 :             : 
    1576                 :           4 :                         initStringInfo(&buf);
    1577                 :           4 :                         initStringInfo(&lock_waiters_sbuf);
    1578                 :           4 :                         initStringInfo(&lock_holders_sbuf);
    1579                 :             : 
    1580                 :           4 :                         DescribeLockTag(&buf, &locallock->tag.lock);
    1581                 :           8 :                         modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
    1582                 :           4 :                                                                            lockmode);
    1583                 :           8 :                         TimestampDifference(get_timeout_start_time(DEADLOCK_TIMEOUT),
    1584                 :           4 :                                                                 GetCurrentTimestamp(),
    1585                 :             :                                                                 &secs, &usecs);
    1586                 :           4 :                         msecs = secs * 1000 + usecs / 1000;
    1587                 :           4 :                         usecs = usecs % 1000;
    1588                 :             : 
    1589                 :             :                         /* Gather a list of all lock holders and waiters */
    1590                 :           4 :                         LWLockAcquire(partitionLock, LW_SHARED);
    1591                 :           4 :                         GetLockHoldersAndWaiters(locallock, &lock_holders_sbuf,
    1592                 :             :                                                                          &lock_waiters_sbuf, &lockHoldersNum);
    1593                 :           4 :                         LWLockRelease(partitionLock);
    1594                 :             : 
    1595         [ -  + ]:           4 :                         if (deadlock_state == DS_SOFT_DEADLOCK)
    1596   [ #  #  #  # ]:           0 :                                 ereport(LOG,
    1597                 :             :                                                 (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
    1598                 :             :                                                                 MyProcPid, modename, buf.data, msecs, usecs),
    1599                 :             :                                                  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
    1600                 :             :                                                                                            "Processes holding the lock: %s. Wait queue: %s.",
    1601                 :             :                                                                                            lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
    1602         [ +  - ]:           4 :                         else if (deadlock_state == DS_HARD_DEADLOCK)
    1603                 :             :                         {
    1604                 :             :                                 /*
    1605                 :             :                                  * This message is a bit redundant with the error that will be
    1606                 :             :                                  * reported subsequently, but in some cases the error report
    1607                 :             :                                  * might not make it to the log (eg, if it's caught by an
    1608                 :             :                                  * exception handler), and we want to ensure all long-wait
    1609                 :             :                                  * events get logged.
    1610                 :             :                                  */
    1611   [ #  #  #  # ]:           0 :                                 ereport(LOG,
    1612                 :             :                                                 (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
    1613                 :             :                                                                 MyProcPid, modename, buf.data, msecs, usecs),
    1614                 :             :                                                  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
    1615                 :             :                                                                                            "Processes holding the lock: %s. Wait queue: %s.",
    1616                 :             :                                                                                            lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
    1617                 :           0 :                         }
    1618                 :             : 
    1619         [ +  + ]:           4 :                         if (myWaitStatus == PROC_WAIT_STATUS_WAITING)
    1620   [ -  +  +  - ]:           2 :                                 ereport(LOG,
    1621                 :             :                                                 (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
    1622                 :             :                                                                 MyProcPid, modename, buf.data, msecs, usecs),
    1623                 :             :                                                  (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
    1624                 :             :                                                                                            "Processes holding the lock: %s. Wait queue: %s.",
    1625                 :             :                                                                                            lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
    1626         [ -  + ]:           2 :                         else if (myWaitStatus == PROC_WAIT_STATUS_OK)
    1627   [ -  +  +  - ]:           2 :                                 ereport(LOG,
    1628                 :             :                                                 (errmsg("process %d acquired %s on %s after %ld.%03d ms",
    1629                 :             :                                                                 MyProcPid, modename, buf.data, msecs, usecs)));
    1630                 :             :                         else
    1631                 :             :                         {
    1632         [ #  # ]:           0 :                                 Assert(myWaitStatus == PROC_WAIT_STATUS_ERROR);
    1633                 :             : 
    1634                 :             :                                 /*
    1635                 :             :                                  * Currently, the deadlock checker always kicks its own
    1636                 :             :                                  * process, which means that we'll only see
    1637                 :             :                                  * PROC_WAIT_STATUS_ERROR when deadlock_state ==
    1638                 :             :                                  * DS_HARD_DEADLOCK, and there's no need to print redundant
    1639                 :             :                                  * messages.  But for completeness and future-proofing, print
    1640                 :             :                                  * a message if it looks like someone else kicked us off the
    1641                 :             :                                  * lock.
    1642                 :             :                                  */
    1643         [ #  # ]:           0 :                                 if (deadlock_state != DS_HARD_DEADLOCK)
    1644   [ #  #  #  # ]:           0 :                                         ereport(LOG,
    1645                 :             :                                                         (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
    1646                 :             :                                                                         MyProcPid, modename, buf.data, msecs, usecs),
    1647                 :             :                                                          (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
    1648                 :             :                                                                                                    "Processes holding the lock: %s. Wait queue: %s.",
    1649                 :             :                                                                                                    lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
    1650                 :             :                         }
    1651                 :             : 
    1652                 :             :                         /*
    1653                 :             :                          * At this point we might still need to wait for the lock. Reset
    1654                 :             :                          * state so we don't print the above messages again.
    1655                 :             :                          */
    1656                 :           4 :                         deadlock_state = DS_NO_DEADLOCK;
    1657                 :             : 
    1658                 :           4 :                         pfree(buf.data);
    1659                 :           4 :                         pfree(lock_holders_sbuf.data);
    1660                 :           4 :                         pfree(lock_waiters_sbuf.data);
    1661                 :           4 :                 }
    1662         [ +  + ]:          49 :         } while (myWaitStatus == PROC_WAIT_STATUS_WAITING);
    1663                 :             : 
    1664                 :             :         /*
    1665                 :             :          * Disable the timers, if they are still running.  As in LockErrorCleanup,
    1666                 :             :          * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
    1667                 :             :          * already caused QueryCancelPending to become set, we want the cancel to
    1668                 :             :          * be reported as a lock timeout, not a user cancel.
    1669                 :             :          */
    1670         [ +  + ]:          43 :         if (!InHotStandby)
    1671                 :             :         {
    1672         [ -  + ]:          42 :                 if (LockTimeout > 0)
    1673                 :             :                 {
    1674                 :           0 :                         DisableTimeoutParams timeouts[2];
    1675                 :             : 
    1676                 :           0 :                         timeouts[0].id = DEADLOCK_TIMEOUT;
    1677                 :           0 :                         timeouts[0].keep_indicator = false;
    1678                 :           0 :                         timeouts[1].id = LOCK_TIMEOUT;
    1679                 :           0 :                         timeouts[1].keep_indicator = true;
    1680                 :           0 :                         disable_timeouts(timeouts, 2);
    1681                 :           0 :                 }
    1682                 :             :                 else
    1683                 :          42 :                         disable_timeout(DEADLOCK_TIMEOUT, false);
    1684                 :          42 :         }
    1685                 :             : 
    1686                 :             :         /*
    1687                 :             :          * Emit the log message if recovery conflict on lock was resolved but the
    1688                 :             :          * startup process waited longer than deadlock_timeout for it.
    1689                 :             :          */
    1690   [ -  +  #  # ]:          43 :         if (InHotStandby && logged_recovery_conflict)
    1691                 :           0 :                 LogRecoveryConflict(PROCSIG_RECOVERY_CONFLICT_LOCK,
    1692                 :           0 :                                                         standbyWaitStart, GetCurrentTimestamp(),
    1693                 :             :                                                         NULL, false);
    1694                 :             : 
    1695                 :             :         /*
    1696                 :             :          * We don't have to do anything else, because the awaker did all the
    1697                 :             :          * necessary updates of the lock table and MyProc. (The caller is
    1698                 :             :          * responsible for updating the local lock table.)
    1699                 :             :          */
    1700                 :          86 :         return myWaitStatus;
    1701                 :          43 : }
    1702                 :             : 
    1703                 :             : 
    1704                 :             : /*
    1705                 :             :  * ProcWakeup -- wake up a process by setting its latch.
    1706                 :             :  *
    1707                 :             :  *       Also remove the process from the wait queue and set its links invalid.
    1708                 :             :  *
    1709                 :             :  * The appropriate lock partition lock must be held by caller.
    1710                 :             :  *
    1711                 :             :  * XXX: presently, this code is only used for the "success" case, and only
    1712                 :             :  * works correctly for that case.  To clean up in failure case, would need
    1713                 :             :  * to twiddle the lock's request counts too --- see RemoveFromWaitQueue.
    1714                 :             :  * Hence, in practice the waitStatus parameter must be PROC_WAIT_STATUS_OK.
    1715                 :             :  */
    1716                 :             : void
    1717                 :          42 : ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
    1718                 :             : {
    1719         [ -  + ]:          42 :         if (dlist_node_is_detached(&proc->links))
    1720                 :           0 :                 return;
    1721                 :             : 
    1722         [ +  - ]:          42 :         Assert(proc->waitStatus == PROC_WAIT_STATUS_WAITING);
    1723                 :             : 
    1724                 :             :         /* Remove process from wait queue */
    1725                 :          42 :         dclist_delete_from_thoroughly(&proc->waitLock->waitProcs, &proc->links);
    1726                 :             : 
    1727                 :             :         /* Clean up process' state and pass it the ok/fail signal */
    1728                 :          42 :         proc->waitLock = NULL;
    1729                 :          42 :         proc->waitProcLock = NULL;
    1730                 :          42 :         proc->waitStatus = waitStatus;
    1731                 :          42 :         pg_atomic_write_u64(&MyProc->waitStart, 0);
    1732                 :             : 
    1733                 :             :         /* And awaken it */
    1734                 :          42 :         SetLatch(&proc->procLatch);
    1735                 :          42 : }
    1736                 :             : 
    1737                 :             : /*
    1738                 :             :  * ProcLockWakeup -- routine for waking up processes when a lock is
    1739                 :             :  *              released (or a prior waiter is aborted).  Scan all waiters
    1740                 :             :  *              for lock, waken any that are no longer blocked.
    1741                 :             :  *
    1742                 :             :  * The appropriate lock partition lock must be held by caller.
    1743                 :             :  */
    1744                 :             : void
    1745                 :          49 : ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
    1746                 :             : {
    1747                 :          49 :         dclist_head *waitQueue = &lock->waitProcs;
    1748                 :          49 :         LOCKMASK        aheadRequests = 0;
    1749                 :          49 :         dlist_mutable_iter miter;
    1750                 :             : 
    1751         [ +  + ]:          49 :         if (dclist_is_empty(waitQueue))
    1752                 :           1 :                 return;
    1753                 :             : 
    1754   [ +  -  +  + ]:         203 :         dclist_foreach_modify(miter, waitQueue)
    1755                 :             :         {
    1756                 :         155 :                 PGPROC     *proc = dlist_container(PGPROC, links, miter.cur);
    1757                 :         155 :                 LOCKMODE        lockmode = proc->waitLockMode;
    1758                 :             : 
    1759                 :             :                 /*
    1760                 :             :                  * Waken if (a) doesn't conflict with requests of earlier waiters, and
    1761                 :             :                  * (b) doesn't conflict with already-held locks.
    1762                 :             :                  */
    1763   [ +  +  +  + ]:         155 :                 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
    1764                 :         140 :                         !LockCheckConflicts(lockMethodTable, lockmode, lock,
    1765                 :          70 :                                                                 proc->waitProcLock))
    1766                 :             :                 {
    1767                 :             :                         /* OK to waken */
    1768                 :          42 :                         GrantLock(lock, proc->waitProcLock, lockmode);
    1769                 :             :                         /* removes proc from the lock's waiting process queue */
    1770                 :          42 :                         ProcWakeup(proc, PROC_WAIT_STATUS_OK);
    1771                 :          42 :                 }
    1772                 :             :                 else
    1773                 :             :                 {
    1774                 :             :                         /*
    1775                 :             :                          * Lock conflicts: Don't wake, but remember requested mode for
    1776                 :             :                          * later checks.
    1777                 :             :                          */
    1778                 :         113 :                         aheadRequests |= LOCKBIT_ON(lockmode);
    1779                 :             :                 }
    1780                 :         155 :         }
    1781         [ -  + ]:          49 : }
    1782                 :             : 
    1783                 :             : /*
    1784                 :             :  * CheckDeadLock
    1785                 :             :  *
    1786                 :             :  * We only get to this routine, if DEADLOCK_TIMEOUT fired while waiting for a
    1787                 :             :  * lock to be released by some other process.  Check if there's a deadlock; if
    1788                 :             :  * not, just return.  (But signal ProcSleep to log a message, if
    1789                 :             :  * log_lock_waits is true.)  If we have a real deadlock, remove ourselves from
    1790                 :             :  * the lock's wait queue and signal an error to ProcSleep.
    1791                 :             :  */
    1792                 :             : static void
    1793                 :           2 : CheckDeadLock(void)
    1794                 :             : {
    1795                 :           2 :         int                     i;
    1796                 :             : 
    1797                 :             :         /*
    1798                 :             :          * Acquire exclusive lock on the entire shared lock data structures. Must
    1799                 :             :          * grab LWLocks in partition-number order to avoid LWLock deadlock.
    1800                 :             :          *
    1801                 :             :          * Note that the deadlock check interrupt had better not be enabled
    1802                 :             :          * anywhere that this process itself holds lock partition locks, else this
    1803                 :             :          * will wait forever.  Also note that LWLockAcquire creates a critical
    1804                 :             :          * section, so that this routine cannot be interrupted by cancel/die
    1805                 :             :          * interrupts.
    1806                 :             :          */
    1807         [ +  + ]:          34 :         for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
    1808                 :          32 :                 LWLockAcquire(LockHashPartitionLockByIndex(i), LW_EXCLUSIVE);
    1809                 :             : 
    1810                 :             :         /*
    1811                 :             :          * Check to see if we've been awoken by anyone in the interim.
    1812                 :             :          *
    1813                 :             :          * If we have, we can return and resume our transaction -- happy day.
    1814                 :             :          * Before we are awoken the process releasing the lock grants it to us so
    1815                 :             :          * we know that we don't have to wait anymore.
    1816                 :             :          *
    1817                 :             :          * We check by looking to see if we've been unlinked from the wait queue.
    1818                 :             :          * This is safe because we hold the lock partition lock.
    1819                 :             :          */
    1820   [ +  -  -  + ]:           2 :         if (MyProc->links.prev == NULL ||
    1821                 :           2 :                 MyProc->links.next == NULL)
    1822                 :           0 :                 goto check_done;
    1823                 :             : 
    1824                 :             : #ifdef LOCK_DEBUG
    1825                 :             :         if (Debug_deadlocks)
    1826                 :             :                 DumpAllLocks();
    1827                 :             : #endif
    1828                 :             : 
    1829                 :             :         /* Run the deadlock check, and set deadlock_state for use by ProcSleep */
    1830                 :           2 :         deadlock_state = DeadLockCheck(MyProc);
    1831                 :             : 
    1832         [ +  - ]:           2 :         if (deadlock_state == DS_HARD_DEADLOCK)
    1833                 :             :         {
    1834                 :             :                 /*
    1835                 :             :                  * Oops.  We have a deadlock.
    1836                 :             :                  *
    1837                 :             :                  * Get this process out of wait state. (Note: we could do this more
    1838                 :             :                  * efficiently by relying on lockAwaited, but use this coding to
    1839                 :             :                  * preserve the flexibility to kill some other transaction than the
    1840                 :             :                  * one detecting the deadlock.)
    1841                 :             :                  *
    1842                 :             :                  * RemoveFromWaitQueue sets MyProc->waitStatus to
    1843                 :             :                  * PROC_WAIT_STATUS_ERROR, so ProcSleep will report an error after we
    1844                 :             :                  * return from the signal handler.
    1845                 :             :                  */
    1846         [ #  # ]:           0 :                 Assert(MyProc->waitLock != NULL);
    1847                 :           0 :                 RemoveFromWaitQueue(MyProc, LockTagHashCode(&(MyProc->waitLock->tag)));
    1848                 :             : 
    1849                 :             :                 /*
    1850                 :             :                  * We're done here.  Transaction abort caused by the error that
    1851                 :             :                  * ProcSleep will raise will cause any other locks we hold to be
    1852                 :             :                  * released, thus allowing other processes to wake up; we don't need
    1853                 :             :                  * to do that here.  NOTE: an exception is that releasing locks we
    1854                 :             :                  * hold doesn't consider the possibility of waiters that were blocked
    1855                 :             :                  * behind us on the lock we just failed to get, and might now be
    1856                 :             :                  * wakable because we're not in front of them anymore.  However,
    1857                 :             :                  * RemoveFromWaitQueue took care of waking up any such processes.
    1858                 :             :                  */
    1859                 :           0 :         }
    1860                 :             : 
    1861                 :             :         /*
    1862                 :             :          * And release locks.  We do this in reverse order for two reasons: (1)
    1863                 :             :          * Anyone else who needs more than one of the locks will be trying to lock
    1864                 :             :          * them in increasing order; we don't want to release the other process
    1865                 :             :          * until it can get all the locks it needs. (2) This avoids O(N^2)
    1866                 :             :          * behavior inside LWLockRelease.
    1867                 :             :          */
    1868                 :             : check_done:
    1869         [ +  + ]:          34 :         for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
    1870                 :          32 :                 LWLockRelease(LockHashPartitionLockByIndex(i));
    1871                 :           2 : }
    1872                 :             : 
    1873                 :             : /*
    1874                 :             :  * CheckDeadLockAlert - Handle the expiry of deadlock_timeout.
    1875                 :             :  *
    1876                 :             :  * NB: Runs inside a signal handler, be careful.
    1877                 :             :  */
    1878                 :             : void
    1879                 :           2 : CheckDeadLockAlert(void)
    1880                 :             : {
    1881                 :           2 :         int                     save_errno = errno;
    1882                 :             : 
    1883                 :           2 :         got_deadlock_timeout = true;
    1884                 :             : 
    1885                 :             :         /*
    1886                 :             :          * Have to set the latch again, even if handle_sig_alarm already did. Back
    1887                 :             :          * then got_deadlock_timeout wasn't yet set... It's unlikely that this
    1888                 :             :          * ever would be a problem, but setting a set latch again is cheap.
    1889                 :             :          *
    1890                 :             :          * Note that, when this function runs inside procsignal_sigusr1_handler(),
    1891                 :             :          * the handler function sets the latch again after the latch is set here.
    1892                 :             :          */
    1893                 :           2 :         SetLatch(MyLatch);
    1894                 :           2 :         errno = save_errno;
    1895                 :           2 : }
    1896                 :             : 
    1897                 :             : /*
    1898                 :             :  * GetLockHoldersAndWaiters - get lock holders and waiters for a lock
    1899                 :             :  *
    1900                 :             :  * Fill lock_holders_sbuf and lock_waiters_sbuf with the PIDs of processes holding
    1901                 :             :  * and waiting for the lock, and set lockHoldersNum to the number of lock holders.
    1902                 :             :  *
    1903                 :             :  * The lock table's partition lock must be held on entry and remains held on exit.
    1904                 :             :  */
    1905                 :             : void
    1906                 :           4 : GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf,
    1907                 :             :                                                  StringInfo lock_waiters_sbuf, int *lockHoldersNum)
    1908                 :             : {
    1909                 :           4 :         dlist_iter      proc_iter;
    1910                 :           4 :         PROCLOCK   *curproclock;
    1911                 :           4 :         LOCK       *lock = locallock->lock;
    1912                 :           4 :         bool            first_holder = true,
    1913                 :           4 :                                 first_waiter = true;
    1914                 :             : 
    1915                 :             : #ifdef USE_ASSERT_CHECKING
    1916                 :             :         {
    1917                 :           4 :                 uint32          hashcode = locallock->hashcode;
    1918                 :           4 :                 LWLock     *partitionLock = LockHashPartitionLock(hashcode);
    1919                 :             : 
    1920         [ +  - ]:           4 :                 Assert(LWLockHeldByMe(partitionLock));
    1921                 :           4 :         }
    1922                 :             : #endif
    1923                 :             : 
    1924                 :           4 :         *lockHoldersNum = 0;
    1925                 :             : 
    1926                 :             :         /*
    1927                 :             :          * Loop over the lock's procLocks to gather a list of all holders and
    1928                 :             :          * waiters. Thus we will be able to provide more detailed information for
    1929                 :             :          * lock debugging purposes.
    1930                 :             :          *
    1931                 :             :          * lock->procLocks contains all processes which hold or wait for this
    1932                 :             :          * lock.
    1933                 :             :          */
    1934   [ +  -  +  + ]:          14 :         dlist_foreach(proc_iter, &lock->procLocks)
    1935                 :             :         {
    1936                 :          10 :                 curproclock =
    1937                 :          10 :                         dlist_container(PROCLOCK, lockLink, proc_iter.cur);
    1938                 :             : 
    1939                 :             :                 /*
    1940                 :             :                  * We are a waiter if myProc->waitProcLock == curproclock; we are a
    1941                 :             :                  * holder if it is NULL or something different.
    1942                 :             :                  */
    1943         [ +  + ]:          10 :                 if (curproclock->tag.myProc->waitProcLock == curproclock)
    1944                 :             :                 {
    1945         [ +  + ]:           4 :                         if (first_waiter)
    1946                 :             :                         {
    1947                 :           4 :                                 appendStringInfo(lock_waiters_sbuf, "%d",
    1948                 :           2 :                                                                  curproclock->tag.myProc->pid);
    1949                 :           2 :                                 first_waiter = false;
    1950                 :           2 :                         }
    1951                 :             :                         else
    1952                 :           4 :                                 appendStringInfo(lock_waiters_sbuf, ", %d",
    1953                 :           2 :                                                                  curproclock->tag.myProc->pid);
    1954                 :           4 :                 }
    1955                 :             :                 else
    1956                 :             :                 {
    1957         [ +  + ]:           6 :                         if (first_holder)
    1958                 :             :                         {
    1959                 :           8 :                                 appendStringInfo(lock_holders_sbuf, "%d",
    1960                 :           4 :                                                                  curproclock->tag.myProc->pid);
    1961                 :           4 :                                 first_holder = false;
    1962                 :           4 :                         }
    1963                 :             :                         else
    1964                 :           4 :                                 appendStringInfo(lock_holders_sbuf, ", %d",
    1965                 :           2 :                                                                  curproclock->tag.myProc->pid);
    1966                 :             : 
    1967                 :           6 :                         (*lockHoldersNum)++;
    1968                 :             :                 }
    1969                 :          10 :         }
    1970                 :           4 : }
    1971                 :             : 
    1972                 :             : /*
    1973                 :             :  * ProcWaitForSignal - wait for a signal from another backend.
    1974                 :             :  *
    1975                 :             :  * As this uses the generic process latch the caller has to be robust against
    1976                 :             :  * unrelated wakeups: Always check that the desired state has occurred, and
    1977                 :             :  * wait again if not.
    1978                 :             :  */
    1979                 :             : void
    1980                 :           0 : ProcWaitForSignal(uint32 wait_event_info)
    1981                 :             : {
    1982                 :           0 :         (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
    1983                 :           0 :                                          wait_event_info);
    1984                 :           0 :         ResetLatch(MyLatch);
    1985         [ #  # ]:           0 :         CHECK_FOR_INTERRUPTS();
    1986                 :           0 : }
    1987                 :             : 
    1988                 :             : /*
    1989                 :             :  * ProcSendSignal - set the latch of a backend identified by ProcNumber
    1990                 :             :  */
    1991                 :             : void
    1992                 :           0 : ProcSendSignal(ProcNumber procNumber)
    1993                 :             : {
    1994         [ #  # ]:           0 :         if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
    1995   [ #  #  #  # ]:           0 :                 elog(ERROR, "procNumber out of range");
    1996                 :             : 
    1997                 :           0 :         SetLatch(&GetPGProcByNumber(procNumber)->procLatch);
    1998                 :           0 : }
    1999                 :             : 
    2000                 :             : /*
    2001                 :             :  * BecomeLockGroupLeader - designate process as lock group leader
    2002                 :             :  *
    2003                 :             :  * Once this function has returned, other processes can join the lock group
    2004                 :             :  * by calling BecomeLockGroupMember.
    2005                 :             :  */
    2006                 :             : void
    2007                 :         203 : BecomeLockGroupLeader(void)
    2008                 :             : {
    2009                 :         203 :         LWLock     *leader_lwlock;
    2010                 :             : 
    2011                 :             :         /* If we already did it, we don't need to do it again. */
    2012         [ +  + ]:         203 :         if (MyProc->lockGroupLeader == MyProc)
    2013                 :         181 :                 return;
    2014                 :             : 
    2015                 :             :         /* We had better not be a follower. */
    2016         [ +  - ]:          22 :         Assert(MyProc->lockGroupLeader == NULL);
    2017                 :             : 
    2018                 :             :         /* Create single-member group, containing only ourselves. */
    2019                 :          22 :         leader_lwlock = LockHashPartitionLockByProc(MyProc);
    2020                 :          22 :         LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
    2021                 :          22 :         MyProc->lockGroupLeader = MyProc;
    2022                 :          22 :         dlist_push_head(&MyProc->lockGroupMembers, &MyProc->lockGroupLink);
    2023                 :          22 :         LWLockRelease(leader_lwlock);
    2024         [ -  + ]:         203 : }
    2025                 :             : 
    2026                 :             : /*
    2027                 :             :  * BecomeLockGroupMember - designate process as lock group member
    2028                 :             :  *
    2029                 :             :  * This is pretty straightforward except for the possibility that the leader
    2030                 :             :  * whose group we're trying to join might exit before we manage to do so;
    2031                 :             :  * and the PGPROC might get recycled for an unrelated process.  To avoid
    2032                 :             :  * that, we require the caller to pass the PID of the intended PGPROC as
    2033                 :             :  * an interlock.  Returns true if we successfully join the intended lock
    2034                 :             :  * group, and false if not.
    2035                 :             :  */
    2036                 :             : bool
    2037                 :         477 : BecomeLockGroupMember(PGPROC *leader, int pid)
    2038                 :             : {
    2039                 :         477 :         LWLock     *leader_lwlock;
    2040                 :         477 :         bool            ok = false;
    2041                 :             : 
    2042                 :             :         /* Group leader can't become member of group */
    2043         [ +  - ]:         477 :         Assert(MyProc != leader);
    2044                 :             : 
    2045                 :             :         /* Can't already be a member of a group */
    2046         [ +  - ]:         477 :         Assert(MyProc->lockGroupLeader == NULL);
    2047                 :             : 
    2048                 :             :         /* PID must be valid. */
    2049         [ +  - ]:         477 :         Assert(pid != 0);
    2050                 :             : 
    2051                 :             :         /*
    2052                 :             :          * Get lock protecting the group fields.  Note LockHashPartitionLockByProc
    2053                 :             :          * calculates the proc number based on the PGPROC slot without looking at
    2054                 :             :          * its contents, so we will acquire the correct lock even if the leader
    2055                 :             :          * PGPROC is in process of being recycled.
    2056                 :             :          */
    2057                 :         477 :         leader_lwlock = LockHashPartitionLockByProc(leader);
    2058                 :         477 :         LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);
    2059                 :             : 
    2060                 :             :         /* Is this the leader we're looking for? */
    2061   [ +  -  -  + ]:         477 :         if (leader->pid == pid && leader->lockGroupLeader == leader)
    2062                 :             :         {
    2063                 :             :                 /* OK, join the group */
    2064                 :         477 :                 ok = true;
    2065                 :         477 :                 MyProc->lockGroupLeader = leader;
    2066                 :         477 :                 dlist_push_tail(&leader->lockGroupMembers, &MyProc->lockGroupLink);
    2067                 :         477 :         }
    2068                 :         477 :         LWLockRelease(leader_lwlock);
    2069                 :             : 
    2070                 :         954 :         return ok;
    2071                 :         477 : }
        

Generated by: LCOV version 2.3.2-1