1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Improve LockAcquire API per my recent proposal. All error conditions

are now reported via elog, eliminating the need to test the result code
at most call sites.  Make it possible for the caller to distinguish a
freshly acquired lock from one already held in the current transaction.
Use that capability to avoid redundant AcceptInvalidationMessages() calls
in LockRelation().
This commit is contained in:
Tom Lane
2005-05-29 22:45:02 +00:00
parent 299c442077
commit 140b078d2a
4 changed files with 81 additions and 69 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.74 2005/05/19 21:35:46 tgl Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.75 2005/05/29 22:45:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -136,24 +136,28 @@ void
LockRelation(Relation relation, LOCKMODE lockmode)
{
LOCKTAG tag;
LockAcquireResult res;
SET_LOCKTAG_RELATION(tag,
relation->rd_lockInfo.lockRelId.dbId,
relation->rd_lockInfo.lockRelId.relId);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false))
elog(ERROR, "LockAcquire failed");
res = LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false);
/*
* Check to see if the relcache entry has been invalidated while we
* were waiting to lock it. If so, rebuild it, or ereport() trying.
* Increment the refcount to ensure that RelationFlushRelation will
* rebuild it and not just delete it.
* rebuild it and not just delete it. We can skip this if the lock
* was already held, however.
*/
RelationIncrementReferenceCount(relation);
AcceptInvalidationMessages();
RelationDecrementReferenceCount(relation);
if (res != LOCKACQUIRE_ALREADY_HELD)
{
RelationIncrementReferenceCount(relation);
AcceptInvalidationMessages();
RelationDecrementReferenceCount(relation);
}
}
/*
@@ -169,24 +173,31 @@ bool
ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
{
LOCKTAG tag;
LockAcquireResult res;
SET_LOCKTAG_RELATION(tag,
relation->rd_lockInfo.lockRelId.dbId,
relation->rd_lockInfo.lockRelId.relId);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, true))
res = LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, true);
if (res == LOCKACQUIRE_NOT_AVAIL)
return false;
/*
* Check to see if the relcache entry has been invalidated while we
* were waiting to lock it. If so, rebuild it, or ereport() trying.
* Increment the refcount to ensure that RelationFlushRelation will
* rebuild it and not just delete it.
* rebuild it and not just delete it. We can skip this if the lock
* was already held, however.
*/
RelationIncrementReferenceCount(relation);
AcceptInvalidationMessages();
RelationDecrementReferenceCount(relation);
if (res != LOCKACQUIRE_ALREADY_HELD)
{
RelationIncrementReferenceCount(relation);
AcceptInvalidationMessages();
RelationDecrementReferenceCount(relation);
}
return true;
}
@@ -225,9 +236,8 @@ LockRelationForSession(LockRelId *relid, LOCKMODE lockmode)
SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
if (!LockAcquire(LockTableId, &tag, InvalidTransactionId,
lockmode, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, InvalidTransactionId,
lockmode, false);
}
/*
@@ -262,9 +272,8 @@ LockRelationForExtension(Relation relation, LOCKMODE lockmode)
relation->rd_lockInfo.lockRelId.dbId,
relation->rd_lockInfo.lockRelId.relId);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false);
}
/*
@@ -298,9 +307,8 @@ LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
relation->rd_lockInfo.lockRelId.relId,
blkno);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false);
}
/*
@@ -319,8 +327,8 @@ ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
relation->rd_lockInfo.lockRelId.relId,
blkno);
return LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, true);
return (LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, true) != LOCKACQUIRE_NOT_AVAIL);
}
/*
@@ -357,9 +365,8 @@ LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
ItemPointerGetBlockNumber(tid),
ItemPointerGetOffsetNumber(tid));
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false);
}
/*
@@ -393,9 +400,8 @@ XactLockTableInsert(TransactionId xid)
SET_LOCKTAG_TRANSACTION(tag, xid);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
ExclusiveLock, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, GetTopTransactionId(),
ExclusiveLock, false);
}
/*
@@ -441,8 +447,9 @@ XactLockTableWait(TransactionId xid)
SET_LOCKTAG_TRANSACTION(tag, xid);
if (!LockAcquire(LockTableId, &tag, myxid, ShareLock, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, myxid,
ShareLock, false);
LockRelease(LockTableId, &tag, myxid, ShareLock);
if (!TransactionIdIsInProgress(xid))
@@ -479,9 +486,8 @@ LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
objid,
objsubid);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false);
}
/*
@@ -519,9 +525,8 @@ LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
objid,
objsubid);
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false))
elog(ERROR, "LockAcquire failed");
(void) LockAcquire(LockTableId, &tag, GetTopTransactionId(),
lockmode, false);
}
/*