Header And Logo

PostgreSQL
| The world's most advanced open source database.

lock.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * lock.h
00004  *    POSTGRES low-level lock mechanism
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * src/include/storage/lock.h
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #ifndef LOCK_H_
00015 #define LOCK_H_
00016 
00017 #include "storage/backendid.h"
00018 #include "storage/lwlock.h"
00019 #include "storage/shmem.h"
00020 
00021 
00022 /* struct PGPROC is declared in proc.h, but must forward-reference it */
00023 typedef struct PGPROC PGPROC;
00024 
00025 typedef struct PROC_QUEUE
00026 {
00027     SHM_QUEUE   links;          /* head of list of PGPROC objects */
00028     int         size;           /* number of entries in list */
00029 } PROC_QUEUE;
00030 
00031 /* GUC variables */
00032 extern int  max_locks_per_xact;
00033 
00034 #ifdef LOCK_DEBUG
00035 extern int  Trace_lock_oidmin;
00036 extern bool Trace_locks;
00037 extern bool Trace_userlocks;
00038 extern int  Trace_lock_table;
00039 extern bool Debug_deadlocks;
00040 #endif   /* LOCK_DEBUG */
00041 
00042 
00043 /*
00044  * Top-level transactions are identified by VirtualTransactionIDs comprising
00045  * the BackendId of the backend running the xact, plus a locally-assigned
00046  * LocalTransactionId.  These are guaranteed unique over the short term,
00047  * but will be reused after a database restart; hence they should never
00048  * be stored on disk.
00049  *
00050  * Note that struct VirtualTransactionId can not be assumed to be atomically
00051  * assignable as a whole.  However, type LocalTransactionId is assumed to
00052  * be atomically assignable, and the backend ID doesn't change often enough
00053  * to be a problem, so we can fetch or assign the two fields separately.
00054  * We deliberately refrain from using the struct within PGPROC, to prevent
00055  * coding errors from trying to use struct assignment with it; instead use
00056  * GET_VXID_FROM_PGPROC().
00057  */
00058 typedef struct
00059 {
00060     BackendId   backendId;      /* determined at backend startup */
00061     LocalTransactionId localTransactionId;      /* backend-local transaction
00062                                                  * id */
00063 } VirtualTransactionId;
00064 
00065 #define InvalidLocalTransactionId       0
00066 #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
00067 #define VirtualTransactionIdIsValid(vxid) \
00068     (((vxid).backendId != InvalidBackendId) && \
00069      LocalTransactionIdIsValid((vxid).localTransactionId))
00070 #define VirtualTransactionIdEquals(vxid1, vxid2) \
00071     ((vxid1).backendId == (vxid2).backendId && \
00072      (vxid1).localTransactionId == (vxid2).localTransactionId)
00073 #define SetInvalidVirtualTransactionId(vxid) \
00074     ((vxid).backendId = InvalidBackendId, \
00075      (vxid).localTransactionId = InvalidLocalTransactionId)
00076 #define GET_VXID_FROM_PGPROC(vxid, proc) \
00077     ((vxid).backendId = (proc).backendId, \
00078      (vxid).localTransactionId = (proc).lxid)
00079 
00080 
00081 /*
00082  * LOCKMODE is an integer (1..N) indicating a lock type.  LOCKMASK is a bit
00083  * mask indicating a set of held or requested lock types (the bit 1<<mode
00084  * corresponds to a particular lock mode).
00085  */
00086 typedef int LOCKMASK;
00087 typedef int LOCKMODE;
00088 
00089 /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
00090 #define MAX_LOCKMODES       10
00091 
00092 #define LOCKBIT_ON(lockmode) (1 << (lockmode))
00093 #define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))
00094 
00095 
00096 /*
00097  * This data structure defines the locking semantics associated with a
00098  * "lock method".  The semantics specify the meaning of each lock mode
00099  * (by defining which lock modes it conflicts with).
00100  * All of this data is constant and is kept in const tables.
00101  *
00102  * numLockModes -- number of lock modes (READ,WRITE,etc) that
00103  *      are defined in this lock method.  Must be less than MAX_LOCKMODES.
00104  *
00105  * conflictTab -- this is an array of bitmasks showing lock
00106  *      mode conflicts.  conflictTab[i] is a mask with the j-th bit
00107  *      turned on if lock modes i and j conflict.  Lock modes are
00108  *      numbered 1..numLockModes; conflictTab[0] is unused.
00109  *
00110  * lockModeNames -- ID strings for debug printouts.
00111  *
00112  * trace_flag -- pointer to GUC trace flag for this lock method.  (The
00113  * GUC variable is not constant, but we use "const" here to denote that
00114  * it can't be changed through this reference.)
00115  */
00116 typedef struct LockMethodData
00117 {
00118     int         numLockModes;
00119     const LOCKMASK *conflictTab;
00120     const char *const * lockModeNames;
00121     const bool *trace_flag;
00122 } LockMethodData;
00123 
00124 typedef const LockMethodData *LockMethod;
00125 
00126 /*
00127  * Lock methods are identified by LOCKMETHODID.  (Despite the declaration as
00128  * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
00129  */
00130 typedef uint16 LOCKMETHODID;
00131 
00132 /* These identify the known lock methods */
00133 #define DEFAULT_LOCKMETHOD  1
00134 #define USER_LOCKMETHOD     2
00135 
00136 /*
00137  * These are the valid values of type LOCKMODE for all the standard lock
00138  * methods (both DEFAULT and USER).
00139  */
00140 
00141 /* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
00142 #define NoLock                  0
00143 
00144 #define AccessShareLock         1       /* SELECT */
00145 #define RowShareLock            2       /* SELECT FOR UPDATE/FOR SHARE */
00146 #define RowExclusiveLock        3       /* INSERT, UPDATE, DELETE */
00147 #define ShareUpdateExclusiveLock 4      /* VACUUM (non-FULL),ANALYZE, CREATE
00148                                          * INDEX CONCURRENTLY */
00149 #define ShareLock               5       /* CREATE INDEX (WITHOUT CONCURRENTLY) */
00150 #define ShareRowExclusiveLock   6       /* like EXCLUSIVE MODE, but allows ROW
00151                                          * SHARE */
00152 #define ExclusiveLock           7       /* blocks ROW SHARE/SELECT...FOR
00153                                          * UPDATE */
00154 #define AccessExclusiveLock     8       /* ALTER TABLE, DROP TABLE, VACUUM
00155                                          * FULL, and unqualified LOCK TABLE */
00156 
00157 
00158 /*
00159  * LOCKTAG is the key information needed to look up a LOCK item in the
00160  * lock hashtable.  A LOCKTAG value uniquely identifies a lockable object.
00161  *
00162  * The LockTagType enum defines the different kinds of objects we can lock.
00163  * We can handle up to 256 different LockTagTypes.
00164  */
00165 typedef enum LockTagType
00166 {
00167     LOCKTAG_RELATION,           /* whole relation */
00168     /* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
00169     LOCKTAG_RELATION_EXTEND,    /* the right to extend a relation */
00170     /* same ID info as RELATION */
00171     LOCKTAG_PAGE,               /* one page of a relation */
00172     /* ID info for a page is RELATION info + BlockNumber */
00173     LOCKTAG_TUPLE,              /* one physical tuple */
00174     /* ID info for a tuple is PAGE info + OffsetNumber */
00175     LOCKTAG_TRANSACTION,        /* transaction (for waiting for xact done) */
00176     /* ID info for a transaction is its TransactionId */
00177     LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
00178     /* ID info for a virtual transaction is its VirtualTransactionId */
00179     LOCKTAG_OBJECT,             /* non-relation database object */
00180     /* ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID */
00181 
00182     /*
00183      * Note: object ID has same representation as in pg_depend and
00184      * pg_description, but notice that we are constraining SUBID to 16 bits.
00185      * Also, we use DB OID = 0 for shared objects such as tablespaces.
00186      */
00187     LOCKTAG_USERLOCK,           /* reserved for old contrib/userlock code */
00188     LOCKTAG_ADVISORY            /* advisory user locks */
00189 } LockTagType;
00190 
00191 #define LOCKTAG_LAST_TYPE   LOCKTAG_ADVISORY
00192 
00193 /*
00194  * The LOCKTAG struct is defined with malice aforethought to fit into 16
00195  * bytes with no padding.  Note that this would need adjustment if we were
00196  * to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
00197  *
00198  * We include lockmethodid in the locktag so that a single hash table in
00199  * shared memory can store locks of different lockmethods.
00200  */
00201 typedef struct LOCKTAG
00202 {
00203     uint32      locktag_field1; /* a 32-bit ID field */
00204     uint32      locktag_field2; /* a 32-bit ID field */
00205     uint32      locktag_field3; /* a 32-bit ID field */
00206     uint16      locktag_field4; /* a 16-bit ID field */
00207     uint8       locktag_type;   /* see enum LockTagType */
00208     uint8       locktag_lockmethodid;   /* lockmethod indicator */
00209 } LOCKTAG;
00210 
00211 /*
00212  * These macros define how we map logical IDs of lockable objects into
00213  * the physical fields of LOCKTAG.  Use these to set up LOCKTAG values,
00214  * rather than accessing the fields directly.  Note multiple eval of target!
00215  */
00216 #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
00217     ((locktag).locktag_field1 = (dboid), \
00218      (locktag).locktag_field2 = (reloid), \
00219      (locktag).locktag_field3 = 0, \
00220      (locktag).locktag_field4 = 0, \
00221      (locktag).locktag_type = LOCKTAG_RELATION, \
00222      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00223 
00224 #define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
00225     ((locktag).locktag_field1 = (dboid), \
00226      (locktag).locktag_field2 = (reloid), \
00227      (locktag).locktag_field3 = 0, \
00228      (locktag).locktag_field4 = 0, \
00229      (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
00230      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00231 
00232 #define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
00233     ((locktag).locktag_field1 = (dboid), \
00234      (locktag).locktag_field2 = (reloid), \
00235      (locktag).locktag_field3 = (blocknum), \
00236      (locktag).locktag_field4 = 0, \
00237      (locktag).locktag_type = LOCKTAG_PAGE, \
00238      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00239 
00240 #define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
00241     ((locktag).locktag_field1 = (dboid), \
00242      (locktag).locktag_field2 = (reloid), \
00243      (locktag).locktag_field3 = (blocknum), \
00244      (locktag).locktag_field4 = (offnum), \
00245      (locktag).locktag_type = LOCKTAG_TUPLE, \
00246      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00247 
00248 #define SET_LOCKTAG_TRANSACTION(locktag,xid) \
00249     ((locktag).locktag_field1 = (xid), \
00250      (locktag).locktag_field2 = 0, \
00251      (locktag).locktag_field3 = 0, \
00252      (locktag).locktag_field4 = 0, \
00253      (locktag).locktag_type = LOCKTAG_TRANSACTION, \
00254      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00255 
00256 #define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
00257     ((locktag).locktag_field1 = (vxid).backendId, \
00258      (locktag).locktag_field2 = (vxid).localTransactionId, \
00259      (locktag).locktag_field3 = 0, \
00260      (locktag).locktag_field4 = 0, \
00261      (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
00262      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00263 
00264 #define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
00265     ((locktag).locktag_field1 = (dboid), \
00266      (locktag).locktag_field2 = (classoid), \
00267      (locktag).locktag_field3 = (objoid), \
00268      (locktag).locktag_field4 = (objsubid), \
00269      (locktag).locktag_type = LOCKTAG_OBJECT, \
00270      (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
00271 
00272 #define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
00273     ((locktag).locktag_field1 = (id1), \
00274      (locktag).locktag_field2 = (id2), \
00275      (locktag).locktag_field3 = (id3), \
00276      (locktag).locktag_field4 = (id4), \
00277      (locktag).locktag_type = LOCKTAG_ADVISORY, \
00278      (locktag).locktag_lockmethodid = USER_LOCKMETHOD)
00279 
00280 
00281 /*
00282  * Per-locked-object lock information:
00283  *
00284  * tag -- uniquely identifies the object being locked
00285  * grantMask -- bitmask for all lock types currently granted on this object.
00286  * waitMask -- bitmask for all lock types currently awaited on this object.
00287  * procLocks -- list of PROCLOCK objects for this lock.
00288  * waitProcs -- queue of processes waiting for this lock.
00289  * requested -- count of each lock type currently requested on the lock
00290  *      (includes requests already granted!!).
00291  * nRequested -- total requested locks of all types.
00292  * granted -- count of each lock type currently granted on the lock.
00293  * nGranted -- total granted locks of all types.
00294  *
00295  * Note: these counts count 1 for each backend.  Internally to a backend,
00296  * there may be multiple grabs on a particular lock, but this is not reflected
00297  * into shared memory.
00298  */
00299 typedef struct LOCK
00300 {
00301     /* hash key */
00302     LOCKTAG     tag;            /* unique identifier of lockable object */
00303 
00304     /* data */
00305     LOCKMASK    grantMask;      /* bitmask for lock types already granted */
00306     LOCKMASK    waitMask;       /* bitmask for lock types awaited */
00307     SHM_QUEUE   procLocks;      /* list of PROCLOCK objects assoc. with lock */
00308     PROC_QUEUE  waitProcs;      /* list of PGPROC objects waiting on lock */
00309     int         requested[MAX_LOCKMODES];       /* counts of requested locks */
00310     int         nRequested;     /* total of requested[] array */
00311     int         granted[MAX_LOCKMODES]; /* counts of granted locks */
00312     int         nGranted;       /* total of granted[] array */
00313 } LOCK;
00314 
00315 #define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
00316 
00317 
00318 /*
00319  * We may have several different backends holding or awaiting locks
00320  * on the same lockable object.  We need to store some per-holder/waiter
00321  * information for each such holder (or would-be holder).  This is kept in
00322  * a PROCLOCK struct.
00323  *
00324  * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the
00325  * proclock hashtable.  A PROCLOCKTAG value uniquely identifies the combination
00326  * of a lockable object and a holder/waiter for that object.  (We can use
00327  * pointers here because the PROCLOCKTAG need only be unique for the lifespan
00328  * of the PROCLOCK, and it will never outlive the lock or the proc.)
00329  *
00330  * Internally to a backend, it is possible for the same lock to be held
00331  * for different purposes: the backend tracks transaction locks separately
00332  * from session locks.  However, this is not reflected in the shared-memory
00333  * state: we only track which backend(s) hold the lock.  This is OK since a
00334  * backend can never block itself.
00335  *
00336  * The holdMask field shows the already-granted locks represented by this
00337  * proclock.  Note that there will be a proclock object, possibly with
00338  * zero holdMask, for any lock that the process is currently waiting on.
00339  * Otherwise, proclock objects whose holdMasks are zero are recycled
00340  * as soon as convenient.
00341  *
00342  * releaseMask is workspace for LockReleaseAll(): it shows the locks due
00343  * to be released during the current call.  This must only be examined or
00344  * set by the backend owning the PROCLOCK.
00345  *
00346  * Each PROCLOCK object is linked into lists for both the associated LOCK
00347  * object and the owning PGPROC object.  Note that the PROCLOCK is entered
00348  * into these lists as soon as it is created, even if no lock has yet been
00349  * granted.  A PGPROC that is waiting for a lock to be granted will also be
00350  * linked into the lock's waitProcs queue.
00351  */
00352 typedef struct PROCLOCKTAG
00353 {
00354     /* NB: we assume this struct contains no padding! */
00355     LOCK       *myLock;         /* link to per-lockable-object information */
00356     PGPROC     *myProc;         /* link to PGPROC of owning backend */
00357 } PROCLOCKTAG;
00358 
00359 typedef struct PROCLOCK
00360 {
00361     /* tag */
00362     PROCLOCKTAG tag;            /* unique identifier of proclock object */
00363 
00364     /* data */
00365     LOCKMASK    holdMask;       /* bitmask for lock types currently held */
00366     LOCKMASK    releaseMask;    /* bitmask for lock types to be released */
00367     SHM_QUEUE   lockLink;       /* list link in LOCK's list of proclocks */
00368     SHM_QUEUE   procLink;       /* list link in PGPROC's list of proclocks */
00369 } PROCLOCK;
00370 
00371 #define PROCLOCK_LOCKMETHOD(proclock) \
00372     LOCK_LOCKMETHOD(*((proclock).tag.myLock))
00373 
00374 /*
00375  * Each backend also maintains a local hash table with information about each
00376  * lock it is currently interested in.  In particular the local table counts
00377  * the number of times that lock has been acquired.  This allows multiple
00378  * requests for the same lock to be executed without additional accesses to
00379  * shared memory.  We also track the number of lock acquisitions per
00380  * ResourceOwner, so that we can release just those locks belonging to a
00381  * particular ResourceOwner.
00382  */
00383 typedef struct LOCALLOCKTAG
00384 {
00385     LOCKTAG     lock;           /* identifies the lockable object */
00386     LOCKMODE    mode;           /* lock mode for this table entry */
00387 } LOCALLOCKTAG;
00388 
00389 typedef struct LOCALLOCKOWNER
00390 {
00391     /*
00392      * Note: if owner is NULL then the lock is held on behalf of the session;
00393      * otherwise it is held on behalf of my current transaction.
00394      *
00395      * Must use a forward struct reference to avoid circularity.
00396      */
00397     struct ResourceOwnerData *owner;
00398     int64       nLocks;         /* # of times held by this owner */
00399 } LOCALLOCKOWNER;
00400 
00401 typedef struct LOCALLOCK
00402 {
00403     /* tag */
00404     LOCALLOCKTAG tag;           /* unique identifier of locallock entry */
00405 
00406     /* data */
00407     LOCK       *lock;           /* associated LOCK object in shared mem */
00408     PROCLOCK   *proclock;       /* associated PROCLOCK object in shmem */
00409     uint32      hashcode;       /* copy of LOCKTAG's hash value */
00410     int64       nLocks;         /* total number of times lock is held */
00411     int         numLockOwners;  /* # of relevant ResourceOwners */
00412     int         maxLockOwners;  /* allocated size of array */
00413     bool        holdsStrongLockCount;   /* bumped FastPathStrongRelatonLocks? */
00414     LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */
00415 } LOCALLOCK;
00416 
00417 #define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
00418 
00419 
00420 /*
00421  * These structures hold information passed from lmgr internals to the lock
00422  * listing user-level functions (in lockfuncs.c).
00423  */
00424 
00425 typedef struct LockInstanceData
00426 {
00427     LOCKTAG     locktag;        /* locked object */
00428     LOCKMASK    holdMask;       /* locks held by this PGPROC */
00429     LOCKMODE    waitLockMode;   /* lock awaited by this PGPROC, if any */
00430     BackendId   backend;        /* backend ID of this PGPROC */
00431     LocalTransactionId lxid;    /* local transaction ID of this PGPROC */
00432     int         pid;            /* pid of this PGPROC */
00433     bool        fastpath;       /* taken via fastpath? */
00434 } LockInstanceData;
00435 
00436 typedef struct LockData
00437 {
00438     int         nelements;      /* The length of the array */
00439     LockInstanceData *locks;
00440 } LockData;
00441 
00442 
00443 /* Result codes for LockAcquire() */
00444 typedef enum
00445 {
00446     LOCKACQUIRE_NOT_AVAIL,      /* lock not available, and dontWait=true */
00447     LOCKACQUIRE_OK,             /* lock successfully acquired */
00448     LOCKACQUIRE_ALREADY_HELD    /* incremented count for lock already held */
00449 } LockAcquireResult;
00450 
00451 /* Deadlock states identified by DeadLockCheck() */
00452 typedef enum
00453 {
00454     DS_NOT_YET_CHECKED,         /* no deadlock check has run yet */
00455     DS_NO_DEADLOCK,             /* no deadlock detected */
00456     DS_SOFT_DEADLOCK,           /* deadlock avoided by queue rearrangement */
00457     DS_HARD_DEADLOCK,           /* deadlock, no way out but ERROR */
00458     DS_BLOCKED_BY_AUTOVACUUM    /* no deadlock; queue blocked by autovacuum
00459                                  * worker */
00460 } DeadLockState;
00461 
00462 
00463 /*
00464  * The lockmgr's shared hash tables are partitioned to reduce contention.
00465  * To determine which partition a given locktag belongs to, compute the tag's
00466  * hash code with LockTagHashCode(), then apply one of these macros.
00467  * NB: NUM_LOCK_PARTITIONS must be a power of 2!
00468  */
00469 #define LockHashPartition(hashcode) \
00470     ((hashcode) % NUM_LOCK_PARTITIONS)
00471 #define LockHashPartitionLock(hashcode) \
00472     ((LWLockId) (FirstLockMgrLock + LockHashPartition(hashcode)))
00473 
00474 
00475 /*
00476  * function prototypes
00477  */
00478 extern void InitLocks(void);
00479 extern LockMethod GetLocksMethodTable(const LOCK *lock);
00480 extern uint32 LockTagHashCode(const LOCKTAG *locktag);
00481 extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2);
00482 extern LockAcquireResult LockAcquire(const LOCKTAG *locktag,
00483             LOCKMODE lockmode,
00484             bool sessionLock,
00485             bool dontWait);
00486 extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag,
00487                     LOCKMODE lockmode,
00488                     bool sessionLock,
00489                     bool dontWait,
00490                     bool report_memory_error);
00491 extern void AbortStrongLockAcquire(void);
00492 extern bool LockRelease(const LOCKTAG *locktag,
00493             LOCKMODE lockmode, bool sessionLock);
00494 extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);
00495 extern void LockReleaseSession(LOCKMETHODID lockmethodid);
00496 extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks);
00497 extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks);
00498 extern bool LockHasWaiters(const LOCKTAG *locktag,
00499                LOCKMODE lockmode, bool sessionLock);
00500 extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag,
00501                  LOCKMODE lockmode);
00502 extern void AtPrepare_Locks(void);
00503 extern void PostPrepare_Locks(TransactionId xid);
00504 extern int LockCheckConflicts(LockMethod lockMethodTable,
00505                    LOCKMODE lockmode,
00506                    LOCK *lock, PROCLOCK *proclock, PGPROC *proc);
00507 extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);
00508 extern void GrantAwaitedLock(void);
00509 extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
00510 extern Size LockShmemSize(void);
00511 extern LockData *GetLockStatusData(void);
00512 
00513 extern void ReportLockTableError(bool report);
00514 
00515 typedef struct xl_standby_lock
00516 {
00517     TransactionId xid;          /* xid of holder of AccessExclusiveLock */
00518     Oid         dbOid;
00519     Oid         relOid;
00520 } xl_standby_lock;
00521 
00522 extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
00523 extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
00524 
00525 extern void lock_twophase_recover(TransactionId xid, uint16 info,
00526                       void *recdata, uint32 len);
00527 extern void lock_twophase_postcommit(TransactionId xid, uint16 info,
00528                          void *recdata, uint32 len);
00529 extern void lock_twophase_postabort(TransactionId xid, uint16 info,
00530                         void *recdata, uint32 len);
00531 extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,
00532                               void *recdata, uint32 len);
00533 
00534 extern DeadLockState DeadLockCheck(PGPROC *proc);
00535 extern PGPROC *GetBlockingAutoVacuumPgproc(void);
00536 extern void DeadLockReport(void) __attribute__((noreturn));
00537 extern void RememberSimpleDeadLock(PGPROC *proc1,
00538                        LOCKMODE lockmode,
00539                        LOCK *lock,
00540                        PGPROC *proc2);
00541 extern void InitDeadLockChecking(void);
00542 
00543 #ifdef LOCK_DEBUG
00544 extern void DumpLocks(PGPROC *proc);
00545 extern void DumpAllLocks(void);
00546 #endif
00547 
00548 /* Lock a VXID (used to wait for a transaction to finish) */
00549 extern void VirtualXactLockTableInsert(VirtualTransactionId vxid);
00550 extern void VirtualXactLockTableCleanup(void);
00551 extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait);
00552 
00553 #endif   /* LOCK_H */