~ubuntu-branches/ubuntu/precise/postgresql-9.1/precise-security

« back to all changes in this revision

Viewing changes to src/include/storage/lock.h

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * lock.h
 
4
 *        POSTGRES low-level lock mechanism
 
5
 *
 
6
 *
 
7
 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
 
8
 * Portions Copyright (c) 1994, Regents of the University of California
 
9
 *
 
10
 * src/include/storage/lock.h
 
11
 *
 
12
 *-------------------------------------------------------------------------
 
13
 */
 
14
#ifndef LOCK_H_
 
15
#define LOCK_H_
 
16
 
 
17
#include "storage/backendid.h"
 
18
#include "storage/lwlock.h"
 
19
#include "storage/shmem.h"
 
20
 
 
21
 
 
22
/* struct PGPROC is declared in proc.h, but must forward-reference it */
 
23
typedef struct PGPROC PGPROC;
 
24
 
 
25
typedef struct PROC_QUEUE
 
26
{
 
27
        SHM_QUEUE       links;                  /* head of list of PGPROC objects */
 
28
        int                     size;                   /* number of entries in list */
 
29
} PROC_QUEUE;
 
30
 
 
31
/* GUC variables */
 
32
extern int      max_locks_per_xact;
 
33
 
 
34
#ifdef LOCK_DEBUG
 
35
extern int      Trace_lock_oidmin;
 
36
extern bool Trace_locks;
 
37
extern bool Trace_userlocks;
 
38
extern int      Trace_lock_table;
 
39
extern bool Debug_deadlocks;
 
40
#endif   /* LOCK_DEBUG */
 
41
 
 
42
 
 
43
/*
 
44
 * Top-level transactions are identified by VirtualTransactionIDs comprising
 
45
 * the BackendId of the backend running the xact, plus a locally-assigned
 
46
 * LocalTransactionId.  These are guaranteed unique over the short term,
 
47
 * but will be reused after a database restart; hence they should never
 
48
 * be stored on disk.
 
49
 *
 
50
 * Note that struct VirtualTransactionId can not be assumed to be atomically
 
51
 * assignable as a whole.  However, type LocalTransactionId is assumed to
 
52
 * be atomically assignable, and the backend ID doesn't change often enough
 
53
 * to be a problem, so we can fetch or assign the two fields separately.
 
54
 * We deliberately refrain from using the struct within PGPROC, to prevent
 
55
 * coding errors from trying to use struct assignment with it; instead use
 
56
 * GET_VXID_FROM_PGPROC().
 
57
 */
 
58
typedef struct
 
59
{
 
60
        BackendId       backendId;              /* determined at backend startup */
 
61
        LocalTransactionId localTransactionId;          /* backend-local transaction
 
62
                                                                                                 * id */
 
63
} VirtualTransactionId;
 
64
 
 
65
#define InvalidLocalTransactionId               0
 
66
#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
 
67
#define VirtualTransactionIdIsValid(vxid) \
 
68
        (((vxid).backendId != InvalidBackendId) && \
 
69
         LocalTransactionIdIsValid((vxid).localTransactionId))
 
70
#define VirtualTransactionIdEquals(vxid1, vxid2) \
 
71
        ((vxid1).backendId == (vxid2).backendId && \
 
72
         (vxid1).localTransactionId == (vxid2).localTransactionId)
 
73
#define SetInvalidVirtualTransactionId(vxid) \
 
74
        ((vxid).backendId = InvalidBackendId, \
 
75
         (vxid).localTransactionId = InvalidLocalTransactionId)
 
76
#define GET_VXID_FROM_PGPROC(vxid, proc) \
 
77
        ((vxid).backendId = (proc).backendId, \
 
78
         (vxid).localTransactionId = (proc).lxid)
 
79
 
 
80
 
 
81
/*
 
82
 * LOCKMODE is an integer (1..N) indicating a lock type.  LOCKMASK is a bit
 
83
 * mask indicating a set of held or requested lock types (the bit 1<<mode
 
84
 * corresponds to a particular lock mode).
 
85
 */
 
86
typedef int LOCKMASK;
 
87
typedef int LOCKMODE;
 
88
 
 
89
/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
 
90
#define MAX_LOCKMODES           10
 
91
 
 
92
#define LOCKBIT_ON(lockmode) (1 << (lockmode))
 
93
#define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))
 
94
 
 
95
 
 
96
/*
 
97
 * This data structure defines the locking semantics associated with a
 
98
 * "lock method".  The semantics specify the meaning of each lock mode
 
99
 * (by defining which lock modes it conflicts with), and also whether locks
 
100
 * of this method are transactional (ie, are released at transaction end).
 
101
 * All of this data is constant and is kept in const tables.
 
102
 *
 
103
 * numLockModes -- number of lock modes (READ,WRITE,etc) that
 
104
 *              are defined in this lock method.  Must be less than MAX_LOCKMODES.
 
105
 *
 
106
 * transactional -- TRUE if locks are released automatically at xact end.
 
107
 *
 
108
 * conflictTab -- this is an array of bitmasks showing lock
 
109
 *              mode conflicts.  conflictTab[i] is a mask with the j-th bit
 
110
 *              turned on if lock modes i and j conflict.  Lock modes are
 
111
 *              numbered 1..numLockModes; conflictTab[0] is unused.
 
112
 *
 
113
 * lockModeNames -- ID strings for debug printouts.
 
114
 *
 
115
 * trace_flag -- pointer to GUC trace flag for this lock method.
 
116
 */
 
117
typedef struct LockMethodData
 
118
{
 
119
        int                     numLockModes;
 
120
        bool            transactional;
 
121
        const LOCKMASK *conflictTab;
 
122
        const char *const * lockModeNames;
 
123
        const bool *trace_flag;
 
124
} LockMethodData;
 
125
 
 
126
typedef const LockMethodData *LockMethod;
 
127
 
 
128
/*
 
129
 * Lock methods are identified by LOCKMETHODID.  (Despite the declaration as
 
130
 * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
 
131
 */
 
132
typedef uint16 LOCKMETHODID;
 
133
 
 
134
/* These identify the known lock methods */
 
135
#define DEFAULT_LOCKMETHOD      1
 
136
#define USER_LOCKMETHOD         2
 
137
 
 
138
/*
 
139
 * These are the valid values of type LOCKMODE for all the standard lock
 
140
 * methods (both DEFAULT and USER).
 
141
 */
 
142
 
 
143
/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
 
144
#define NoLock                                  0
 
145
 
 
146
#define AccessShareLock                 1               /* SELECT */
 
147
#define RowShareLock                    2               /* SELECT FOR UPDATE/FOR SHARE */
 
148
#define RowExclusiveLock                3               /* INSERT, UPDATE, DELETE */
 
149
#define ShareUpdateExclusiveLock 4              /* VACUUM (non-FULL),ANALYZE, CREATE
 
150
                                                                                 * INDEX CONCURRENTLY */
 
151
#define ShareLock                               5               /* CREATE INDEX (WITHOUT CONCURRENTLY) */
 
152
#define ShareRowExclusiveLock   6               /* like EXCLUSIVE MODE, but allows ROW
 
153
                                                                                 * SHARE */
 
154
#define ExclusiveLock                   7               /* blocks ROW SHARE/SELECT...FOR
 
155
                                                                                 * UPDATE */
 
156
#define AccessExclusiveLock             8               /* ALTER TABLE, DROP TABLE, VACUUM
 
157
                                                                                 * FULL, and unqualified LOCK TABLE */
 
158
 
 
159
 
 
160
/*
 
161
 * LOCKTAG is the key information needed to look up a LOCK item in the
 
162
 * lock hashtable.      A LOCKTAG value uniquely identifies a lockable object.
 
163
 *
 
164
 * The LockTagType enum defines the different kinds of objects we can lock.
 
165
 * We can handle up to 256 different LockTagTypes.
 
166
 */
 
167
typedef enum LockTagType
 
168
{
 
169
        LOCKTAG_RELATION,                       /* whole relation */
 
170
        /* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
 
171
        LOCKTAG_RELATION_EXTEND,        /* the right to extend a relation */
 
172
        /* same ID info as RELATION */
 
173
        LOCKTAG_PAGE,                           /* one page of a relation */
 
174
        /* ID info for a page is RELATION info + BlockNumber */
 
175
        LOCKTAG_TUPLE,                          /* one physical tuple */
 
176
        /* ID info for a tuple is PAGE info + OffsetNumber */
 
177
        LOCKTAG_TRANSACTION,            /* transaction (for waiting for xact done) */
 
178
        /* ID info for a transaction is its TransactionId */
 
179
        LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
 
180
        /* ID info for a virtual transaction is its VirtualTransactionId */
 
181
        LOCKTAG_OBJECT,                         /* non-relation database object */
 
182
        /* ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID */
 
183
 
 
184
        /*
 
185
         * Note: object ID has same representation as in pg_depend and
 
186
         * pg_description, but notice that we are constraining SUBID to 16 bits.
 
187
         * Also, we use DB OID = 0 for shared objects such as tablespaces.
 
188
         */
 
189
        LOCKTAG_USERLOCK,                       /* reserved for old contrib/userlock code */
 
190
        LOCKTAG_ADVISORY                        /* advisory user locks */
 
191
} LockTagType;
 
192
 
 
193
#define LOCKTAG_LAST_TYPE       LOCKTAG_ADVISORY
 
194
 
 
195
/*
 
196
 * The LOCKTAG struct is defined with malice aforethought to fit into 16
 
197
 * bytes with no padding.  Note that this would need adjustment if we were
 
198
 * to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
 
199
 *
 
200
 * We include lockmethodid in the locktag so that a single hash table in
 
201
 * shared memory can store locks of different lockmethods.
 
202
 */
 
203
typedef struct LOCKTAG
 
204
{
 
205
        uint32          locktag_field1; /* a 32-bit ID field */
 
206
        uint32          locktag_field2; /* a 32-bit ID field */
 
207
        uint32          locktag_field3; /* a 32-bit ID field */
 
208
        uint16          locktag_field4; /* a 16-bit ID field */
 
209
        uint8           locktag_type;   /* see enum LockTagType */
 
210
        uint8           locktag_lockmethodid;   /* lockmethod indicator */
 
211
} LOCKTAG;
 
212
 
 
213
/*
 
214
 * These macros define how we map logical IDs of lockable objects into
 
215
 * the physical fields of LOCKTAG.      Use these to set up LOCKTAG values,
 
216
 * rather than accessing the fields directly.  Note multiple eval of target!
 
217
 */
 
218
#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
 
219
        ((locktag).locktag_field1 = (dboid), \
 
220
         (locktag).locktag_field2 = (reloid), \
 
221
         (locktag).locktag_field3 = 0, \
 
222
         (locktag).locktag_field4 = 0, \
 
223
         (locktag).locktag_type = LOCKTAG_RELATION, \
 
224
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
225
 
 
226
#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
 
227
        ((locktag).locktag_field1 = (dboid), \
 
228
         (locktag).locktag_field2 = (reloid), \
 
229
         (locktag).locktag_field3 = 0, \
 
230
         (locktag).locktag_field4 = 0, \
 
231
         (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
 
232
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
233
 
 
234
#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
 
235
        ((locktag).locktag_field1 = (dboid), \
 
236
         (locktag).locktag_field2 = (reloid), \
 
237
         (locktag).locktag_field3 = (blocknum), \
 
238
         (locktag).locktag_field4 = 0, \
 
239
         (locktag).locktag_type = LOCKTAG_PAGE, \
 
240
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
241
 
 
242
#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
 
243
        ((locktag).locktag_field1 = (dboid), \
 
244
         (locktag).locktag_field2 = (reloid), \
 
245
         (locktag).locktag_field3 = (blocknum), \
 
246
         (locktag).locktag_field4 = (offnum), \
 
247
         (locktag).locktag_type = LOCKTAG_TUPLE, \
 
248
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
249
 
 
250
#define SET_LOCKTAG_TRANSACTION(locktag,xid) \
 
251
        ((locktag).locktag_field1 = (xid), \
 
252
         (locktag).locktag_field2 = 0, \
 
253
         (locktag).locktag_field3 = 0, \
 
254
         (locktag).locktag_field4 = 0, \
 
255
         (locktag).locktag_type = LOCKTAG_TRANSACTION, \
 
256
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
257
 
 
258
#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
 
259
        ((locktag).locktag_field1 = (vxid).backendId, \
 
260
         (locktag).locktag_field2 = (vxid).localTransactionId, \
 
261
         (locktag).locktag_field3 = 0, \
 
262
         (locktag).locktag_field4 = 0, \
 
263
         (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
 
264
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
265
 
 
266
#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
 
267
        ((locktag).locktag_field1 = (dboid), \
 
268
         (locktag).locktag_field2 = (classoid), \
 
269
         (locktag).locktag_field3 = (objoid), \
 
270
         (locktag).locktag_field4 = (objsubid), \
 
271
         (locktag).locktag_type = LOCKTAG_OBJECT, \
 
272
         (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
 
273
 
 
274
#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
 
275
        ((locktag).locktag_field1 = (id1), \
 
276
         (locktag).locktag_field2 = (id2), \
 
277
         (locktag).locktag_field3 = (id3), \
 
278
         (locktag).locktag_field4 = (id4), \
 
279
         (locktag).locktag_type = LOCKTAG_ADVISORY, \
 
280
         (locktag).locktag_lockmethodid = USER_LOCKMETHOD)
 
281
 
 
282
 
 
283
/*
 
284
 * Per-locked-object lock information:
 
285
 *
 
286
 * tag -- uniquely identifies the object being locked
 
287
 * grantMask -- bitmask for all lock types currently granted on this object.
 
288
 * waitMask -- bitmask for all lock types currently awaited on this object.
 
289
 * procLocks -- list of PROCLOCK objects for this lock.
 
290
 * waitProcs -- queue of processes waiting for this lock.
 
291
 * requested -- count of each lock type currently requested on the lock
 
292
 *              (includes requests already granted!!).
 
293
 * nRequested -- total requested locks of all types.
 
294
 * granted -- count of each lock type currently granted on the lock.
 
295
 * nGranted -- total granted locks of all types.
 
296
 *
 
297
 * Note: these counts count 1 for each backend.  Internally to a backend,
 
298
 * there may be multiple grabs on a particular lock, but this is not reflected
 
299
 * into shared memory.
 
300
 */
 
301
typedef struct LOCK
 
302
{
 
303
        /* hash key */
 
304
        LOCKTAG         tag;                    /* unique identifier of lockable object */
 
305
 
 
306
        /* data */
 
307
        LOCKMASK        grantMask;              /* bitmask for lock types already granted */
 
308
        LOCKMASK        waitMask;               /* bitmask for lock types awaited */
 
309
        SHM_QUEUE       procLocks;              /* list of PROCLOCK objects assoc. with lock */
 
310
        PROC_QUEUE      waitProcs;              /* list of PGPROC objects waiting on lock */
 
311
        int                     requested[MAX_LOCKMODES];               /* counts of requested locks */
 
312
        int                     nRequested;             /* total of requested[] array */
 
313
        int                     granted[MAX_LOCKMODES]; /* counts of granted locks */
 
314
        int                     nGranted;               /* total of granted[] array */
 
315
} LOCK;
 
316
 
 
317
#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
 
318
 
 
319
 
 
320
/*
 
321
 * We may have several different backends holding or awaiting locks
 
322
 * on the same lockable object.  We need to store some per-holder/waiter
 
323
 * information for each such holder (or would-be holder).  This is kept in
 
324
 * a PROCLOCK struct.
 
325
 *
 
326
 * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the
 
327
 * proclock hashtable.  A PROCLOCKTAG value uniquely identifies the combination
 
328
 * of a lockable object and a holder/waiter for that object.  (We can use
 
329
 * pointers here because the PROCLOCKTAG need only be unique for the lifespan
 
330
 * of the PROCLOCK, and it will never outlive the lock or the proc.)
 
331
 *
 
332
 * Internally to a backend, it is possible for the same lock to be held
 
333
 * for different purposes: the backend tracks transaction locks separately
 
334
 * from session locks.  However, this is not reflected in the shared-memory
 
335
 * state: we only track which backend(s) hold the lock.  This is OK since a
 
336
 * backend can never block itself.
 
337
 *
 
338
 * The holdMask field shows the already-granted locks represented by this
 
339
 * proclock.  Note that there will be a proclock object, possibly with
 
340
 * zero holdMask, for any lock that the process is currently waiting on.
 
341
 * Otherwise, proclock objects whose holdMasks are zero are recycled
 
342
 * as soon as convenient.
 
343
 *
 
344
 * releaseMask is workspace for LockReleaseAll(): it shows the locks due
 
345
 * to be released during the current call.      This must only be examined or
 
346
 * set by the backend owning the PROCLOCK.
 
347
 *
 
348
 * Each PROCLOCK object is linked into lists for both the associated LOCK
 
349
 * object and the owning PGPROC object.  Note that the PROCLOCK is entered
 
350
 * into these lists as soon as it is created, even if no lock has yet been
 
351
 * granted.  A PGPROC that is waiting for a lock to be granted will also be
 
352
 * linked into the lock's waitProcs queue.
 
353
 */
 
354
typedef struct PROCLOCKTAG
 
355
{
 
356
        /* NB: we assume this struct contains no padding! */
 
357
        LOCK       *myLock;                     /* link to per-lockable-object information */
 
358
        PGPROC     *myProc;                     /* link to PGPROC of owning backend */
 
359
} PROCLOCKTAG;
 
360
 
 
361
typedef struct PROCLOCK
 
362
{
 
363
        /* tag */
 
364
        PROCLOCKTAG tag;                        /* unique identifier of proclock object */
 
365
 
 
366
        /* data */
 
367
        LOCKMASK        holdMask;               /* bitmask for lock types currently held */
 
368
        LOCKMASK        releaseMask;    /* bitmask for lock types to be released */
 
369
        SHM_QUEUE       lockLink;               /* list link in LOCK's list of proclocks */
 
370
        SHM_QUEUE       procLink;               /* list link in PGPROC's list of proclocks */
 
371
} PROCLOCK;
 
372
 
 
373
#define PROCLOCK_LOCKMETHOD(proclock) \
 
374
        LOCK_LOCKMETHOD(*((proclock).tag.myLock))
 
375
 
 
376
/*
 
377
 * Each backend also maintains a local hash table with information about each
 
378
 * lock it is currently interested in.  In particular the local table counts
 
379
 * the number of times that lock has been acquired.  This allows multiple
 
380
 * requests for the same lock to be executed without additional accesses to
 
381
 * shared memory.  We also track the number of lock acquisitions per
 
382
 * ResourceOwner, so that we can release just those locks belonging to a
 
383
 * particular ResourceOwner.
 
384
 */
 
385
typedef struct LOCALLOCKTAG
 
386
{
 
387
        LOCKTAG         lock;                   /* identifies the lockable object */
 
388
        LOCKMODE        mode;                   /* lock mode for this table entry */
 
389
} LOCALLOCKTAG;
 
390
 
 
391
typedef struct LOCALLOCKOWNER
 
392
{
 
393
        /*
 
394
         * Note: if owner is NULL then the lock is held on behalf of the session;
 
395
         * otherwise it is held on behalf of my current transaction.
 
396
         *
 
397
         * Must use a forward struct reference to avoid circularity.
 
398
         */
 
399
        struct ResourceOwnerData *owner;
 
400
        int64           nLocks;                 /* # of times held by this owner */
 
401
} LOCALLOCKOWNER;
 
402
 
 
403
typedef struct LOCALLOCK
 
404
{
 
405
        /* tag */
 
406
        LOCALLOCKTAG tag;                       /* unique identifier of locallock entry */
 
407
 
 
408
        /* data */
 
409
        LOCK       *lock;                       /* associated LOCK object in shared mem */
 
410
        PROCLOCK   *proclock;           /* associated PROCLOCK object in shmem */
 
411
        uint32          hashcode;               /* copy of LOCKTAG's hash value */
 
412
        int64           nLocks;                 /* total number of times lock is held */
 
413
        int                     numLockOwners;  /* # of relevant ResourceOwners */
 
414
        int                     maxLockOwners;  /* allocated size of array */
 
415
        LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */
 
416
} LOCALLOCK;
 
417
 
 
418
#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
 
419
 
 
420
 
 
421
/*
 
422
 * This struct holds information passed from lmgr internals to the lock
 
423
 * listing user-level functions (in lockfuncs.c).       For each PROCLOCK in
 
424
 * the system, copies of the PROCLOCK object and associated PGPROC and
 
425
 * LOCK objects are stored.  Note there will often be multiple copies
 
426
 * of the same PGPROC or LOCK --- to detect whether two are the same,
 
427
 * compare the PROCLOCK tag fields.
 
428
 */
 
429
typedef struct LockData
 
430
{
 
431
        int                     nelements;              /* The length of each of the arrays */
 
432
        PROCLOCK   *proclocks;
 
433
        PGPROC     *procs;
 
434
        LOCK       *locks;
 
435
} LockData;
 
436
 
 
437
 
 
438
/* Result codes for LockAcquire() */
 
439
typedef enum
 
440
{
 
441
        LOCKACQUIRE_NOT_AVAIL,          /* lock not available, and dontWait=true */
 
442
        LOCKACQUIRE_OK,                         /* lock successfully acquired */
 
443
        LOCKACQUIRE_ALREADY_HELD        /* incremented count for lock already held */
 
444
} LockAcquireResult;
 
445
 
 
446
/* Deadlock states identified by DeadLockCheck() */
 
447
typedef enum
 
448
{
 
449
        DS_NOT_YET_CHECKED,                     /* no deadlock check has run yet */
 
450
        DS_NO_DEADLOCK,                         /* no deadlock detected */
 
451
        DS_SOFT_DEADLOCK,                       /* deadlock avoided by queue rearrangement */
 
452
        DS_HARD_DEADLOCK,                       /* deadlock, no way out but ERROR */
 
453
        DS_BLOCKED_BY_AUTOVACUUM        /* no deadlock; queue blocked by autovacuum
 
454
                                                                 * worker */
 
455
} DeadLockState;
 
456
 
 
457
 
 
458
/*
 
459
 * The lockmgr's shared hash tables are partitioned to reduce contention.
 
460
 * To determine which partition a given locktag belongs to, compute the tag's
 
461
 * hash code with LockTagHashCode(), then apply one of these macros.
 
462
 * NB: NUM_LOCK_PARTITIONS must be a power of 2!
 
463
 */
 
464
#define LockHashPartition(hashcode) \
 
465
        ((hashcode) % NUM_LOCK_PARTITIONS)
 
466
#define LockHashPartitionLock(hashcode) \
 
467
        ((LWLockId) (FirstLockMgrLock + LockHashPartition(hashcode)))
 
468
 
 
469
 
 
470
/*
 
471
 * function prototypes
 
472
 */
 
473
extern void InitLocks(void);
 
474
extern LockMethod GetLocksMethodTable(const LOCK *lock);
 
475
extern uint32 LockTagHashCode(const LOCKTAG *locktag);
 
476
extern LockAcquireResult LockAcquire(const LOCKTAG *locktag,
 
477
                        LOCKMODE lockmode,
 
478
                        bool sessionLock,
 
479
                        bool dontWait);
 
480
extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag,
 
481
                                        LOCKMODE lockmode,
 
482
                                        bool sessionLock,
 
483
                                        bool dontWait,
 
484
                                        bool report_memory_error);
 
485
extern bool LockRelease(const LOCKTAG *locktag,
 
486
                        LOCKMODE lockmode, bool sessionLock);
 
487
extern void LockReleaseSession(LOCKMETHODID lockmethodid);
 
488
extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);
 
489
extern void LockReleaseCurrentOwner(void);
 
490
extern void LockReassignCurrentOwner(void);
 
491
extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag,
 
492
                                 LOCKMODE lockmode);
 
493
extern void AtPrepare_Locks(void);
 
494
extern void PostPrepare_Locks(TransactionId xid);
 
495
extern int LockCheckConflicts(LockMethod lockMethodTable,
 
496
                                   LOCKMODE lockmode,
 
497
                                   LOCK *lock, PROCLOCK *proclock, PGPROC *proc);
 
498
extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);
 
499
extern void GrantAwaitedLock(void);
 
500
extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
 
501
extern Size LockShmemSize(void);
 
502
extern LockData *GetLockStatusData(void);
 
503
 
 
504
extern void ReportLockTableError(bool report);
 
505
 
 
506
typedef struct xl_standby_lock
 
507
{
 
508
        TransactionId xid;                      /* xid of holder of AccessExclusiveLock */
 
509
        Oid                     dbOid;
 
510
        Oid                     relOid;
 
511
} xl_standby_lock;
 
512
 
 
513
extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
 
514
extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
 
515
 
 
516
extern void lock_twophase_recover(TransactionId xid, uint16 info,
 
517
                                          void *recdata, uint32 len);
 
518
extern void lock_twophase_postcommit(TransactionId xid, uint16 info,
 
519
                                                 void *recdata, uint32 len);
 
520
extern void lock_twophase_postabort(TransactionId xid, uint16 info,
 
521
                                                void *recdata, uint32 len);
 
522
extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,
 
523
                                                          void *recdata, uint32 len);
 
524
 
 
525
extern DeadLockState DeadLockCheck(PGPROC *proc);
 
526
extern PGPROC *GetBlockingAutoVacuumPgproc(void);
 
527
extern void DeadLockReport(void);
 
528
extern void RememberSimpleDeadLock(PGPROC *proc1,
 
529
                                           LOCKMODE lockmode,
 
530
                                           LOCK *lock,
 
531
                                           PGPROC *proc2);
 
532
extern void InitDeadLockChecking(void);
 
533
 
 
534
#ifdef LOCK_DEBUG
 
535
extern void DumpLocks(PGPROC *proc);
 
536
extern void DumpAllLocks(void);
 
537
#endif
 
538
 
 
539
#endif   /* LOCK_H */