codekingpro/portable-devtools
115k
1/*-------------------------------------------------------------------------2 *3 * lock.h4 * POSTGRES low-level lock mechanism5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/storage/lock.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef LOCK_H_15#define LOCK_H_16 17#ifdef FRONTEND18#error "lock.h may not be included from frontend code"19#endif20 21#include "lib/ilist.h"22#include "storage/backendid.h"23#include "storage/lockdefs.h"24#include "storage/lwlock.h"25#include "storage/shmem.h"26#include "utils/timestamp.h"27 28/* struct PGPROC is declared in proc.h, but must forward-reference it */29typedef struct PGPROC PGPROC;30 31/* GUC variables */32extern PGDLLIMPORT int max_locks_per_xact;33 34#ifdef LOCK_DEBUG35extern PGDLLIMPORT int Trace_lock_oidmin;36extern PGDLLIMPORT bool Trace_locks;37extern PGDLLIMPORT bool Trace_userlocks;38extern PGDLLIMPORT int Trace_lock_table;39extern PGDLLIMPORT bool Debug_deadlocks;40#endif /* LOCK_DEBUG */41 42 43/*44 * Top-level transactions are identified by VirtualTransactionIDs comprising45 * PGPROC fields backendId and lxid. For recovered prepared transactions, the46 * LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never47 * refers to that kind. These are guaranteed unique over the short term, but48 * will be reused after a database restart or XID wraparound; hence they49 * should never be stored on disk.50 *51 * Note that struct VirtualTransactionId can not be assumed to be atomically52 * assignable as a whole. However, type LocalTransactionId is assumed to53 * be atomically assignable, and the backend ID doesn't change often enough54 * to be a problem, so we can fetch or assign the two fields separately.55 * We deliberately refrain from using the struct within PGPROC, to prevent56 * coding errors from trying to use struct assignment with it; instead use57 * GET_VXID_FROM_PGPROC().58 */59typedef struct60{61 BackendId backendId; /* backendId from PGPROC */62 LocalTransactionId localTransactionId; /* lxid from PGPROC */63} VirtualTransactionId;64 65#define InvalidLocalTransactionId 066#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)67#define VirtualTransactionIdIsValid(vxid) \68 (LocalTransactionIdIsValid((vxid).localTransactionId))69#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \70 ((vxid).backendId == InvalidBackendId)71#define VirtualTransactionIdEquals(vxid1, vxid2) \72 ((vxid1).backendId == (vxid2).backendId && \73 (vxid1).localTransactionId == (vxid2).localTransactionId)74#define SetInvalidVirtualTransactionId(vxid) \75 ((vxid).backendId = InvalidBackendId, \76 (vxid).localTransactionId = InvalidLocalTransactionId)77#define GET_VXID_FROM_PGPROC(vxid, proc) \78 ((vxid).backendId = (proc).backendId, \79 (vxid).localTransactionId = (proc).lxid)80 81/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */82#define MAX_LOCKMODES 1083 84#define LOCKBIT_ON(lockmode) (1 << (lockmode))85#define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))86 87 88/*89 * This data structure defines the locking semantics associated with a90 * "lock method". The semantics specify the meaning of each lock mode91 * (by defining which lock modes it conflicts with).92 * All of this data is constant and is kept in const tables.93 *94 * numLockModes -- number of lock modes (READ,WRITE,etc) that95 * are defined in this lock method. Must be less than MAX_LOCKMODES.96 *97 * conflictTab -- this is an array of bitmasks showing lock98 * mode conflicts. conflictTab[i] is a mask with the j-th bit99 * turned on if lock modes i and j conflict. Lock modes are100 * numbered 1..numLockModes; conflictTab[0] is unused.101 *102 * lockModeNames -- ID strings for debug printouts.103 *104 * trace_flag -- pointer to GUC trace flag for this lock method. (The105 * GUC variable is not constant, but we use "const" here to denote that106 * it can't be changed through this reference.)107 */108typedef struct LockMethodData109{110 int numLockModes;111 const LOCKMASK *conflictTab;112 const char *const *lockModeNames;113 const bool *trace_flag;114} LockMethodData;115 116typedef const LockMethodData *LockMethod;117 118/*119 * Lock methods are identified by LOCKMETHODID. (Despite the declaration as120 * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)121 */122typedef uint16 LOCKMETHODID;123 124/* These identify the known lock methods */125#define DEFAULT_LOCKMETHOD 1126#define USER_LOCKMETHOD 2127 128/*129 * LOCKTAG is the key information needed to look up a LOCK item in the130 * lock hashtable. A LOCKTAG value uniquely identifies a lockable object.131 *132 * The LockTagType enum defines the different kinds of objects we can lock.133 * We can handle up to 256 different LockTagTypes.134 */135typedef enum LockTagType136{137 LOCKTAG_RELATION, /* whole relation */138 LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */139 LOCKTAG_DATABASE_FROZEN_IDS, /* pg_database.datfrozenxid */140 LOCKTAG_PAGE, /* one page of a relation */141 LOCKTAG_TUPLE, /* one physical tuple */142 LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */143 LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */144 LOCKTAG_SPECULATIVE_TOKEN, /* speculative insertion Xid and token */145 LOCKTAG_OBJECT, /* non-relation database object */146 LOCKTAG_USERLOCK, /* reserved for old contrib/userlock code */147 LOCKTAG_ADVISORY, /* advisory user locks */148 LOCKTAG_APPLY_TRANSACTION /* transaction being applied on a logical149 * replication subscriber */150} LockTagType;151 152#define LOCKTAG_LAST_TYPE LOCKTAG_APPLY_TRANSACTION153 154extern PGDLLIMPORT const char *const LockTagTypeNames[];155 156/*157 * The LOCKTAG struct is defined with malice aforethought to fit into 16158 * bytes with no padding. Note that this would need adjustment if we were159 * to widen Oid, BlockNumber, or TransactionId to more than 32 bits.160 *161 * We include lockmethodid in the locktag so that a single hash table in162 * shared memory can store locks of different lockmethods.163 */164typedef struct LOCKTAG165{166 uint32 locktag_field1; /* a 32-bit ID field */167 uint32 locktag_field2; /* a 32-bit ID field */168 uint32 locktag_field3; /* a 32-bit ID field */169 uint16 locktag_field4; /* a 16-bit ID field */170 uint8 locktag_type; /* see enum LockTagType */171 uint8 locktag_lockmethodid; /* lockmethod indicator */172} LOCKTAG;173 174/*175 * These macros define how we map logical IDs of lockable objects into176 * the physical fields of LOCKTAG. Use these to set up LOCKTAG values,177 * rather than accessing the fields directly. Note multiple eval of target!178 */179 180/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */181#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \182 ((locktag).locktag_field1 = (dboid), \183 (locktag).locktag_field2 = (reloid), \184 (locktag).locktag_field3 = 0, \185 (locktag).locktag_field4 = 0, \186 (locktag).locktag_type = LOCKTAG_RELATION, \187 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)188 189/* same ID info as RELATION */190#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \191 ((locktag).locktag_field1 = (dboid), \192 (locktag).locktag_field2 = (reloid), \193 (locktag).locktag_field3 = 0, \194 (locktag).locktag_field4 = 0, \195 (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \196 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)197 198/* ID info for frozen IDs is DB OID */199#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \200 ((locktag).locktag_field1 = (dboid), \201 (locktag).locktag_field2 = 0, \202 (locktag).locktag_field3 = 0, \203 (locktag).locktag_field4 = 0, \204 (locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \205 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)206 207/* ID info for a page is RELATION info + BlockNumber */208#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \209 ((locktag).locktag_field1 = (dboid), \210 (locktag).locktag_field2 = (reloid), \211 (locktag).locktag_field3 = (blocknum), \212 (locktag).locktag_field4 = 0, \213 (locktag).locktag_type = LOCKTAG_PAGE, \214 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)215 216/* ID info for a tuple is PAGE info + OffsetNumber */217#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \218 ((locktag).locktag_field1 = (dboid), \219 (locktag).locktag_field2 = (reloid), \220 (locktag).locktag_field3 = (blocknum), \221 (locktag).locktag_field4 = (offnum), \222 (locktag).locktag_type = LOCKTAG_TUPLE, \223 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)224 225/* ID info for a transaction is its TransactionId */226#define SET_LOCKTAG_TRANSACTION(locktag,xid) \227 ((locktag).locktag_field1 = (xid), \228 (locktag).locktag_field2 = 0, \229 (locktag).locktag_field3 = 0, \230 (locktag).locktag_field4 = 0, \231 (locktag).locktag_type = LOCKTAG_TRANSACTION, \232 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)233 234/* ID info for a virtual transaction is its VirtualTransactionId */235#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \236 ((locktag).locktag_field1 = (vxid).backendId, \237 (locktag).locktag_field2 = (vxid).localTransactionId, \238 (locktag).locktag_field3 = 0, \239 (locktag).locktag_field4 = 0, \240 (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \241 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)242 243/*244 * ID info for a speculative insert is TRANSACTION info +245 * its speculative insert counter.246 */247#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \248 ((locktag).locktag_field1 = (xid), \249 (locktag).locktag_field2 = (token), \250 (locktag).locktag_field3 = 0, \251 (locktag).locktag_field4 = 0, \252 (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \253 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)254 255/*256 * ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID257 *258 * Note: object ID has same representation as in pg_depend and259 * pg_description, but notice that we are constraining SUBID to 16 bits.260 * Also, we use DB OID = 0 for shared objects such as tablespaces.261 */262#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \263 ((locktag).locktag_field1 = (dboid), \264 (locktag).locktag_field2 = (classoid), \265 (locktag).locktag_field3 = (objoid), \266 (locktag).locktag_field4 = (objsubid), \267 (locktag).locktag_type = LOCKTAG_OBJECT, \268 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)269 270#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \271 ((locktag).locktag_field1 = (id1), \272 (locktag).locktag_field2 = (id2), \273 (locktag).locktag_field3 = (id3), \274 (locktag).locktag_field4 = (id4), \275 (locktag).locktag_type = LOCKTAG_ADVISORY, \276 (locktag).locktag_lockmethodid = USER_LOCKMETHOD)277 278/*279 * ID info for a remote transaction on a logical replication subscriber is: DB280 * OID + SUBSCRIPTION OID + TRANSACTION ID + OBJID281 */282#define SET_LOCKTAG_APPLY_TRANSACTION(locktag,dboid,suboid,xid,objid) \283 ((locktag).locktag_field1 = (dboid), \284 (locktag).locktag_field2 = (suboid), \285 (locktag).locktag_field3 = (xid), \286 (locktag).locktag_field4 = (objid), \287 (locktag).locktag_type = LOCKTAG_APPLY_TRANSACTION, \288 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)289 290/*291 * Per-locked-object lock information:292 *293 * tag -- uniquely identifies the object being locked294 * grantMask -- bitmask for all lock types currently granted on this object.295 * waitMask -- bitmask for all lock types currently awaited on this object.296 * procLocks -- list of PROCLOCK objects for this lock.297 * waitProcs -- queue of processes waiting for this lock.298 * requested -- count of each lock type currently requested on the lock299 * (includes requests already granted!!).300 * nRequested -- total requested locks of all types.301 * granted -- count of each lock type currently granted on the lock.302 * nGranted -- total granted locks of all types.303 *304 * Note: these counts count 1 for each backend. Internally to a backend,305 * there may be multiple grabs on a particular lock, but this is not reflected306 * into shared memory.307 */308typedef struct LOCK309{310 /* hash key */311 LOCKTAG tag; /* unique identifier of lockable object */312 313 /* data */314 LOCKMASK grantMask; /* bitmask for lock types already granted */315 LOCKMASK waitMask; /* bitmask for lock types awaited */316 dlist_head procLocks; /* list of PROCLOCK objects assoc. with lock */317 dclist_head waitProcs; /* list of PGPROC objects waiting on lock */318 int requested[MAX_LOCKMODES]; /* counts of requested locks */319 int nRequested; /* total of requested[] array */320 int granted[MAX_LOCKMODES]; /* counts of granted locks */321 int nGranted; /* total of granted[] array */322} LOCK;323 324#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)325#define LOCK_LOCKTAG(lock) ((LockTagType) (lock).tag.locktag_type)326 327 328/*329 * We may have several different backends holding or awaiting locks330 * on the same lockable object. We need to store some per-holder/waiter331 * information for each such holder (or would-be holder). This is kept in332 * a PROCLOCK struct.333 *334 * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the335 * proclock hashtable. A PROCLOCKTAG value uniquely identifies the combination336 * of a lockable object and a holder/waiter for that object. (We can use337 * pointers here because the PROCLOCKTAG need only be unique for the lifespan338 * of the PROCLOCK, and it will never outlive the lock or the proc.)339 *340 * Internally to a backend, it is possible for the same lock to be held341 * for different purposes: the backend tracks transaction locks separately342 * from session locks. However, this is not reflected in the shared-memory343 * state: we only track which backend(s) hold the lock. This is OK since a344 * backend can never block itself.345 *346 * The holdMask field shows the already-granted locks represented by this347 * proclock. Note that there will be a proclock object, possibly with348 * zero holdMask, for any lock that the process is currently waiting on.349 * Otherwise, proclock objects whose holdMasks are zero are recycled350 * as soon as convenient.351 *352 * releaseMask is workspace for LockReleaseAll(): it shows the locks due353 * to be released during the current call. This must only be examined or354 * set by the backend owning the PROCLOCK.355 *356 * Each PROCLOCK object is linked into lists for both the associated LOCK357 * object and the owning PGPROC object. Note that the PROCLOCK is entered358 * into these lists as soon as it is created, even if no lock has yet been359 * granted. A PGPROC that is waiting for a lock to be granted will also be360 * linked into the lock's waitProcs queue.361 */362typedef struct PROCLOCKTAG363{364 /* NB: we assume this struct contains no padding! */365 LOCK *myLock; /* link to per-lockable-object information */366 PGPROC *myProc; /* link to PGPROC of owning backend */367} PROCLOCKTAG;368 369typedef struct PROCLOCK370{371 /* tag */372 PROCLOCKTAG tag; /* unique identifier of proclock object */373 374 /* data */375 PGPROC *groupLeader; /* proc's lock group leader, or proc itself */376 LOCKMASK holdMask; /* bitmask for lock types currently held */377 LOCKMASK releaseMask; /* bitmask for lock types to be released */378 dlist_node lockLink; /* list link in LOCK's list of proclocks */379 dlist_node procLink; /* list link in PGPROC's list of proclocks */380} PROCLOCK;381 382#define PROCLOCK_LOCKMETHOD(proclock) \383 LOCK_LOCKMETHOD(*((proclock).tag.myLock))384 385/*386 * Each backend also maintains a local hash table with information about each387 * lock it is currently interested in. In particular the local table counts388 * the number of times that lock has been acquired. This allows multiple389 * requests for the same lock to be executed without additional accesses to390 * shared memory. We also track the number of lock acquisitions per391 * ResourceOwner, so that we can release just those locks belonging to a392 * particular ResourceOwner.393 *394 * When holding a lock taken "normally", the lock and proclock fields always395 * point to the associated objects in shared memory. However, if we acquired396 * the lock via the fast-path mechanism, the lock and proclock fields are set397 * to NULL, since there probably aren't any such objects in shared memory.398 * (If the lock later gets promoted to normal representation, we may eventually399 * update our locallock's lock/proclock fields after finding the shared400 * objects.)401 *402 * Caution: a locallock object can be left over from a failed lock acquisition403 * attempt. In this case its lock/proclock fields are untrustworthy, since404 * the shared lock object is neither held nor awaited, and hence is available405 * to be reclaimed. If nLocks > 0 then these pointers must either be valid or406 * NULL, but when nLocks == 0 they should be considered garbage.407 */408typedef struct LOCALLOCKTAG409{410 LOCKTAG lock; /* identifies the lockable object */411 LOCKMODE mode; /* lock mode for this table entry */412} LOCALLOCKTAG;413 414typedef struct LOCALLOCKOWNER415{416 /*417 * Note: if owner is NULL then the lock is held on behalf of the session;418 * otherwise it is held on behalf of my current transaction.419 *420 * Must use a forward struct reference to avoid circularity.421 */422 struct ResourceOwnerData *owner;423 int64 nLocks; /* # of times held by this owner */424} LOCALLOCKOWNER;425 426typedef struct LOCALLOCK427{428 /* tag */429 LOCALLOCKTAG tag; /* unique identifier of locallock entry */430 431 /* data */432 uint32 hashcode; /* copy of LOCKTAG's hash value */433 LOCK *lock; /* associated LOCK object, if any */434 PROCLOCK *proclock; /* associated PROCLOCK object, if any */435 int64 nLocks; /* total number of times lock is held */436 int numLockOwners; /* # of relevant ResourceOwners */437 int maxLockOwners; /* allocated size of array */438 LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */439 bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */440 bool lockCleared; /* we read all sinval msgs for lock */441} LOCALLOCK;442 443#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)444#define LOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type)445 446 447/*448 * These structures hold information passed from lmgr internals to the lock449 * listing user-level functions (in lockfuncs.c).450 */451 452typedef struct LockInstanceData453{454 LOCKTAG locktag; /* tag for locked object */455 LOCKMASK holdMask; /* locks held by this PGPROC */456 LOCKMODE waitLockMode; /* lock awaited by this PGPROC, if any */457 BackendId backend; /* backend ID of this PGPROC */458 LocalTransactionId lxid; /* local transaction ID of this PGPROC */459 TimestampTz waitStart; /* time at which this PGPROC started waiting460 * for lock */461 int pid; /* pid of this PGPROC */462 int leaderPid; /* pid of group leader; = pid if no group */463 bool fastpath; /* taken via fastpath? */464} LockInstanceData;465 466typedef struct LockData467{468 int nelements; /* The length of the array */469 LockInstanceData *locks; /* Array of per-PROCLOCK information */470} LockData;471 472typedef struct BlockedProcData473{474 int pid; /* pid of a blocked PGPROC */475 /* Per-PROCLOCK information about PROCLOCKs of the lock the pid awaits */476 /* (these fields refer to indexes in BlockedProcsData.locks[]) */477 int first_lock; /* index of first relevant LockInstanceData */478 int num_locks; /* number of relevant LockInstanceDatas */479 /* PIDs of PGPROCs that are ahead of "pid" in the lock's wait queue */480 /* (these fields refer to indexes in BlockedProcsData.waiter_pids[]) */481 int first_waiter; /* index of first preceding waiter */482 int num_waiters; /* number of preceding waiters */483} BlockedProcData;484 485typedef struct BlockedProcsData486{487 BlockedProcData *procs; /* Array of per-blocked-proc information */488 LockInstanceData *locks; /* Array of per-PROCLOCK information */489 int *waiter_pids; /* Array of PIDs of other blocked PGPROCs */490 int nprocs; /* # of valid entries in procs[] array */491 int maxprocs; /* Allocated length of procs[] array */492 int nlocks; /* # of valid entries in locks[] array */493 int maxlocks; /* Allocated length of locks[] array */494 int npids; /* # of valid entries in waiter_pids[] array */495 int maxpids; /* Allocated length of waiter_pids[] array */496} BlockedProcsData;497 498 499/* Result codes for LockAcquire() */500typedef enum501{502 LOCKACQUIRE_NOT_AVAIL, /* lock not available, and dontWait=true */503 LOCKACQUIRE_OK, /* lock successfully acquired */504 LOCKACQUIRE_ALREADY_HELD, /* incremented count for lock already held */505 LOCKACQUIRE_ALREADY_CLEAR /* incremented count for lock already clear */506} LockAcquireResult;507 508/* Deadlock states identified by DeadLockCheck() */509typedef enum510{511 DS_NOT_YET_CHECKED, /* no deadlock check has run yet */512 DS_NO_DEADLOCK, /* no deadlock detected */513 DS_SOFT_DEADLOCK, /* deadlock avoided by queue rearrangement */514 DS_HARD_DEADLOCK, /* deadlock, no way out but ERROR */515 DS_BLOCKED_BY_AUTOVACUUM /* no deadlock; queue blocked by autovacuum516 * worker */517} DeadLockState;518 519/*520 * The lockmgr's shared hash tables are partitioned to reduce contention.521 * To determine which partition a given locktag belongs to, compute the tag's522 * hash code with LockTagHashCode(), then apply one of these macros.523 * NB: NUM_LOCK_PARTITIONS must be a power of 2!524 */525#define LockHashPartition(hashcode) \526 ((hashcode) % NUM_LOCK_PARTITIONS)527#define LockHashPartitionLock(hashcode) \528 (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \529 LockHashPartition(hashcode)].lock)530#define LockHashPartitionLockByIndex(i) \531 (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)532 533/*534 * The deadlock detector needs to be able to access lockGroupLeader and535 * related fields in the PGPROC, so we arrange for those fields to be protected536 * by one of the lock hash partition locks. Since the deadlock detector537 * acquires all such locks anyway, this makes it safe for it to access these538 * fields without doing anything extra. To avoid contention as much as539 * possible, we map different PGPROCs to different partition locks. The lock540 * used for a given lock group is determined by the group leader's pgprocno.541 */542#define LockHashPartitionLockByProc(leader_pgproc) \543 LockHashPartitionLock((leader_pgproc)->pgprocno)544 545/*546 * function prototypes547 */548extern void InitLocks(void);549extern LockMethod GetLocksMethodTable(const LOCK *lock);550extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag);551extern uint32 LockTagHashCode(const LOCKTAG *locktag);552extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2);553extern LockAcquireResult LockAcquire(const LOCKTAG *locktag,554 LOCKMODE lockmode,555 bool sessionLock,556 bool dontWait);557extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag,558 LOCKMODE lockmode,559 bool sessionLock,560 bool dontWait,561 bool reportMemoryError,562 LOCALLOCK **locallockp);563extern void AbortStrongLockAcquire(void);564extern void MarkLockClear(LOCALLOCK *locallock);565extern bool LockRelease(const LOCKTAG *locktag,566 LOCKMODE lockmode, bool sessionLock);567extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);568extern void LockReleaseSession(LOCKMETHODID lockmethodid);569extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks);570extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks);571extern bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode);572#ifdef USE_ASSERT_CHECKING573extern HTAB *GetLockMethodLocalHash(void);574#endif575extern bool LockHasWaiters(const LOCKTAG *locktag,576 LOCKMODE lockmode, bool sessionLock);577extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag,578 LOCKMODE lockmode, int *countp);579extern void AtPrepare_Locks(void);580extern void PostPrepare_Locks(TransactionId xid);581extern bool LockCheckConflicts(LockMethod lockMethodTable,582 LOCKMODE lockmode,583 LOCK *lock, PROCLOCK *proclock);584extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);585extern void GrantAwaitedLock(void);586extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);587extern Size LockShmemSize(void);588extern LockData *GetLockStatusData(void);589extern BlockedProcsData *GetBlockerStatusData(int blocked_pid);590 591extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);592extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);593 594extern void lock_twophase_recover(TransactionId xid, uint16 info,595 void *recdata, uint32 len);596extern void lock_twophase_postcommit(TransactionId xid, uint16 info,597 void *recdata, uint32 len);598extern void lock_twophase_postabort(TransactionId xid, uint16 info,599 void *recdata, uint32 len);600extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,601 void *recdata, uint32 len);602 603extern DeadLockState DeadLockCheck(PGPROC *proc);604extern PGPROC *GetBlockingAutoVacuumPgproc(void);605extern void DeadLockReport(void) pg_attribute_noreturn();606extern void RememberSimpleDeadLock(PGPROC *proc1,607 LOCKMODE lockmode,608 LOCK *lock,609 PGPROC *proc2);610extern void InitDeadLockChecking(void);611 612extern int LockWaiterCount(const LOCKTAG *locktag);613 614#ifdef LOCK_DEBUG615extern void DumpLocks(PGPROC *proc);616extern void DumpAllLocks(void);617#endif618 619/* Lock a VXID (used to wait for a transaction to finish) */620extern void VirtualXactLockTableInsert(VirtualTransactionId vxid);621extern void VirtualXactLockTableCleanup(void);622extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait);623 624#endif /* LOCK_H_ */625 