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

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

866 {
867  int32 key1 = PG_GETARG_INT32(0);
868  int32 key2 = PG_GETARG_INT32(1);
869  LOCKTAG tag;
870 
871  SET_LOCKTAG_INT32(tag, key1, key2);
872 
873  (void) LockAcquire(&tag, ExclusiveLock, true, false);
874 
875  PG_RETURN_VOID();
876 }
#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:676
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
signed int int32
Definition: c.h:363
#define PG_RETURN_VOID()
Definition: fmgr.h:348

◆ pg_advisory_lock_int8()

Datum pg_advisory_lock_int8 ( PG_FUNCTION_ARGS  )

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

684 {
685  int64 key = PG_GETARG_INT64(0);
686  LOCKTAG tag;
687 
688  SET_LOCKTAG_INT64(tag, key);
689 
690  (void) LockAcquire(&tag, ExclusiveLock, true, false);
691 
692  PG_RETURN_VOID();
693 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#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 900 of file lockfuncs.c.

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

901 {
902  int32 key1 = PG_GETARG_INT32(0);
903  int32 key2 = PG_GETARG_INT32(1);
904  LOCKTAG tag;
905 
906  SET_LOCKTAG_INT32(tag, key1, key2);
907 
908  (void) LockAcquire(&tag, ShareLock, true, false);
909 
910  PG_RETURN_VOID();
911 }
#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:676
Definition: lock.h:164
signed int int32
Definition: c.h:363
#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 716 of file lockfuncs.c.

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

717 {
718  int64 key = PG_GETARG_INT64(0);
719  LOCKTAG tag;
720 
721  SET_LOCKTAG_INT64(tag, key);
722 
723  (void) LockAcquire(&tag, ShareLock, true, false);
724 
725  PG_RETURN_VOID();
726 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:164
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_advisory_unlock_all()

Datum pg_advisory_unlock_all ( PG_FUNCTION_ARGS  )

Definition at line 1057 of file lockfuncs.c.

References LockReleaseSession(), PG_RETURN_VOID, and USER_LOCKMETHOD.

1058 {
1060 
1061  PG_RETURN_VOID();
1062 }
#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 1019 of file lockfuncs.c.

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

1020 {
1021  int32 key1 = PG_GETARG_INT32(0);
1022  int32 key2 = PG_GETARG_INT32(1);
1023  LOCKTAG tag;
1024  bool res;
1025 
1026  SET_LOCKTAG_INT32(tag, key1, key2);
1027 
1028  res = LockRelease(&tag, ExclusiveLock, true);
1029 
1030  PG_RETURN_BOOL(res);
1031 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:676
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
signed int int32
Definition: c.h:363
#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 829 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().

830 {
831  int64 key = PG_GETARG_INT64(0);
832  LOCKTAG tag;
833  bool res;
834 
835  SET_LOCKTAG_INT64(tag, key);
836 
837  res = LockRelease(&tag, ExclusiveLock, true);
838 
839  PG_RETURN_BOOL(res);
840 }
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
#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:670
#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 1039 of file lockfuncs.c.

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

1040 {
1041  int32 key1 = PG_GETARG_INT32(0);
1042  int32 key2 = PG_GETARG_INT32(1);
1043  LOCKTAG tag;
1044  bool res;
1045 
1046  SET_LOCKTAG_INT32(tag, key1, key2);
1047 
1048  res = LockRelease(&tag, ShareLock, true);
1049 
1050  PG_RETURN_BOOL(res);
1051 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define SET_LOCKTAG_INT32(tag, key1, key2)
Definition: lockfuncs.c:676
Definition: lock.h:164
signed int int32
Definition: c.h:363
#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 848 of file lockfuncs.c.

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

849 {
850  int64 key = PG_GETARG_INT64(0);
851  LOCKTAG tag;
852  bool res;
853 
854  SET_LOCKTAG_INT64(tag, key);
855 
856  res = LockRelease(&tag, ShareLock, true);
857 
858  PG_RETURN_BOOL(res);
859 }
Definition: lock.h:164
#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:670
#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 883 of file lockfuncs.c.

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

884 {
885  int32 key1 = PG_GETARG_INT32(0);
886  int32 key2 = PG_GETARG_INT32(1);
887  LOCKTAG tag;
888 
889  SET_LOCKTAG_INT32(tag, key1, key2);
890 
891  (void) LockAcquire(&tag, ExclusiveLock, false, false);
892 
893  PG_RETURN_VOID();
894 }
#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:676
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
signed int int32
Definition: c.h:363
#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 700 of file lockfuncs.c.

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

701 {
702  int64 key = PG_GETARG_INT64(0);
703  LOCKTAG tag;
704 
705  SET_LOCKTAG_INT64(tag, key);
706 
707  (void) LockAcquire(&tag, ExclusiveLock, false, false);
708 
709  PG_RETURN_VOID();
710 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#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 918 of file lockfuncs.c.

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

919 {
920  int32 key1 = PG_GETARG_INT32(0);
921  int32 key2 = PG_GETARG_INT32(1);
922  LOCKTAG tag;
923 
924  SET_LOCKTAG_INT32(tag, key1, key2);
925 
926  (void) LockAcquire(&tag, ShareLock, false, false);
927 
928  PG_RETURN_VOID();
929 }
#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:676
Definition: lock.h:164
signed int int32
Definition: c.h:363
#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 733 of file lockfuncs.c.

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

734 {
735  int64 key = PG_GETARG_INT64(0);
736  LOCKTAG tag;
737 
738  SET_LOCKTAG_INT64(tag, key);
739 
740  (void) LockAcquire(&tag, ShareLock, false, false);
741 
742  PG_RETURN_VOID();
743 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:164
#define PG_RETURN_VOID()
Definition: fmgr.h:348
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ pg_blocking_pids()

Datum pg_blocking_pids ( PG_FUNCTION_ARGS  )

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

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

◆ pg_isolation_test_session_is_blocked()

Datum pg_isolation_test_session_is_blocked ( PG_FUNCTION_ARGS  )

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

595 {
596  int blocked_pid = PG_GETARG_INT32(0);
597  ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
598  ArrayType *blocking_pids_a;
599  int32 *interesting_pids;
600  int32 *blocking_pids;
601  int num_interesting_pids;
602  int num_blocking_pids;
603  int dummy;
604  int i,
605  j;
606 
607  /* Validate the passed-in array */
608  Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
609  if (array_contains_nulls(interesting_pids_a))
610  elog(ERROR, "array must not contain nulls");
611  interesting_pids = (int32 *) ARR_DATA_PTR(interesting_pids_a);
612  num_interesting_pids = ArrayGetNItems(ARR_NDIM(interesting_pids_a),
613  ARR_DIMS(interesting_pids_a));
614 
615  /*
616  * Get the PIDs of all sessions blocking the given session's attempt to
617  * acquire heavyweight locks.
618  */
619  blocking_pids_a =
621 
622  Assert(ARR_ELEMTYPE(blocking_pids_a) == INT4OID);
623  Assert(!array_contains_nulls(blocking_pids_a));
624  blocking_pids = (int32 *) ARR_DATA_PTR(blocking_pids_a);
625  num_blocking_pids = ArrayGetNItems(ARR_NDIM(blocking_pids_a),
626  ARR_DIMS(blocking_pids_a));
627 
628  /*
629  * Check if any of these are in the list of interesting PIDs, that being
630  * the sessions that the isolation tester is running. We don't use
631  * "arrayoverlaps" here, because it would lead to cache lookups and one of
632  * our goals is to run quickly under CLOBBER_CACHE_ALWAYS. We expect
633  * blocking_pids to be usually empty and otherwise a very small number in
634  * isolation tester cases, so make that the outer loop of a naive search
635  * for a match.
636  */
637  for (i = 0; i < num_blocking_pids; i++)
638  for (j = 0; j < num_interesting_pids; j++)
639  {
640  if (blocking_pids[i] == interesting_pids[j])
641  PG_RETURN_BOOL(true);
642  }
643 
644  /*
645  * Check if blocked_pid is waiting for a safe snapshot. We could in
646  * theory check the resulting array of blocker PIDs against the
647  * interesting PIDs whitelist, but since there is no danger of autovacuum
648  * blocking GetSafeSnapshot there seems to be no point in expending cycles
649  * on allocating a buffer and searching for overlap; so it's presently
650  * sufficient for the isolation tester's purposes to use a single element
651  * buffer and check if the number of safe snapshot blockers is non-zero.
652  */
653  if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0)
654  PG_RETURN_BOOL(true);
655 
656  PG_RETURN_BOOL(false);
657 }
#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:363
#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:439
#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:746
#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:1556
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 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, TransactionIdGetDatum, FuncCallContext::tuple_desc, TupleDescInitEntry(), UInt16GetDatum, UInt32GetDatum, FuncCallContext::user_fctx, values, SERIALIZABLEXACT::vxid, VXIDGetDatum(), LockInstanceData::waitLockMode, 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 
146  funcctx->tuple_desc = BlessTupleDesc(tupdesc);
147 
148  /*
149  * Collect all the locking information that we will format and send
150  * out as a result set.
151  */
152  mystatus = (PG_Lock_Status *) palloc(sizeof(PG_Lock_Status));
153  funcctx->user_fctx = (void *) mystatus;
154 
155  mystatus->lockData = GetLockStatusData();
156  mystatus->currIdx = 0;
158  mystatus->predLockIdx = 0;
159 
160  MemoryContextSwitchTo(oldcontext);
161  }
162 
163  funcctx = SRF_PERCALL_SETUP();
164  mystatus = (PG_Lock_Status *) funcctx->user_fctx;
165  lockData = mystatus->lockData;
166 
167  while (mystatus->currIdx < lockData->nelements)
168  {
169  bool granted;
170  LOCKMODE mode = 0;
171  const char *locktypename;
172  char tnbuf[32];
174  bool nulls[NUM_LOCK_STATUS_COLUMNS];
175  HeapTuple tuple;
176  Datum result;
177  LockInstanceData *instance;
178 
179  instance = &(lockData->locks[mystatus->currIdx]);
180 
181  /*
182  * Look to see if there are any held lock modes in this PROCLOCK. If
183  * so, report, and destructively modify lockData so we don't report
184  * again.
185  */
186  granted = false;
187  if (instance->holdMask)
188  {
189  for (mode = 0; mode < MAX_LOCKMODES; mode++)
190  {
191  if (instance->holdMask & LOCKBIT_ON(mode))
192  {
193  granted = true;
194  instance->holdMask &= LOCKBIT_OFF(mode);
195  break;
196  }
197  }
198  }
199 
200  /*
201  * If no (more) held modes to report, see if PROC is waiting for a
202  * lock on this lock.
203  */
204  if (!granted)
205  {
206  if (instance->waitLockMode != NoLock)
207  {
208  /* Yes, so report it with proper mode */
209  mode = instance->waitLockMode;
210 
211  /*
212  * We are now done with this PROCLOCK, so advance pointer to
213  * continue with next one on next call.
214  */
215  mystatus->currIdx++;
216  }
217  else
218  {
219  /*
220  * Okay, we've displayed all the locks associated with this
221  * PROCLOCK, proceed to the next one.
222  */
223  mystatus->currIdx++;
224  continue;
225  }
226  }
227 
228  /*
229  * Form tuple with appropriate data.
230  */
231  MemSet(values, 0, sizeof(values));
232  MemSet(nulls, false, sizeof(nulls));
233 
234  if (instance->locktag.locktag_type <= LOCKTAG_LAST_TYPE)
235  locktypename = LockTagTypeNames[instance->locktag.locktag_type];
236  else
237  {
238  snprintf(tnbuf, sizeof(tnbuf), "unknown %d",
239  (int) instance->locktag.locktag_type);
240  locktypename = tnbuf;
241  }
242  values[0] = CStringGetTextDatum(locktypename);
243 
244  switch ((LockTagType) instance->locktag.locktag_type)
245  {
246  case LOCKTAG_RELATION:
248  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
249  values[2] = ObjectIdGetDatum(instance->locktag.locktag_field2);
250  nulls[3] = true;
251  nulls[4] = true;
252  nulls[5] = true;
253  nulls[6] = true;
254  nulls[7] = true;
255  nulls[8] = true;
256  nulls[9] = true;
257  break;
259  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
260  nulls[2] = true;
261  nulls[3] = true;
262  nulls[4] = true;
263  nulls[5] = true;
264  nulls[6] = true;
265  nulls[7] = true;
266  nulls[8] = true;
267  nulls[9] = true;
268  break;
269  case LOCKTAG_PAGE:
270  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
271  values[2] = ObjectIdGetDatum(instance->locktag.locktag_field2);
272  values[3] = UInt32GetDatum(instance->locktag.locktag_field3);
273  nulls[4] = true;
274  nulls[5] = true;
275  nulls[6] = true;
276  nulls[7] = true;
277  nulls[8] = true;
278  nulls[9] = true;
279  break;
280  case LOCKTAG_TUPLE:
281  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
282  values[2] = ObjectIdGetDatum(instance->locktag.locktag_field2);
283  values[3] = UInt32GetDatum(instance->locktag.locktag_field3);
284  values[4] = UInt16GetDatum(instance->locktag.locktag_field4);
285  nulls[5] = true;
286  nulls[6] = true;
287  nulls[7] = true;
288  nulls[8] = true;
289  nulls[9] = true;
290  break;
291  case LOCKTAG_TRANSACTION:
292  values[6] =
294  nulls[1] = true;
295  nulls[2] = true;
296  nulls[3] = true;
297  nulls[4] = true;
298  nulls[5] = true;
299  nulls[7] = true;
300  nulls[8] = true;
301  nulls[9] = true;
302  break;
304  values[5] = VXIDGetDatum(instance->locktag.locktag_field1,
305  instance->locktag.locktag_field2);
306  nulls[1] = true;
307  nulls[2] = true;
308  nulls[3] = true;
309  nulls[4] = true;
310  nulls[6] = true;
311  nulls[7] = true;
312  nulls[8] = true;
313  nulls[9] = true;
314  break;
315  case LOCKTAG_OBJECT:
316  case LOCKTAG_USERLOCK:
317  case LOCKTAG_ADVISORY:
318  default: /* treat unknown locktags like OBJECT */
319  values[1] = ObjectIdGetDatum(instance->locktag.locktag_field1);
320  values[7] = ObjectIdGetDatum(instance->locktag.locktag_field2);
321  values[8] = ObjectIdGetDatum(instance->locktag.locktag_field3);
322  values[9] = Int16GetDatum(instance->locktag.locktag_field4);
323  nulls[2] = true;
324  nulls[3] = true;
325  nulls[4] = true;
326  nulls[5] = true;
327  nulls[6] = true;
328  break;
329  }
330 
331  values[10] = VXIDGetDatum(instance->backend, instance->lxid);
332  if (instance->pid != 0)
333  values[11] = Int32GetDatum(instance->pid);
334  else
335  nulls[11] = true;
336  values[12] = CStringGetTextDatum(GetLockmodeName(instance->locktag.locktag_lockmethodid, mode));
337  values[13] = BoolGetDatum(granted);
338  values[14] = BoolGetDatum(instance->fastpath);
339 
340  tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
341  result = HeapTupleGetDatum(tuple);
342  SRF_RETURN_NEXT(funcctx, result);
343  }
344 
345  /*
346  * Have returned all regular locks. Now start on the SIREAD predicate
347  * locks.
348  */
349  predLockData = mystatus->predLockData;
350  if (mystatus->predLockIdx < predLockData->nelements)
351  {
352  PredicateLockTargetType lockType;
353 
354  PREDICATELOCKTARGETTAG *predTag = &(predLockData->locktags[mystatus->predLockIdx]);
355  SERIALIZABLEXACT *xact = &(predLockData->xacts[mystatus->predLockIdx]);
357  bool nulls[NUM_LOCK_STATUS_COLUMNS];
358  HeapTuple tuple;
359  Datum result;
360 
361  mystatus->predLockIdx++;
362 
363  /*
364  * Form tuple with appropriate data.
365  */
366  MemSet(values, 0, sizeof(values));
367  MemSet(nulls, false, sizeof(nulls));
368 
369  /* lock type */
370  lockType = GET_PREDICATELOCKTARGETTAG_TYPE(*predTag);
371 
372  values[0] = CStringGetTextDatum(PredicateLockTagTypeNames[lockType]);
373 
374  /* lock target */
375  values[1] = GET_PREDICATELOCKTARGETTAG_DB(*predTag);
376  values[2] = GET_PREDICATELOCKTARGETTAG_RELATION(*predTag);
377  if (lockType == PREDLOCKTAG_TUPLE)
378  values[4] = GET_PREDICATELOCKTARGETTAG_OFFSET(*predTag);
379  else
380  nulls[4] = true;
381  if ((lockType == PREDLOCKTAG_TUPLE) ||
382  (lockType == PREDLOCKTAG_PAGE))
383  values[3] = GET_PREDICATELOCKTARGETTAG_PAGE(*predTag);
384  else
385  nulls[3] = true;
386 
387  /* these fields are targets for other types of locks */
388  nulls[5] = true; /* virtualxid */
389  nulls[6] = true; /* transactionid */
390  nulls[7] = true; /* classid */
391  nulls[8] = true; /* objid */
392  nulls[9] = true; /* objsubid */
393 
394  /* lock holder */
395  values[10] = VXIDGetDatum(xact->vxid.backendId,
396  xact->vxid.localTransactionId);
397  if (xact->pid != 0)
398  values[11] = Int32GetDatum(xact->pid);
399  else
400  nulls[11] = true;
401 
402  /*
403  * Lock mode. Currently all predicate locks are SIReadLocks, which are
404  * always held (never waiting) and have no fast path
405  */
406  values[12] = CStringGetTextDatum("SIReadLock");
407  values[13] = BoolGetDatum(true);
408  values[14] = BoolGetDatum(false);
409 
410  tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
411  result = HeapTupleGetDatum(tuple);
412  SRF_RETURN_NEXT(funcctx, result);
413  }
414 
415  SRF_RETURN_DONE(funcctx);
416 }
#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:4015
PredicateLockTargetType
LockInstanceData * locks
Definition: lock.h:456
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
int LOCKMODE
Definition: lockdefs.h:26
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:294
bool fastpath
Definition: lock.h:450
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define Int16GetDatum(X)
Definition: postgres.h:451
#define MemSet(start, val, len)
Definition: c.h:950
SERIALIZABLEXACT * xacts
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
Definition: lock.h:453
LocalTransactionId localTransactionId
Definition: lock.h:65
#define NUM_LOCK_STATUS_COLUMNS
Definition: lockfuncs.c:66
LOCKTAG locktag
Definition: lock.h:443
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:298
LOCKMODE waitLockMode
Definition: lock.h:445
PredicateLockData * GetPredicateLockStatusData(void)
Definition: predicate.c:1371
TupleDesc tuple_desc
Definition: funcapi.h:112
uint16 locktag_field4
Definition: lock.h:169
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:300
#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:167
#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:47
int nelements
Definition: lock.h:455
#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:446
#define BoolGetDatum(X)
Definition: postgres.h:402
#define LOCKTAG_LAST_TYPE
Definition: lock.h:152
uint8 locktag_type
Definition: lock.h:170
LocalTransactionId lxid
Definition: lock.h:447
BackendId backendId
Definition: lock.h:64
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
LOCKMASK holdMask
Definition: lock.h:444
uint8 locktag_lockmethodid
Definition: lock.h:171
#define LOCKBIT_ON(lockmode)
Definition: lock.h:86
static Datum values[MAXATTR]
Definition: bootstrap.c:165
PredicateLockData * predLockData
Definition: lockfuncs.c:61
#define Int32GetDatum(X)
Definition: postgres.h:479
void * user_fctx
Definition: funcapi.h:82
void * palloc(Size size)
Definition: mcxt.c:950
LockData * lockData
Definition: lockfuncs.c:59
#define CStringGetTextDatum(s)
Definition: builtins.h:86
const char *const LockTagTypeNames[]
Definition: lockfuncs.c:29
LockTagType
Definition: lock.h:137
uint32 locktag_field1
Definition: lock.h:166
#define snprintf
Definition: port.h:215
#define UInt16GetDatum(X)
Definition: postgres.h:465
int16 AttrNumber
Definition: attnum.h:21
uint32 locktag_field3
Definition: lock.h:168
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 549 of file lockfuncs.c.

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

550 {
551  int blocked_pid = PG_GETARG_INT32(0);
552  int *blockers;
553  int num_blockers;
554  Datum *blocker_datums;
555 
556  /* A buffer big enough for any possible blocker list without truncation */
557  blockers = (int *) palloc(MaxBackends * sizeof(int));
558 
559  /* Collect a snapshot of processes waited for by GetSafeSnapshot */
560  num_blockers =
561  GetSafeSnapshotBlockingPids(blocked_pid, blockers, MaxBackends);
562 
563  /* Convert int array to Datum array */
564  if (num_blockers > 0)
565  {
566  int i;
567 
568  blocker_datums = (Datum *) palloc(num_blockers * sizeof(Datum));
569  for (i = 0; i < num_blockers; ++i)
570  blocker_datums[i] = Int32GetDatum(blockers[i]);
571  }
572  else
573  blocker_datums = NULL;
574 
575  /* Construct array, using hardwired knowledge about int4 type */
576  PG_RETURN_ARRAYTYPE_P(construct_array(blocker_datums, num_blockers,
577  INT4OID,
578  sizeof(int32), true, TYPALIGN_INT));
579 }
#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:363
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:950
int i
int GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
Definition: predicate.c:1556

◆ pg_try_advisory_lock_int4()

Datum pg_try_advisory_lock_int4 ( PG_FUNCTION_ARGS  )

Definition at line 937 of file lockfuncs.c.

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

938 {
939  int32 key1 = PG_GETARG_INT32(0);
940  int32 key2 = PG_GETARG_INT32(1);
941  LOCKTAG tag;
942  LockAcquireResult res;
943 
944  SET_LOCKTAG_INT32(tag, key1, key2);
945 
946  res = LockAcquire(&tag, ExclusiveLock, true, true);
947 
949 }
#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:676
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
signed int int32
Definition: c.h:363
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487

◆ pg_try_advisory_lock_int8()

Datum pg_try_advisory_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 751 of file lockfuncs.c.

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

752 {
753  int64 key = PG_GETARG_INT64(0);
754  LOCKTAG tag;
755  LockAcquireResult res;
756 
757  SET_LOCKTAG_INT64(tag, key);
758 
759  res = LockAcquire(&tag, ExclusiveLock, true, true);
760 
762 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#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 978 of file lockfuncs.c.

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

979 {
980  int32 key1 = PG_GETARG_INT32(0);
981  int32 key2 = PG_GETARG_INT32(1);
982  LOCKTAG tag;
983  LockAcquireResult res;
984 
985  SET_LOCKTAG_INT32(tag, key1, key2);
986 
987  res = LockAcquire(&tag, ShareLock, true, true);
988 
990 }
#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:676
Definition: lock.h:164
signed int int32
Definition: c.h:363
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487
#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 790 of file lockfuncs.c.

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

791 {
792  int64 key = PG_GETARG_INT64(0);
793  LOCKTAG tag;
794  LockAcquireResult res;
795 
796  SET_LOCKTAG_INT64(tag, key);
797 
798  res = LockAcquire(&tag, ShareLock, true, true);
799 
801 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:164
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#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 958 of file lockfuncs.c.

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

959 {
960  int32 key1 = PG_GETARG_INT32(0);
961  int32 key2 = PG_GETARG_INT32(1);
962  LOCKTAG tag;
963  LockAcquireResult res;
964 
965  SET_LOCKTAG_INT32(tag, key1, key2);
966 
967  res = LockAcquire(&tag, ExclusiveLock, false, true);
968 
970 }
#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:676
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
signed int int32
Definition: c.h:363
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487

◆ pg_try_advisory_xact_lock_int8()

Datum pg_try_advisory_xact_lock_int8 ( PG_FUNCTION_ARGS  )

Definition at line 771 of file lockfuncs.c.

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

772 {
773  int64 key = PG_GETARG_INT64(0);
774  LOCKTAG tag;
775  LockAcquireResult res;
776 
777  SET_LOCKTAG_INT64(tag, key);
778 
779  res = LockAcquire(&tag, ExclusiveLock, false, true);
780 
782 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
#define ExclusiveLock
Definition: lockdefs.h:44
Definition: lock.h:164
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#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 999 of file lockfuncs.c.

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

1000 {
1001  int32 key1 = PG_GETARG_INT32(0);
1002  int32 key2 = PG_GETARG_INT32(1);
1003  LOCKTAG tag;
1004  LockAcquireResult res;
1005 
1006  SET_LOCKTAG_INT32(tag, key1, key2);
1007 
1008  res = LockAcquire(&tag, ShareLock, false, true);
1009 
1011 }
#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:676
Definition: lock.h:164
signed int int32
Definition: c.h:363
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487
#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 810 of file lockfuncs.c.

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

811 {
812  int64 key = PG_GETARG_INT64(0);
813  LOCKTAG tag;
814  LockAcquireResult res;
815 
816  SET_LOCKTAG_INT64(tag, key);
817 
818  res = LockAcquire(&tag, ShareLock, false, true);
819 
821 }
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
Definition: lock.h:164
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
LockAcquireResult
Definition: lock.h:487
#define ShareLock
Definition: lockdefs.h:41
#define SET_LOCKTAG_INT64(tag, key64)
Definition: lockfuncs.c:670
#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 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:86
#define snprintf
Definition: port.h:215

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