PostgreSQL Source Code: src/include/storage/lock.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef LOCK_H_
15#define LOCK_H_
16
17#ifdef FRONTEND
18#error "lock.h may not be included from frontend code"
19#endif
20
27
28
30
31
34
35#ifdef LOCK_DEBUG
41#endif
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60typedef struct
61{
65
66#define InvalidLocalTransactionId 0
67#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
68#define VirtualTransactionIdIsValid(vxid) \
69 (LocalTransactionIdIsValid((vxid).localTransactionId))
70#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \
71 ((vxid).procNumber == INVALID_PROC_NUMBER)
72#define VirtualTransactionIdEquals(vxid1, vxid2) \
73 ((vxid1).procNumber == (vxid2).procNumber && \
74 (vxid1).localTransactionId == (vxid2).localTransactionId)
75#define SetInvalidVirtualTransactionId(vxid) \
76 ((vxid).procNumber = INVALID_PROC_NUMBER, \
77 (vxid).localTransactionId = InvalidLocalTransactionId)
78#define GET_VXID_FROM_PGPROC(vxid_dst, proc) \
79 ((vxid_dst).procNumber = (proc).vxid.procNumber, \
80 (vxid_dst).localTransactionId = (proc).vxid.lxid)
81
82
83#define MAX_LOCKMODES 10
84
85#define LOCKBIT_ON(lockmode) (1 << (lockmode))
86#define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
110{
116
118
119
120
121
122
124
125
126#define DEFAULT_LOCKMETHOD 1
127#define USER_LOCKMETHOD 2
128
129
130
131
132
133
134
135
137{
150
152
153#define LOCKTAG_LAST_TYPE LOCKTAG_APPLY_TRANSACTION
154
156
157
158
159
160
161
162
163
164
166{
174
175
176
177
178
179
180
181
182#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
183 ((locktag).locktag_field1 = (dboid), \
184 (locktag).locktag_field2 = (reloid), \
185 (locktag).locktag_field3 = 0, \
186 (locktag).locktag_field4 = 0, \
187 (locktag).locktag_type = LOCKTAG_RELATION, \
188 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
189
190
191#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
192 ((locktag).locktag_field1 = (dboid), \
193 (locktag).locktag_field2 = (reloid), \
194 (locktag).locktag_field3 = 0, \
195 (locktag).locktag_field4 = 0, \
196 (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
197 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
198
199
200#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \
201 ((locktag).locktag_field1 = (dboid), \
202 (locktag).locktag_field2 = 0, \
203 (locktag).locktag_field3 = 0, \
204 (locktag).locktag_field4 = 0, \
205 (locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \
206 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
207
208
209#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
210 ((locktag).locktag_field1 = (dboid), \
211 (locktag).locktag_field2 = (reloid), \
212 (locktag).locktag_field3 = (blocknum), \
213 (locktag).locktag_field4 = 0, \
214 (locktag).locktag_type = LOCKTAG_PAGE, \
215 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
216
217
218#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
219 ((locktag).locktag_field1 = (dboid), \
220 (locktag).locktag_field2 = (reloid), \
221 (locktag).locktag_field3 = (blocknum), \
222 (locktag).locktag_field4 = (offnum), \
223 (locktag).locktag_type = LOCKTAG_TUPLE, \
224 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
225
226
227#define SET_LOCKTAG_TRANSACTION(locktag,xid) \
228 ((locktag).locktag_field1 = (xid), \
229 (locktag).locktag_field2 = 0, \
230 (locktag).locktag_field3 = 0, \
231 (locktag).locktag_field4 = 0, \
232 (locktag).locktag_type = LOCKTAG_TRANSACTION, \
233 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
234
235
236#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
237 ((locktag).locktag_field1 = (vxid).procNumber, \
238 (locktag).locktag_field2 = (vxid).localTransactionId, \
239 (locktag).locktag_field3 = 0, \
240 (locktag).locktag_field4 = 0, \
241 (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
242 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
243
244
245
246
247
248#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \
249 ((locktag).locktag_field1 = (xid), \
250 (locktag).locktag_field2 = (token), \
251 (locktag).locktag_field3 = 0, \
252 (locktag).locktag_field4 = 0, \
253 (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \
254 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
255
256
257
258
259
260
261
262
263#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
264 ((locktag).locktag_field1 = (dboid), \
265 (locktag).locktag_field2 = (classoid), \
266 (locktag).locktag_field3 = (objoid), \
267 (locktag).locktag_field4 = (objsubid), \
268 (locktag).locktag_type = LOCKTAG_OBJECT, \
269 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
270
271#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
272 ((locktag).locktag_field1 = (id1), \
273 (locktag).locktag_field2 = (id2), \
274 (locktag).locktag_field3 = (id3), \
275 (locktag).locktag_field4 = (id4), \
276 (locktag).locktag_type = LOCKTAG_ADVISORY, \
277 (locktag).locktag_lockmethodid = USER_LOCKMETHOD)
278
279
280
281
282
283#define SET_LOCKTAG_APPLY_TRANSACTION(locktag,dboid,suboid,xid,objid) \
284 ((locktag).locktag_field1 = (dboid), \
285 (locktag).locktag_field2 = (suboid), \
286 (locktag).locktag_field3 = (xid), \
287 (locktag).locktag_field4 = (objid), \
288 (locktag).locktag_type = LOCKTAG_APPLY_TRANSACTION, \
289 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
310{
311
313
314
324
325#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
326#define LOCK_LOCKTAG(lock) ((LockTagType) (lock).tag.locktag_type)
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
364{
365
369
371{
372
374
375
382
383#define PROCLOCK_LOCKMETHOD(proclock) \
384 LOCK_LOCKMETHOD(*((proclock).tag.myLock))
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
410{
414
416{
417
418
419
420
421
422
426
428{
429
431
432
441 bool lockCleared;
443
444#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
445#define LOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type)
446
447
448
449
450
451
452
454{
460
465
467{
471
473{
475
476
477 int first_lock;
479
480
484
486{
489 int *waiter_pids;
497
498
499
500typedef enum
501{
507
508
509typedef enum
510{
516
518
519
520
521
522
523
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
535
536
537
538
539
540
541
542#define LockHashPartitionLockByProc(leader_pgproc) \
543 LockHashPartitionLock(GetNumberFromPGProc(leader_pgproc))
544
545
546
547
557 bool sessionLock,
558 bool dontWait);
561 bool sessionLock,
562 bool dontWait,
563 bool reportMemoryError,
565 bool logLockFailure);
569 LOCKMODE lockmode, bool sessionLock);
575 LOCKMODE lockmode, bool orstronger);
576#ifdef USE_ASSERT_CHECKING
577extern HTAB *GetLockMethodLocalHash(void);
578#endif
580 LOCKMODE lockmode, bool sessionLock);
582 LOCKMODE lockmode, int *countp);
592
596
599
608
617
619
620#ifdef LOCK_DEBUG
621extern void DumpLocks(PGPROC *proc);
622extern void DumpAllLocks(void);
623#endif
624
625
629
630#endif
uint32 LocalTransactionId
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode, bool orstronger)
PGDLLIMPORT int max_locks_per_xact
bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2)
struct LOCALLOCK LOCALLOCK
const LockMethodData * LockMethod
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
PGPROC * GetBlockingAutoVacuumPgproc(void)
@ LOCKTAG_RELATION_EXTEND
@ LOCKTAG_SPECULATIVE_TOKEN
@ LOCKTAG_APPLY_TRANSACTION
@ LOCKTAG_DATABASE_FROZEN_IDS
@ LOCKTAG_VIRTUALTRANSACTION
void GrantAwaitedLock(void)
int LockWaiterCount(const LOCKTAG *locktag)
void AtPrepare_Locks(void)
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void lock_twophase_postcommit(TransactionId xid, uint16 info, void *recdata, uint32 len)
Size LockManagerShmemSize(void)
void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)
struct LOCALLOCKOWNER LOCALLOCKOWNER
void InitLockManagerAccess(void)
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
void VirtualXactLockTableCleanup(void)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError, LOCALLOCK **locallockp, bool logLockFailure)
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
struct LockMethodData LockMethodData
void ResetAwaitedLock(void)
void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks)
struct BlockedProcData BlockedProcData
void AbortStrongLockAcquire(void)
@ DS_BLOCKED_BY_AUTOVACUUM
struct LockInstanceData LockInstanceData
BlockedProcsData * GetBlockerStatusData(int blocked_pid)
void LockManagerShmemInit(void)
void lock_twophase_postabort(TransactionId xid, uint16 info, void *recdata, uint32 len)
bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
struct PROCLOCKTAG PROCLOCKTAG
PGDLLIMPORT const char *const LockTagTypeNames[]
void lock_twophase_standby_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)
void InitDeadLockChecking(void)
void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks)
LOCALLOCK * GetAwaitedLock(void)
void lock_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)
void LockReleaseSession(LOCKMETHODID lockmethodid)
void MarkLockClear(LOCALLOCK *locallock)
LockData * GetLockStatusData(void)
DeadLockState DeadLockCheck(PGPROC *proc)
uint32 LockTagHashCode(const LOCKTAG *locktag)
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
pg_noreturn void DeadLockReport(void)
struct LOCALLOCKTAG LOCALLOCKTAG
PGDLLIMPORT bool log_lock_failure
LockMethod GetLocksMethodTable(const LOCK *lock)
void PostPrepare_Locks(TransactionId xid)
@ LOCKACQUIRE_ALREADY_CLEAR
@ LOCKACQUIRE_ALREADY_HELD
struct BlockedProcsData BlockedProcsData
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag)
static PgChecksumMode mode
struct ResourceOwnerData * owner
LOCALLOCKOWNER * lockOwners
bool holdsStrongLockCount
uint8 locktag_lockmethodid
int requested[MAX_LOCKMODES]
int granted[MAX_LOCKMODES]
VirtualTransactionId vxid
const LOCKMASK * conflictTab
const char *const * lockModeNames
LocalTransactionId localTransactionId