PostgreSQL Source Code  git master
lockfuncs.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "storage/predicate_internals.h"
#include "utils/array.h"
#include "utils/builtins.h"
Include dependency graph for lockfuncs.c:

Go to the source code of this file.

Data Structures

struct  PG_Lock_Status
 

Macros

#define NUM_LOCK_STATUS_COLUMNS   15
 
#define SET_LOCKTAG_INT64(tag, key64)
 
#define SET_LOCKTAG_INT32(tag, key1, key2)   SET_LOCKTAG_ADVISORY(tag, MyDatabaseId, key1, key2, 2)
 

Functions

 StaticAssertDecl (lengthof(LockTagTypeNames)==(LOCKTAG_ADVISORY+1), "array length mismatch")
 
 StaticAssertDecl (lengthof(PredicateLockTagTypeNames)==(PREDLOCKTAG_TUPLE+1), "array length mismatch")
 
static Datum VXIDGetDatum (BackendId bid, LocalTransactionId lxid)
 
Datum pg_lock_status (PG_FUNCTION_ARGS)
 
Datum pg_blocking_pids (PG_FUNCTION_ARGS)
 
Datum pg_safe_snapshot_blocking_pids (PG_FUNCTION_ARGS)
 
Datum pg_isolation_test_session_is_blocked (PG_FUNCTION_ARGS)
 
Datum pg_advisory_lock_int8 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_xact_lock_int8 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_lock_shared_int8 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_xact_lock_shared_int8 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_lock_int8 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_xact_lock_int8 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_lock_shared_int8 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_xact_lock_shared_int8 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_unlock_int8 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_unlock_shared_int8 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_lock_int4 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_xact_lock_int4 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_lock_shared_int4 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_xact_lock_shared_int4 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_lock_int4 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_xact_lock_int4 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_lock_shared_int4 (PG_FUNCTION_ARGS)
 
Datum pg_try_advisory_xact_lock_shared_int4 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_unlock_int4 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_unlock_shared_int4 (PG_FUNCTION_ARGS)
 
Datum pg_advisory_unlock_all (PG_FUNCTION_ARGS)
 

Variables

const char *const LockTagTypeNames []
 
static const char *const PredicateLockTagTypeNames []
 

Macro Definition Documentation

◆ NUM_LOCK_STATUS_COLUMNS

#define NUM_LOCK_STATUS_COLUMNS   15

Definition at line 65 of file lockfuncs.c.

Referenced by pg_lock_status().

◆ SET_LOCKTAG_INT32

◆ SET_LOCKTAG_INT64

#define SET_LOCKTAG_INT64 (   tag,
  key64 
)

Function Documentation

◆ pg_advisory_lock_int4()

Datum pg_advisory_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 853 of file lockfuncs.c.

References ExclusiveLock, LockAcquire(), PG_GETARG_INT32, PG_RETURN_VOID, and SET_LOCKTAG_INT32.

854 {
855  int32 key1 = PG_GETARG_INT32(0);
856  int32 key2 = PG_GETARG_INT32(1);
857  LOCKTAG tag;
858 
859  SET_LOCKTAG_INT32(tag, key1, key2);
860 
861  (void) LockAcquire(&tag, ExclusiveLock, true, false);
862 
863  PG_RETURN_VOID();
864 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_VOID()
Definition: fmgr.h:348

◆ pg_advisory_lock_int8()

Datum pg_advisory_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 671 of file lockfuncs.c.

References ExclusiveLock, sort-test::key, LockAcquire(), PG_GETARG_INT64, PG_RETURN_VOID, and SET_LOCKTAG_INT64.

Referenced by delay_execution_planner().

672 {
673  int64 key = PG_GETARG_INT64(0);
674  LOCKTAG tag;
675 
676  SET_LOCKTAG_INT64(tag, key);
677 
678  (void) LockAcquire(&tag, ExclusiveLock, true, false);
679 
680  PG_RETURN_VOID();
681 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_advisory_lock_shared_int4()

Datum pg_advisory_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 888 of file lockfuncs.c.

References LockAcquire(), PG_GETARG_INT32, PG_RETURN_VOID, SET_LOCKTAG_INT32, and ShareLock.

889 {
890  int32 key1 = PG_GETARG_INT32(0);
891  int32 key2 = PG_GETARG_INT32(1);
892  LOCKTAG tag;
893 
894  SET_LOCKTAG_INT32(tag, key1, key2);
895 
896  (void) LockAcquire(&tag, ShareLock, true, false);
897 
898  PG_RETURN_VOID();
899 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define ShareLock
Definition: lockdefs.h:41

◆ pg_advisory_lock_shared_int8()

Datum pg_advisory_lock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 704 of file lockfuncs.c.

References sort-test::key, LockAcquire(), PG_GETARG_INT64, PG_RETURN_VOID, SET_LOCKTAG_INT64, and ShareLock.

705 {
706  int64 key = PG_GETARG_INT64(0);
707  LOCKTAG tag;
708 
709  SET_LOCKTAG_INT64(tag, key);
710 
711  (void) LockAcquire(&tag, ShareLock, true, false);
712 
713  PG_RETURN_VOID();
714 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:163
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_advisory_unlock_all()

Datum pg_advisory_unlock_all ( PG_FUNCTION_ARGS  )

Definition at line 1045 of file lockfuncs.c.

References LockReleaseSession(), PG_RETURN_VOID, and USER_LOCKMETHOD.

1046 {
1048 
1049  PG_RETURN_VOID();
1050 }
#define USER_LOCKMETHOD
Definition: lock.h:128
#define PG_RETURN_VOID()
Definition: fmgr.h:348
void LockReleaseSession(LOCKMETHODID lockmethodid)
Definition: lock.c:2454

◆ pg_advisory_unlock_int4()

Datum pg_advisory_unlock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1007 of file lockfuncs.c.

References ExclusiveLock, LockRelease(), PG_GETARG_INT32, PG_RETURN_BOOL, and SET_LOCKTAG_INT32.

1008 {
1009  int32 key1 = PG_GETARG_INT32(0);
1010  int32 key2 = PG_GETARG_INT32(1);
1011  LOCKTAG tag;
1012  bool res;
1013 
1014  SET_LOCKTAG_INT32(tag, key1, key2);
1015 
1016  res = LockRelease(&tag, ExclusiveLock, true);
1017 
1018  PG_RETURN_BOOL(res);
1019 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1975

◆ pg_advisory_unlock_int8()

Datum pg_advisory_unlock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 817 of file lockfuncs.c.

References ExclusiveLock, sort-test::key, LockRelease(), PG_GETARG_INT64, PG_RETURN_BOOL, and SET_LOCKTAG_INT64.

Referenced by delay_execution_planner().

818 {
819  int64 key = PG_GETARG_INT64(0);
820  LOCKTAG tag;
821  bool res;
822 
823  SET_LOCKTAG_INT64(tag, key);
824 
825  res = LockRelease(&tag, ExclusiveLock, true);
826 
827  PG_RETURN_BOOL(res);
828 }
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1975
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_advisory_unlock_shared_int4()

Datum pg_advisory_unlock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1027 of file lockfuncs.c.

References LockRelease(), PG_GETARG_INT32, PG_RETURN_BOOL, SET_LOCKTAG_INT32, and ShareLock.

1028 {
1029  int32 key1 = PG_GETARG_INT32(0);
1030  int32 key2 = PG_GETARG_INT32(1);
1031  LOCKTAG tag;
1032  bool res;
1033 
1034  SET_LOCKTAG_INT32(tag, key1, key2);
1035 
1036  res = LockRelease(&tag, ShareLock, true);
1037 
1038  PG_RETURN_BOOL(res);
1039 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define ShareLock
Definition: lockdefs.h:41
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1975

◆ pg_advisory_unlock_shared_int8()

Datum pg_advisory_unlock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 836 of file lockfuncs.c.

References sort-test::key, LockRelease(), PG_GETARG_INT64, PG_RETURN_BOOL, SET_LOCKTAG_INT64, and ShareLock.

837 {
838  int64 key = PG_GETARG_INT64(0);
839  LOCKTAG tag;
840  bool res;
841 
842  SET_LOCKTAG_INT64(tag, key);
843 
844  res = LockRelease(&tag, ShareLock, true);
845 
846  PG_RETURN_BOOL(res);
847 }
Definition: lock.h:163
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define ShareLock
Definition: lockdefs.h:41
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1975
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_advisory_xact_lock_int4()

Datum pg_advisory_xact_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 871 of file lockfuncs.c.

References ExclusiveLock, LockAcquire(), PG_GETARG_INT32, PG_RETURN_VOID, and SET_LOCKTAG_INT32.

872 {
873  int32 key1 = PG_GETARG_INT32(0);
874  int32 key2 = PG_GETARG_INT32(1);
875  LOCKTAG tag;
876 
877  SET_LOCKTAG_INT32(tag, key1, key2);
878 
879  (void) LockAcquire(&tag, ExclusiveLock, false, false);
880 
881  PG_RETURN_VOID();
882 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_VOID()
Definition: fmgr.h:348

◆ pg_advisory_xact_lock_int8()

Datum pg_advisory_xact_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 688 of file lockfuncs.c.

References ExclusiveLock, sort-test::key, LockAcquire(), PG_GETARG_INT64, PG_RETURN_VOID, and SET_LOCKTAG_INT64.

689 {
690  int64 key = PG_GETARG_INT64(0);
691  LOCKTAG tag;
692 
693  SET_LOCKTAG_INT64(tag, key);
694 
695  (void) LockAcquire(&tag, ExclusiveLock, false, false);
696 
697  PG_RETURN_VOID();
698 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_advisory_xact_lock_shared_int4()

Datum pg_advisory_xact_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 906 of file lockfuncs.c.

References LockAcquire(), PG_GETARG_INT32, PG_RETURN_VOID, SET_LOCKTAG_INT32, and ShareLock.

907 {
908  int32 key1 = PG_GETARG_INT32(0);
909  int32 key2 = PG_GETARG_INT32(1);
910  LOCKTAG tag;
911 
912  SET_LOCKTAG_INT32(tag, key1, key2);
913 
914  (void) LockAcquire(&tag, ShareLock, false, false);
915 
916  PG_RETURN_VOID();
917 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define ShareLock
Definition: lockdefs.h:41

◆ pg_advisory_xact_lock_shared_int8()

Datum pg_advisory_xact_lock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 721 of file lockfuncs.c.

References sort-test::key, LockAcquire(), PG_GETARG_INT64, PG_RETURN_VOID, SET_LOCKTAG_INT64, and ShareLock.

722 {
723  int64 key = PG_GETARG_INT64(0);
724  LOCKTAG tag;
725 
726  SET_LOCKTAG_INT64(tag, key);
727 
728  (void) LockAcquire(&tag, ShareLock, false, false);
729 
730  PG_RETURN_VOID();
731 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:163
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_blocking_pids()

Datum pg_blocking_pids ( PG_FUNCTION_ARGS  )

Definition at line 427 of file lockfuncs.c.

References Assert, LockMethodData::conflictTab, construct_array(), BlockedProcData::first_lock, BlockedProcData::first_waiter, GetBlockerStatusData(), GetLockTagsMethodTable(), LockInstanceData::holdMask, i, Int32GetDatum, LockInstanceData::leaderPid, LOCKBIT_ON, BlockedProcsData::locks, LockInstanceData::locktag, BlockedProcsData::nlocks, NoLock, BlockedProcsData::nprocs, BlockedProcData::num_locks, BlockedProcData::num_waiters, palloc(), PG_GETARG_INT32, PG_RETURN_ARRAYTYPE_P, LockInstanceData::pid, BlockedProcData::pid, BlockedProcsData::procs, BlockedProcsData::waiter_pids, and LockInstanceData::waitLockMode.

Referenced by pg_isolation_test_session_is_blocked().

428 {
429  int blocked_pid = PG_GETARG_INT32(0);
430  Datum *arrayelems;
431  int narrayelems;
432  BlockedProcsData *lockData; /* state data from lmgr */
433  int i,
434  j;
435 
436  /* Collect a snapshot of lock manager state */
437  lockData = GetBlockerStatusData(blocked_pid);
438 
439  /* We can't need more output entries than there are reported PROCLOCKs */
440  arrayelems = (Datum *) palloc(lockData->nlocks * sizeof(Datum));
441  narrayelems = 0;
442 
443  /* For each blocked proc in the lock group ... */
444  for (i = 0; i < lockData->nprocs; i++)
445  {
446  BlockedProcData *bproc = &lockData->procs[i];
447  LockInstanceData *instances = &lockData->locks[bproc->first_lock];
448  int *preceding_waiters = &lockData->waiter_pids[bproc->first_waiter];
449  LockInstanceData *blocked_instance;
450  LockMethod lockMethodTable;
451  int conflictMask;
452 
453  /*
454  * Locate the blocked proc's own entry in the LockInstanceData array.
455  * There should be exactly one matching entry.
456  */
457  blocked_instance = NULL;
458  for (j = 0; j < bproc->num_locks; j++)
459  {
460  LockInstanceData *instance = &(instances[j]);
461 
462  if (instance->pid == bproc->pid)
463  {
464  Assert(blocked_instance == NULL);
465  blocked_instance = instance;
466  }
467  }
468  Assert(blocked_instance != NULL);
469 
470  lockMethodTable = GetLockTagsMethodTable(&(blocked_instance->locktag));
471  conflictMask = lockMethodTable->conflictTab[blocked_instance->waitLockMode];
472 
473  /* Now scan the PROCLOCK data for conflicting procs */
474  for (j = 0; j < bproc->num_locks; j++)
475  {
476  LockInstanceData *instance = &(instances[j]);
477 
478  /* A proc never blocks itself, so ignore that entry */
479  if (instance == blocked_instance)
480  continue;
481  /* Members of same lock group never block each other, either */
482  if (instance->leaderPid == blocked_instance->leaderPid)
483  continue;
484 
485  if (conflictMask & instance->holdMask)
486  {
487  /* hard block: blocked by lock already held by this entry */
488  }
489  else if (instance->waitLockMode != NoLock &&
490  (conflictMask & LOCKBIT_ON(instance->waitLockMode)))
491  {
492  /* conflict in lock requests; who's in front in wait queue? */
493  bool ahead = false;
494  int k;
495 
496  for (k = 0; k < bproc->num_waiters; k++)
497  {
498  if (preceding_waiters[k] == instance->pid)
499  {
500  /* soft block: this entry is ahead of blocked proc */
501  ahead = true;
502  break;
503  }
504  }
505  if (!ahead)
506  continue; /* not blocked by this entry */
507  }
508  else
509  {
510  /* not blocked by this entry */
511  continue;
512  }
513 
514  /* blocked by this entry, so emit a record */
515  arrayelems[narrayelems++] = Int32GetDatum(instance->leaderPid);
516  }
517  }
518 
519  /* Assert we didn't overrun arrayelems[] */
520  Assert(narrayelems <= lockData->nlocks);
521 
522  /* Construct array, using hardwired knowledge about int4 type */
523  PG_RETURN_ARRAYTYPE_P(construct_array(arrayelems, narrayelems,
524  INT4OID,
525  sizeof(int32), true, TYPALIGN_INT));
526 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int * waiter_pids
Definition: lock.h:466
BlockedProcsData * GetBlockerStatusData(int blocked_pid)
Definition: lock.c:3753
int first_lock
Definition: lock.h:454
int num_waiters
Definition: lock.h:459
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3313
const LOCKMASK * conflictTab
Definition: lock.h:113
BlockedProcData * procs
Definition: lock.h:464
LOCKTAG locktag
Definition: lock.h:433
LOCKMODE waitLockMode
Definition: lock.h:435
int num_locks
Definition: lock.h:455
signed int int32
Definition: c.h:362
int leaderPid
Definition: lock.h:439
#define NoLock
Definition: lockdefs.h:34
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:253
LockInstanceData * locks
Definition: lock.h:465
uintptr_t Datum
Definition: postgres.h:367
LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag)
Definition: lock.c:499
int first_waiter
Definition: lock.h:458
#define Assert(condition)
Definition: c.h:745
LOCKMASK holdMask
Definition: lock.h:434
#define LOCKBIT_ON(lockmode)
Definition: lock.h:86
#define Int32GetDatum(X)
Definition: postgres.h:479
void * palloc(Size size)
Definition: mcxt.c:949
int i

◆ pg_isolation_test_session_is_blocked()

Datum pg_isolation_test_session_is_blocked ( PG_FUNCTION_ARGS  )

Definition at line 582 of file lockfuncs.c.

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, array_contains_nulls(), ArrayGetNItems(), Assert, DatumGetArrayTypeP, DirectFunctionCall1, elog, ERROR, GetSafeSnapshotBlockingPids(), i, pg_blocking_pids(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_INT32, and PG_RETURN_BOOL.

583 {
584  int blocked_pid = PG_GETARG_INT32(0);
585  ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
586  ArrayType *blocking_pids_a;
587  int32 *interesting_pids;
588  int32 *blocking_pids;
589  int num_interesting_pids;
590  int num_blocking_pids;
591  int dummy;
592  int i,
593  j;
594 
595  /* Validate the passed-in array */
596  Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
597  if (array_contains_nulls(interesting_pids_a))
598  elog(ERROR, "array must not contain nulls");
599  interesting_pids = (int32 *) ARR_DATA_PTR(interesting_pids_a);
600  num_interesting_pids = ArrayGetNItems(ARR_NDIM(interesting_pids_a),
601  ARR_DIMS(interesting_pids_a));
602 
603  /*
604  * Get the PIDs of all sessions blocking the given session's attempt to
605  * acquire heavyweight locks.
606  */
607  blocking_pids_a =
609 
610  Assert(ARR_ELEMTYPE(blocking_pids_a) == INT4OID);
611  Assert(!array_contains_nulls(blocking_pids_a));
612  blocking_pids = (int32 *) ARR_DATA_PTR(blocking_pids_a);
613  num_blocking_pids = ArrayGetNItems(ARR_NDIM(blocking_pids_a),
614  ARR_DIMS(blocking_pids_a));
615 
616  /*
617  * Check if any of these are in the list of interesting PIDs, that being
618  * the sessions that the isolation tester is running. We don't use
619  * "arrayoverlaps" here, because it would lead to cache lookups and one of
620  * our goals is to run quickly under CLOBBER_CACHE_ALWAYS. We expect
621  * blocking_pids to be usually empty and otherwise a very small number in
622  * isolation tester cases, so make that the outer loop of a naive search
623  * for a match.
624  */
625  for (i = 0; i < num_blocking_pids; i++)
626  for (j = 0; j < num_interesting_pids; j++)
627  {
628  if (blocking_pids[i] == interesting_pids[j])
629  PG_RETURN_BOOL(true);
630  }
631 
632  /*
633  * Check if blocked_pid is waiting for a safe snapshot. We could in
634  * theory check the resulting array of blocker PIDs against the
635  * interesting PIDs whitelist, but since there is no danger of autovacuum
636  * blocking GetSafeSnapshot there seems to be no point in expending cycles
637  * on allocating a buffer and searching for overlap; so it's presently
638  * sufficient for the isolation tester's purposes to use a single element
639  * buffer and check if the number of safe snapshot blockers is non-zero.
640  */
641  if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0)
642  PG_RETURN_BOOL(true);
643 
644  PG_RETURN_BOOL(false);
645 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:624
signed int int32
Definition: c.h:362
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define ERROR
Definition: elog.h:43
Datum pg_blocking_pids(PG_FUNCTION_ARGS)
Definition: lockfuncs.c:427
#define ARR_DIMS(a)
Definition: array.h:282
#define ARR_DATA_PTR(a)
Definition: array.h:310
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define Assert(condition)
Definition: c.h:745
#define ARR_NDIM(a)
Definition: array.h:278
#define elog(elevel,...)
Definition: elog.h:214
int i
int GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
Definition: predicate.c:1558
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3550
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define DatumGetArrayTypeP(X)
Definition: array.h:249

◆ pg_lock_status()

Datum pg_lock_status ( PG_FUNCTION_ARGS  )

Definition at line 91 of file lockfuncs.c.

References LockInstanceData::backend, VirtualTransactionId::backendId, BlessTupleDesc(), BoolGetDatum, CreateTemplateTupleDesc(), CStringGetTextDatum, PG_Lock_Status::currIdx, LockInstanceData::fastpath, GET_PREDICATELOCKTARGETTAG_DB, GET_PREDICATELOCKTARGETTAG_OFFSET, GET_PREDICATELOCKTARGETTAG_PAGE, GET_PREDICATELOCKTARGETTAG_RELATION, GET_PREDICATELOCKTARGETTAG_TYPE, GetLockmodeName(), GetLockStatusData(), GetPredicateLockStatusData(), heap_form_tuple(), HeapTupleGetDatum, LockInstanceData::holdMask, Int16GetDatum, Int32GetDatum, VirtualTransactionId::localTransactionId, LOCKBIT_OFF, LOCKBIT_ON, PG_Lock_Status::lockData, LockData::locks, LockInstanceData::locktag, LOCKTAG_ADVISORY, LOCKTAG::locktag_field1, LOCKTAG::locktag_field2, LOCKTAG::locktag_field3, LOCKTAG::locktag_field4, LOCKTAG_LAST_TYPE, LOCKTAG::locktag_lockmethodid, LOCKTAG_OBJECT, LOCKTAG_PAGE, LOCKTAG_RELATION, LOCKTAG_RELATION_EXTEND, LOCKTAG_TRANSACTION, LOCKTAG_TUPLE, LOCKTAG::locktag_type, LOCKTAG_USERLOCK, LOCKTAG_VIRTUALTRANSACTION, PredicateLockData::locktags, LockTagTypeNames, LockInstanceData::lxid, MAX_LOCKMODES, MemoryContextSwitchTo(), MemSet, mode, FuncCallContext::multi_call_memory_ctx, PredicateLockData::nelements, LockData::nelements, NoLock, NUM_LOCK_STATUS_COLUMNS, ObjectIdGetDatum, palloc(), SERIALIZABLEXACT::pid, LockInstanceData::pid, PredicateLockTagTypeNames, PG_Lock_Status::predLockData, PG_Lock_Status::predLockIdx, PREDLOCKTAG_PAGE, PREDLOCKTAG_TUPLE, snprintf, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, TransactionIdGetDatum, FuncCallContext::tuple_desc, TupleDescInitEntry(), UInt16GetDatum, UInt32GetDatum, FuncCallContext::user_fctx, values, SERIALIZABLEXACT::vxid, VXIDGetDatum(), LockInstanceData::waitLockMode, and PredicateLockData::xacts.

92 {
93  FuncCallContext *funcctx;
94  PG_Lock_Status *mystatus;
95  LockData *lockData;
96  PredicateLockData *predLockData;
97 
98  if (SRF_IS_FIRSTCALL())
99  {
100  TupleDesc tupdesc;
101  MemoryContext oldcontext;
102 
103  /* create a function context for cross-call persistence */
104  funcctx = SRF_FIRSTCALL_INIT();
105 
106  /*
107  * switch to memory context appropriate for multiple function calls
108  */
109  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
110 
111  /* build tupdesc for result tuples */
112  /* this had better match function's declaration in pg_proc.h */
114  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "locktype",
115  TEXTOID, -1, 0);
116  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database",
117  OIDOID, -1, 0);
118  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "relation",
119  OIDOID, -1, 0);
120  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "page",
121  INT4OID, -1, 0);
122  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "tuple",
123  INT2OID, -1, 0);
124  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "virtualxid",
125  TEXTOID, -1, 0);
126  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "transactionid",
127  XIDOID, -1, 0);
128  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "classid",
129  OIDOID, -1, 0);
130  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "objid",
131  OIDOID, -1, 0);
132  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "objsubid",
133  INT2OID, -1, 0);
134  TupleDescInitEntry(tupdesc, (AttrNumber) 11, "virtualtransaction",
135  TEXTOID, -1, 0);
136  TupleDescInitEntry(tupdesc, (AttrNumber) 12, "pid",
137  INT4OID, -1, 0);
138  TupleDescInitEntry(tupdesc, (AttrNumber) 13, "mode",
139  TEXTOID, -1, 0);
140  TupleDescInitEntry(tupdesc, (AttrNumber) 14, "granted",
141  BOOLOID, -1, 0);
142  TupleDescInitEntry(tupdesc, (AttrNumber) 15, "fastpath",
143  BOOLOID, -1, 0);
144 
145  funcctx->tuple_desc = BlessTupleDesc(tupdesc);
146 
147  /*
148  * Collect all the locking information that we will format and send
149  * out as a result set.
150  */
151  mystatus = (PG_Lock_Status *) palloc(sizeof(PG_Lock_Status));
152  funcctx->user_fctx = (void *) mystatus;
153 
154  mystatus->lockData = GetLockStatusData();
155  mystatus->currIdx = 0;
157  mystatus->predLockIdx = 0;
158 
159  MemoryContextSwitchTo(oldcontext);
160  }
161 
162  funcctx = SRF_PERCALL_SETUP();
163  mystatus = (PG_Lock_Status *) funcctx->user_fctx;
164  lockData = mystatus->lockData;
165 
166  while (mystatus->currIdx < lockData->nelements)
167  {
168  bool granted;
169  LOCKMODE mode = 0;
170  const char *locktypename;
171  char tnbuf[32];
173  bool nulls[NUM_LOCK_STATUS_COLUMNS];
174  HeapTuple tuple;
175  Datum result;
176  LockInstanceData *instance;
177 
178  instance = &(lockData->locks[mystatus->currIdx]);
179 
180  /*
181  * Look to see if there are any held lock modes in this PROCLOCK. If
182  * so, report, and destructively modify lockData so we don't report
183  * again.
184  */
185  granted = false;
186  if (instance->holdMask)
187  {
188  for (mode = 0; mode < MAX_LOCKMODES; mode++)
189  {
190  if (instance->holdMask & LOCKBIT_ON(mode))
191  {
192  granted = true;
193  instance->holdMask &= LOCKBIT_OFF(mode);
194  break;
195  }
196  }
197  }
198 
199  /*
200  * If no (more) held modes to report, see if PROC is waiting for a
201  * lock on this lock.
202  */
203  if (!granted)
204  {
205  if (instance->waitLockMode != NoLock)
206  {
207  /* Yes, so report it with proper mode */
208  mode = instance->waitLockMode;
209 
210  /*
211  * We are now done with this PROCLOCK, so advance pointer to
212  * continue with next one on next call.
213  */
214  mystatus->currIdx++;
215  }
216  else
217  {
218  /*
219  * Okay, we've displayed all the locks associated with this
220  * PROCLOCK, proceed to the next one.
221  */
222  mystatus->currIdx++;
223  continue;
224  }
225  }
226 
227  /*
228  * Form tuple with appropriate data.
229  */
230  MemSet(values, 0, sizeof(values));
231  MemSet(nulls, false, sizeof(nulls));
232 
233  if (instance->locktag.locktag_type <= LOCKTAG_LAST_TYPE)
234  locktypename = LockTagTypeNames[instance->locktag.locktag_type];
235  else
236  {
237  snprintf(tnbuf, sizeof(tnbuf), "unknown %d",
238  (int) instance->locktag.locktag_type);
239  locktypename = tnbuf;
240  }
241  values[0] = CStringGetTextDatum(locktypename);
242 
243  switch ((LockTagType) instance->locktag.locktag_type)
244  {
245  case LOCKTAG_RELATION:
247  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
248  values[2] = ObjectIdGetDatum(instance->locktag.locktag_field2);
249  nulls[3] = true;
250  nulls[4] = true;
251  nulls[5] = true;
252  nulls[6] = true;
253  nulls[7] = true;
254  nulls[8] = true;
255  nulls[9] = true;
256  break;
257  case LOCKTAG_PAGE:
258  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
259  values[2] = ObjectIdGetDatum(instance->locktag.locktag_field2);
260  values[3] = UInt32GetDatum(instance->locktag.locktag_field3);
261  nulls[4] = true;
262  nulls[5] = true;
263  nulls[6] = true;
264  nulls[7] = true;
265  nulls[8] = true;
266  nulls[9] = true;
267  break;
268  case LOCKTAG_TUPLE:
269  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
270  values[2] = ObjectIdGetDatum(instance->locktag.locktag_field2);
271  values[3] = UInt32GetDatum(instance->locktag.locktag_field3);
272  values[4] = UInt16GetDatum(instance->locktag.locktag_field4);
273  nulls[5] = true;
274  nulls[6] = true;
275  nulls[7] = true;
276  nulls[8] = true;
277  nulls[9] = true;
278  break;
279  case LOCKTAG_TRANSACTION:
280  values[6] =
282  nulls[1] = true;
283  nulls[2] = true;
284  nulls[3] = true;
285  nulls[4] = true;
286  nulls[5] = true;
287  nulls[7] = true;
288  nulls[8] = true;
289  nulls[9] = true;
290  break;
292  values[5] = VXIDGetDatum(instance->locktag.locktag_field1,
293  instance->locktag.locktag_field2);
294  nulls[1] = true;
295  nulls[2] = true;
296  nulls[3] = true;
297  nulls[4] = true;
298  nulls[6] = true;
299  nulls[7] = true;
300  nulls[8] = true;
301  nulls[9] = true;
302  break;
303  case LOCKTAG_OBJECT:
304  case LOCKTAG_USERLOCK:
305  case LOCKTAG_ADVISORY:
306  default: /* treat unknown locktags like OBJECT */
307  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
308  values[7] = ObjectIdGetDatum(instance->locktag.locktag_field2);
309  values[8] = ObjectIdGetDatum(instance->locktag.locktag_field3);
310  values[9] = Int16GetDatum(instance->locktag.locktag_field4);
311  nulls[2] = true;
312  nulls[3] = true;
313  nulls[4] = true;
314  nulls[5] = true;
315  nulls[6] = true;
316  break;
317  }
318 
319  values[10] = VXIDGetDatum(instance->backend, instance->lxid);
320  if (instance->pid != 0)
321  values[11] = Int32GetDatum(instance->pid);
322  else
323  nulls[11] = true;
324  values[12] = CStringGetTextDatum(GetLockmodeName(instance->locktag.locktag_lockmethodid, mode));
325  values[13] = BoolGetDatum(granted);
326  values[14] = BoolGetDatum(instance->fastpath);
327 
328  tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
329  result = HeapTupleGetDatum(tuple);
330  SRF_RETURN_NEXT(funcctx, result);
331  }
332 
333  /*
334  * Have returned all regular locks. Now start on the SIREAD predicate
335  * locks.
336  */
337  predLockData = mystatus->predLockData;
338  if (mystatus->predLockIdx < predLockData->nelements)
339  {
340  PredicateLockTargetType lockType;
341 
342  PREDICATELOCKTARGETTAG *predTag = &(predLockData->locktags[mystatus->predLockIdx]);
343  SERIALIZABLEXACT *xact = &(predLockData->xacts[mystatus->predLockIdx]);
345  bool nulls[NUM_LOCK_STATUS_COLUMNS];
346  HeapTuple tuple;
347  Datum result;
348 
349  mystatus->predLockIdx++;
350 
351  /*
352  * Form tuple with appropriate data.
353  */
354  MemSet(values, 0, sizeof(values));
355  MemSet(nulls, false, sizeof(nulls));
356 
357  /* lock type */
358  lockType = GET_PREDICATELOCKTARGETTAG_TYPE(*predTag);
359 
360  values[0] = CStringGetTextDatum(PredicateLockTagTypeNames[lockType]);
361 
362  /* lock target */
363  values[1] = GET_PREDICATELOCKTARGETTAG_DB(*predTag);
364  values[2] = GET_PREDICATELOCKTARGETTAG_RELATION(*predTag);
365  if (lockType == PREDLOCKTAG_TUPLE)
366  values[4] = GET_PREDICATELOCKTARGETTAG_OFFSET(*predTag);
367  else
368  nulls[4] = true;
369  if ((lockType == PREDLOCKTAG_TUPLE) ||
370  (lockType == PREDLOCKTAG_PAGE))
371  values[3] = GET_PREDICATELOCKTARGETTAG_PAGE(*predTag);
372  else
373  nulls[3] = true;
374 
375  /* these fields are targets for other types of locks */
376  nulls[5] = true; /* virtualxid */
377  nulls[6] = true; /* transactionid */
378  nulls[7] = true; /* classid */
379  nulls[8] = true; /* objid */
380  nulls[9] = true; /* objsubid */
381 
382  /* lock holder */
383  values[10] = VXIDGetDatum(xact->vxid.backendId,
384  xact->vxid.localTransactionId);
385  if (xact->pid != 0)
386  values[11] = Int32GetDatum(xact->pid);
387  else
388  nulls[11] = true;
389 
390  /*
391  * Lock mode. Currently all predicate locks are SIReadLocks, which are
392  * always held (never waiting) and have no fast path
393  */
394  values[12] = CStringGetTextDatum("SIReadLock");
395  values[13] = BoolGetDatum(true);
396  values[14] = BoolGetDatum(false);
397 
398  tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
399  result = HeapTupleGetDatum(tuple);
400  SRF_RETURN_NEXT(funcctx, result);
401  }
402 
403  SRF_RETURN_DONE(funcctx);
404 }
#define GET_PREDICATELOCKTARGETTAG_RELATION(locktag)
#define GET_PREDICATELOCKTARGETTAG_PAGE(locktag)
static PgChecksumMode mode
Definition: pg_checksums.c:61
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:4016
PredicateLockTargetType
LockInstanceData * locks
Definition: lock.h:446
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
int LOCKMODE
Definition: lockdefs.h:26
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:293
bool fastpath
Definition: lock.h:440
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define Int16GetDatum(X)
Definition: postgres.h:451
#define MemSet(start, val, len)
Definition: c.h:978
SERIALIZABLEXACT * xacts
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
Definition: lock.h:443
LocalTransactionId localTransactionId
Definition: lock.h:65
#define NUM_LOCK_STATUS_COLUMNS
Definition: lockfuncs.c:65
LOCKTAG locktag
Definition: lock.h:433
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:297
LOCKMODE waitLockMode
Definition: lock.h:435
PredicateLockData * GetPredicateLockStatusData(void)
Definition: predicate.c:1373
TupleDesc tuple_desc
Definition: funcapi.h:112
uint16 locktag_field4
Definition: lock.h:168
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
#define LOCKBIT_OFF(lockmode)
Definition: lock.h:87
#define GET_PREDICATELOCKTARGETTAG_OFFSET(locktag)
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2052
LockData * GetLockStatusData(void)
Definition: lock.c:3569
VirtualTransactionId vxid
#define NoLock
Definition: lockdefs.h:34
#define GET_PREDICATELOCKTARGETTAG_TYPE(locktag)
uint32 locktag_field2
Definition: lock.h:166
#define GET_PREDICATELOCKTARGETTAG_DB(locktag)
#define UInt32GetDatum(X)
Definition: postgres.h:493
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
PREDICATELOCKTARGETTAG * locktags
static const char *const PredicateLockTagTypeNames[]
Definition: lockfuncs.c:46
int nelements
Definition: lock.h:445
#define TransactionIdGetDatum(X)
Definition: postgres.h:521
#define MAX_LOCKMODES
Definition: lock.h:84
uintptr_t Datum
Definition: postgres.h:367
BackendId backend
Definition: lock.h:436
#define BoolGetDatum(X)
Definition: postgres.h:402
#define LOCKTAG_LAST_TYPE
Definition: lock.h:151
uint8 locktag_type
Definition: lock.h:169
LocalTransactionId lxid
Definition: lock.h:437
BackendId backendId
Definition: lock.h:64
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
LOCKMASK holdMask
Definition: lock.h:434
uint8 locktag_lockmethodid
Definition: lock.h:170
#define LOCKBIT_ON(lockmode)
Definition: lock.h:86
static Datum values[MAXATTR]
Definition: bootstrap.c:167
PredicateLockData * predLockData
Definition: lockfuncs.c:60
#define Int32GetDatum(X)
Definition: postgres.h:479
void * user_fctx
Definition: funcapi.h:82
void * palloc(Size size)
Definition: mcxt.c:949
LockData * lockData
Definition: lockfuncs.c:58
#define CStringGetTextDatum(s)
Definition: builtins.h:87
const char *const LockTagTypeNames[]
Definition: lockfuncs.c:29
LockTagType
Definition: lock.h:137
uint32 locktag_field1
Definition: lock.h:165
#define snprintf
Definition: port.h:193
#define UInt16GetDatum(X)
Definition: postgres.h:465
int16 AttrNumber
Definition: attnum.h:21
uint32 locktag_field3
Definition: lock.h:167
static Datum VXIDGetDatum(BackendId bid, LocalTransactionId lxid)
Definition: lockfuncs.c:73
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:317
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295

◆ pg_safe_snapshot_blocking_pids()

Datum pg_safe_snapshot_blocking_pids ( PG_FUNCTION_ARGS  )

Definition at line 537 of file lockfuncs.c.

References construct_array(), GetSafeSnapshotBlockingPids(), i, Int32GetDatum, MaxBackends, palloc(), PG_GETARG_INT32, and PG_RETURN_ARRAYTYPE_P.

538 {
539  int blocked_pid = PG_GETARG_INT32(0);
540  int *blockers;
541  int num_blockers;
542  Datum *blocker_datums;
543 
544  /* A buffer big enough for any possible blocker list without truncation */
545  blockers = (int *) palloc(MaxBackends * sizeof(int));
546 
547  /* Collect a snapshot of processes waited for by GetSafeSnapshot */
548  num_blockers =
549  GetSafeSnapshotBlockingPids(blocked_pid, blockers, MaxBackends);
550 
551  /* Convert int array to Datum array */
552  if (num_blockers > 0)
553  {
554  int i;
555 
556  blocker_datums = (Datum *) palloc(num_blockers * sizeof(Datum));
557  for (i = 0; i < num_blockers; ++i)
558  blocker_datums[i] = Int32GetDatum(blockers[i]);
559  }
560  else
561  blocker_datums = NULL;
562 
563  /* Construct array, using hardwired knowledge about int4 type */
564  PG_RETURN_ARRAYTYPE_P(construct_array(blocker_datums, num_blockers,
565  INT4OID,
566  sizeof(int32), true, TYPALIGN_INT));
567 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3313
signed int int32
Definition: c.h:362
int MaxBackends
Definition: globals.c:136
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:253
uintptr_t Datum
Definition: postgres.h:367
#define Int32GetDatum(X)
Definition: postgres.h:479
void * palloc(Size size)
Definition: mcxt.c:949
int i
int GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
Definition: predicate.c:1558

◆ pg_try_advisory_lock_int4()

Datum pg_try_advisory_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 925 of file lockfuncs.c.

References ExclusiveLock, LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT32, PG_RETURN_BOOL, and SET_LOCKTAG_INT32.

926 {
927  int32 key1 = PG_GETARG_INT32(0);
928  int32 key2 = PG_GETARG_INT32(1);
929  LOCKTAG tag;
930  LockAcquireResult res;
931 
932  SET_LOCKTAG_INT32(tag, key1, key2);
933 
934  res = LockAcquire(&tag, ExclusiveLock, true, true);
935 
937 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477

◆ pg_try_advisory_lock_int8()

Datum pg_try_advisory_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 739 of file lockfuncs.c.

References ExclusiveLock, sort-test::key, LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT64, PG_RETURN_BOOL, and SET_LOCKTAG_INT64.

740 {
741  int64 key = PG_GETARG_INT64(0);
742  LOCKTAG tag;
743  LockAcquireResult res;
744 
745  SET_LOCKTAG_INT64(tag, key);
746 
747  res = LockAcquire(&tag, ExclusiveLock, true, true);
748 
750 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_try_advisory_lock_shared_int4()

Datum pg_try_advisory_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 966 of file lockfuncs.c.

References LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT32, PG_RETURN_BOOL, SET_LOCKTAG_INT32, and ShareLock.

967 {
968  int32 key1 = PG_GETARG_INT32(0);
969  int32 key2 = PG_GETARG_INT32(1);
970  LOCKTAG tag;
971  LockAcquireResult res;
972 
973  SET_LOCKTAG_INT32(tag, key1, key2);
974 
975  res = LockAcquire(&tag, ShareLock, true, true);
976 
978 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477
#define ShareLock
Definition: lockdefs.h:41

◆ pg_try_advisory_lock_shared_int8()

Datum pg_try_advisory_lock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 778 of file lockfuncs.c.

References sort-test::key, LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT64, PG_RETURN_BOOL, SET_LOCKTAG_INT64, and ShareLock.

779 {
780  int64 key = PG_GETARG_INT64(0);
781  LOCKTAG tag;
782  LockAcquireResult res;
783 
784  SET_LOCKTAG_INT64(tag, key);
785 
786  res = LockAcquire(&tag, ShareLock, true, true);
787 
789 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:163
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_try_advisory_xact_lock_int4()

Datum pg_try_advisory_xact_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 946 of file lockfuncs.c.

References ExclusiveLock, LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT32, PG_RETURN_BOOL, and SET_LOCKTAG_INT32.

947 {
948  int32 key1 = PG_GETARG_INT32(0);
949  int32 key2 = PG_GETARG_INT32(1);
950  LOCKTAG tag;
951  LockAcquireResult res;
952 
953  SET_LOCKTAG_INT32(tag, key1, key2);
954 
955  res = LockAcquire(&tag, ExclusiveLock, false, true);
956 
958 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477

◆ pg_try_advisory_xact_lock_int8()

Datum pg_try_advisory_xact_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 759 of file lockfuncs.c.

References ExclusiveLock, sort-test::key, LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT64, PG_RETURN_BOOL, and SET_LOCKTAG_INT64.

760 {
761  int64 key = PG_GETARG_INT64(0);
762  LOCKTAG tag;
763  LockAcquireResult res;
764 
765  SET_LOCKTAG_INT64(tag, key);
766 
767  res = LockAcquire(&tag, ExclusiveLock, false, true);
768 
770 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:163
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_try_advisory_xact_lock_shared_int4()

Datum pg_try_advisory_xact_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 987 of file lockfuncs.c.

References LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT32, PG_RETURN_BOOL, SET_LOCKTAG_INT32, and ShareLock.

988 {
989  int32 key1 = PG_GETARG_INT32(0);
990  int32 key2 = PG_GETARG_INT32(1);
991  LOCKTAG tag;
992  LockAcquireResult res;
993 
994  SET_LOCKTAG_INT32(tag, key1, key2);
995 
996  res = LockAcquire(&tag, ShareLock, false, true);
997 
999 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:664
Definition: lock.h:163
signed int int32
Definition: c.h:362
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477
#define ShareLock
Definition: lockdefs.h:41

◆ pg_try_advisory_xact_lock_shared_int8()

Datum pg_try_advisory_xact_lock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 798 of file lockfuncs.c.

References sort-test::key, LockAcquire(), LOCKACQUIRE_NOT_AVAIL, PG_GETARG_INT64, PG_RETURN_BOOL, SET_LOCKTAG_INT64, and ShareLock.

799 {
800  int64 key = PG_GETARG_INT64(0);
801  LOCKTAG tag;
802  LockAcquireResult res;
803 
804  SET_LOCKTAG_INT64(tag, key);
805 
806  res = LockAcquire(&tag, ShareLock, false, true);
807 
809 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:163
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:477
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:658
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ StaticAssertDecl() [1/2]

StaticAssertDecl ( lengthof(LockTagTypeNames = =(LOCKTAG_ADVISORY+1),
"array length mismatch"   
)

◆ StaticAssertDecl() [2/2]

StaticAssertDecl ( lengthof(PredicateLockTagTypeNames = =(PREDLOCKTAG_TUPLE+1),
"array length mismatch"   
)

◆ VXIDGetDatum()

static Datum VXIDGetDatum ( BackendId  bid,
LocalTransactionId  lxid 
)
static

Definition at line 73 of file lockfuncs.c.

References CStringGetTextDatum, and snprintf.

Referenced by pg_lock_status().

74 {
75  /*
76  * The representation is "<bid>/<lxid>", decimal and unsigned decimal
77  * respectively. Note that elog.c also knows how to format a vxid.
78  */
79  char vxidstr[32];
80 
81  snprintf(vxidstr, sizeof(vxidstr), "%d/%u", bid, lxid);
82 
83  return CStringGetTextDatum(vxidstr);
84 }
#define CStringGetTextDatum(s)
Definition: builtins.h:87
#define snprintf
Definition: port.h:193

Variable Documentation

◆ LockTagTypeNames

const char* const LockTagTypeNames[]
Initial value:
= {
"relation",
"extend",
"page",
"tuple",
"transactionid",
"virtualxid",
"spectoken",
"object",
"userlock",
"advisory"
}

Definition at line 29 of file lockfuncs.c.

Referenced by GetLockNameFromTagType(), and pg_lock_status().

◆ PredicateLockTagTypeNames

const char* const PredicateLockTagTypeNames[]
static
Initial value:
= {
"relation",
"page",
"tuple"
}

Definition at line 46 of file lockfuncs.c.

Referenced by pg_lock_status().