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   16
 
#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   16

Definition at line 66 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 872 of file lockfuncs.c.

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

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

◆ pg_advisory_lock_int8()

Datum pg_advisory_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 690 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().

691 {
692  int64 key = PG_GETARG_INT64(0);
693  LOCKTAG tag;
694 
695  SET_LOCKTAG_INT64(tag, key);
696 
697  (void) LockAcquire(&tag, ExclusiveLock, true, false);
698 
699  PG_RETURN_VOID();
700 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_advisory_lock_shared_int4()

Datum pg_advisory_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 907 of file lockfuncs.c.

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

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

◆ pg_advisory_lock_shared_int8()

Datum pg_advisory_lock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 723 of file lockfuncs.c.

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

724 {
725  int64 key = PG_GETARG_INT64(0);
726  LOCKTAG tag;
727 
728  SET_LOCKTAG_INT64(tag, key);
729 
730  (void) LockAcquire(&tag, ShareLock, true, false);
731 
732  PG_RETURN_VOID();
733 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
Definition: lock.h:166
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_advisory_unlock_all()

Datum pg_advisory_unlock_all ( PG_FUNCTION_ARGS  )

Definition at line 1064 of file lockfuncs.c.

References LockReleaseSession(), PG_RETURN_VOID, and USER_LOCKMETHOD.

1065 {
1067 
1068  PG_RETURN_VOID();
1069 }
#define USER_LOCKMETHOD
Definition: lock.h:130
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void LockReleaseSession(LOCKMETHODID lockmethodid)
Definition: lock.c:2453

◆ pg_advisory_unlock_int4()

Datum pg_advisory_unlock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1026 of file lockfuncs.c.

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

1027 {
1028  int32 key1 = PG_GETARG_INT32(0);
1029  int32 key2 = PG_GETARG_INT32(1);
1030  LOCKTAG tag;
1031  bool res;
1032 
1033  SET_LOCKTAG_INT32(tag, key1, key2);
1034 
1035  res = LockRelease(&tag, ExclusiveLock, true);
1036 
1037  PG_RETURN_BOOL(res);
1038 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1974

◆ pg_advisory_unlock_int8()

Datum pg_advisory_unlock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 836 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().

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, ExclusiveLock, true);
845 
846  PG_RETURN_BOOL(res);
847 }
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1974
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_advisory_unlock_shared_int4()

Datum pg_advisory_unlock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1046 of file lockfuncs.c.

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

1047 {
1048  int32 key1 = PG_GETARG_INT32(0);
1049  int32 key2 = PG_GETARG_INT32(1);
1050  LOCKTAG tag;
1051  bool res;
1052 
1053  SET_LOCKTAG_INT32(tag, key1, key2);
1054 
1055  res = LockRelease(&tag, ShareLock, true);
1056 
1057  PG_RETURN_BOOL(res);
1058 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define ShareLock
Definition: lockdefs.h:41
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1974

◆ pg_advisory_unlock_shared_int8()

Datum pg_advisory_unlock_shared_int8 ( PG_FUNCTION_ARGS  )

Definition at line 855 of file lockfuncs.c.

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

856 {
857  int64 key = PG_GETARG_INT64(0);
858  LOCKTAG tag;
859  bool res;
860 
861  SET_LOCKTAG_INT64(tag, key);
862 
863  res = LockRelease(&tag, ShareLock, true);
864 
865  PG_RETURN_BOOL(res);
866 }
Definition: lock.h:166
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define ShareLock
Definition: lockdefs.h:41
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1974
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_advisory_xact_lock_int4()

Datum pg_advisory_xact_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 890 of file lockfuncs.c.

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

891 {
892  int32 key1 = PG_GETARG_INT32(0);
893  int32 key2 = PG_GETARG_INT32(1);
894  LOCKTAG tag;
895 
896  SET_LOCKTAG_INT32(tag, key1, key2);
897 
898  (void) LockAcquire(&tag, ExclusiveLock, false, false);
899 
900  PG_RETURN_VOID();
901 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_VOID()
Definition: fmgr.h:349

◆ pg_advisory_xact_lock_int8()

Datum pg_advisory_xact_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 707 of file lockfuncs.c.

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

708 {
709  int64 key = PG_GETARG_INT64(0);
710  LOCKTAG tag;
711 
712  SET_LOCKTAG_INT64(tag, key);
713 
714  (void) LockAcquire(&tag, ExclusiveLock, false, false);
715 
716  PG_RETURN_VOID();
717 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_advisory_xact_lock_shared_int4()

Datum pg_advisory_xact_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 925 of file lockfuncs.c.

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

926 {
927  int32 key1 = PG_GETARG_INT32(0);
928  int32 key2 = PG_GETARG_INT32(1);
929  LOCKTAG tag;
930 
931  SET_LOCKTAG_INT32(tag, key1, key2);
932 
933  (void) LockAcquire(&tag, ShareLock, false, false);
934 
935  PG_RETURN_VOID();
936 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#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 740 of file lockfuncs.c.

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

741 {
742  int64 key = PG_GETARG_INT64(0);
743  LOCKTAG tag;
744 
745  SET_LOCKTAG_INT64(tag, key);
746 
747  (void) LockAcquire(&tag, ShareLock, false, false);
748 
749  PG_RETURN_VOID();
750 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
Definition: lock.h:166
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_blocking_pids()

Datum pg_blocking_pids ( PG_FUNCTION_ARGS  )

Definition at line 446 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().

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

◆ pg_isolation_test_session_is_blocked()

Datum pg_isolation_test_session_is_blocked ( PG_FUNCTION_ARGS  )

Definition at line 601 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.

602 {
603  int blocked_pid = PG_GETARG_INT32(0);
604  ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
605  ArrayType *blocking_pids_a;
606  int32 *interesting_pids;
607  int32 *blocking_pids;
608  int num_interesting_pids;
609  int num_blocking_pids;
610  int dummy;
611  int i,
612  j;
613 
614  /* Validate the passed-in array */
615  Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
616  if (array_contains_nulls(interesting_pids_a))
617  elog(ERROR, "array must not contain nulls");
618  interesting_pids = (int32 *) ARR_DATA_PTR(interesting_pids_a);
619  num_interesting_pids = ArrayGetNItems(ARR_NDIM(interesting_pids_a),
620  ARR_DIMS(interesting_pids_a));
621 
622  /*
623  * Get the PIDs of all sessions blocking the given session's attempt to
624  * acquire heavyweight locks.
625  */
626  blocking_pids_a =
628 
629  Assert(ARR_ELEMTYPE(blocking_pids_a) == INT4OID);
630  Assert(!array_contains_nulls(blocking_pids_a));
631  blocking_pids = (int32 *) ARR_DATA_PTR(blocking_pids_a);
632  num_blocking_pids = ArrayGetNItems(ARR_NDIM(blocking_pids_a),
633  ARR_DIMS(blocking_pids_a));
634 
635  /*
636  * Check if any of these are in the list of interesting PIDs, that being
637  * the sessions that the isolation tester is running. We don't use
638  * "arrayoverlaps" here, because it would lead to cache lookups and one of
639  * our goals is to run quickly with debug_invalidate_system_caches_always > 0. We expect
640  * blocking_pids to be usually empty and otherwise a very small number in
641  * isolation tester cases, so make that the outer loop of a naive search
642  * for a match.
643  */
644  for (i = 0; i < num_blocking_pids; i++)
645  for (j = 0; j < num_interesting_pids; j++)
646  {
647  if (blocking_pids[i] == interesting_pids[j])
648  PG_RETURN_BOOL(true);
649  }
650 
651  /*
652  * Check if blocked_pid is waiting for a safe snapshot. We could in
653  * theory check the resulting array of blocker PIDs against the
654  * interesting PIDs list, but since there is no danger of autovacuum
655  * blocking GetSafeSnapshot there seems to be no point in expending cycles
656  * on allocating a buffer and searching for overlap; so it's presently
657  * sufficient for the isolation tester's purposes to use a single element
658  * buffer and check if the number of safe snapshot blockers is non-zero.
659  */
660  if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0)
661  PG_RETURN_BOOL(true);
662 
663  PG_RETURN_BOOL(false);
664 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
signed int int32
Definition: c.h:429
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ERROR
Definition: elog.h:46
Datum pg_blocking_pids(PG_FUNCTION_ARGS)
Definition: lockfuncs.c:446
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define Assert(condition)
Definition: c.h:804
#define ARR_NDIM(a)
Definition: array.h:283
#define elog(elevel,...)
Definition: elog.h:232
int i
int GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
Definition: predicate.c:1628
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3557
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ pg_lock_status()

Datum pg_lock_status ( PG_FUNCTION_ARGS  )

Definition at line 92 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_DATABASE_FROZEN_IDS, 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, TimestampTzGetDatum, TransactionIdGetDatum, FuncCallContext::tuple_desc, TupleDescInitEntry(), UInt16GetDatum, UInt32GetDatum, FuncCallContext::user_fctx, values, SERIALIZABLEXACT::vxid, VXIDGetDatum(), LockInstanceData::waitLockMode, LockInstanceData::waitStart, and PredicateLockData::xacts.

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

◆ pg_safe_snapshot_blocking_pids()

Datum pg_safe_snapshot_blocking_pids ( PG_FUNCTION_ARGS  )

Definition at line 556 of file lockfuncs.c.

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

557 {
558  int blocked_pid = PG_GETARG_INT32(0);
559  int *blockers;
560  int num_blockers;
561  Datum *blocker_datums;
562 
563  /* A buffer big enough for any possible blocker list without truncation */
564  blockers = (int *) palloc(MaxBackends * sizeof(int));
565 
566  /* Collect a snapshot of processes waited for by GetSafeSnapshot */
567  num_blockers =
568  GetSafeSnapshotBlockingPids(blocked_pid, blockers, MaxBackends);
569 
570  /* Convert int array to Datum array */
571  if (num_blockers > 0)
572  {
573  int i;
574 
575  blocker_datums = (Datum *) palloc(num_blockers * sizeof(Datum));
576  for (i = 0; i < num_blockers; ++i)
577  blocker_datums[i] = Int32GetDatum(blockers[i]);
578  }
579  else
580  blocker_datums = NULL;
581 
582  /* Construct array, using hardwired knowledge about int4 type */
583  PG_RETURN_ARRAYTYPE_P(construct_array(blocker_datums, num_blockers,
584  INT4OID,
585  sizeof(int32), true, TYPALIGN_INT));
586 }
#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:3318
signed int int32
Definition: c.h:429
int MaxBackends
Definition: globals.c:139
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:258
uintptr_t Datum
Definition: postgres.h:411
#define Int32GetDatum(X)
Definition: postgres.h:523
void * palloc(Size size)
Definition: mcxt.c:1062
int i
int GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
Definition: predicate.c:1628

◆ pg_try_advisory_lock_int4()

Datum pg_try_advisory_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 944 of file lockfuncs.c.

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

945 {
946  int32 key1 = PG_GETARG_INT32(0);
947  int32 key2 = PG_GETARG_INT32(1);
948  LOCKTAG tag;
949  LockAcquireResult res;
950 
951  SET_LOCKTAG_INT32(tag, key1, key2);
952 
953  res = LockAcquire(&tag, ExclusiveLock, true, true);
954 
956 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491

◆ pg_try_advisory_lock_int8()

Datum pg_try_advisory_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 758 of file lockfuncs.c.

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

759 {
760  int64 key = PG_GETARG_INT64(0);
761  LOCKTAG tag;
762  LockAcquireResult res;
763 
764  SET_LOCKTAG_INT64(tag, key);
765 
766  res = LockAcquire(&tag, ExclusiveLock, true, true);
767 
769 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_try_advisory_lock_shared_int4()

Datum pg_try_advisory_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 985 of file lockfuncs.c.

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

986 {
987  int32 key1 = PG_GETARG_INT32(0);
988  int32 key2 = PG_GETARG_INT32(1);
989  LOCKTAG tag;
990  LockAcquireResult res;
991 
992  SET_LOCKTAG_INT32(tag, key1, key2);
993 
994  res = LockAcquire(&tag, ShareLock, true, true);
995 
997 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491
#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 797 of file lockfuncs.c.

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

798 {
799  int64 key = PG_GETARG_INT64(0);
800  LOCKTAG tag;
801  LockAcquireResult res;
802 
803  SET_LOCKTAG_INT64(tag, key);
804 
805  res = LockAcquire(&tag, ShareLock, true, true);
806 
808 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
Definition: lock.h:166
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_try_advisory_xact_lock_int4()

Datum pg_try_advisory_xact_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 965 of file lockfuncs.c.

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

966 {
967  int32 key1 = PG_GETARG_INT32(0);
968  int32 key2 = PG_GETARG_INT32(1);
969  LOCKTAG tag;
970  LockAcquireResult res;
971 
972  SET_LOCKTAG_INT32(tag, key1, key2);
973 
974  res = LockAcquire(&tag, ExclusiveLock, false, true);
975 
977 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491

◆ pg_try_advisory_xact_lock_int8()

Datum pg_try_advisory_xact_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 778 of file lockfuncs.c.

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

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, ExclusiveLock, false, true);
787 
789 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:166
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ pg_try_advisory_xact_lock_shared_int4()

Datum pg_try_advisory_xact_lock_shared_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1006 of file lockfuncs.c.

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

1007 {
1008  int32 key1 = PG_GETARG_INT32(0);
1009  int32 key2 = PG_GETARG_INT32(1);
1010  LOCKTAG tag;
1011  LockAcquireResult res;
1012 
1013  SET_LOCKTAG_INT32(tag, key1, key2);
1014 
1015  res = LockAcquire(&tag, ShareLock, false, true);
1016 
1018 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:683
Definition: lock.h:166
signed int int32
Definition: c.h:429
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491
#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 817 of file lockfuncs.c.

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

818 {
819  int64 key = PG_GETARG_INT64(0);
820  LOCKTAG tag;
821  LockAcquireResult res;
822 
823  SET_LOCKTAG_INT64(tag, key);
824 
825  res = LockAcquire(&tag, ShareLock, false, true);
826 
828 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
Definition: lock.h:166
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
LockAcquireResult
Definition: lock.h:491
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:677
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ 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 74 of file lockfuncs.c.

References CStringGetTextDatum, and snprintf.

Referenced by pg_lock_status().

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

Variable Documentation

◆ LockTagTypeNames

const char* const LockTagTypeNames[]
Initial value:
= {
"relation",
"extend",
"frozenid",
"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 47 of file lockfuncs.c.

Referenced by pg_lock_status().