Commit a513f1df authored by Peter Eisentraut's avatar Peter Eisentraut

Remove STATUS_WAITING

Add a separate enum for use in the locking APIs, which were the only
user.

Discussion: https://www.postgresql.org/message-id/flat/a6f91ead-0ce4-2a34-062b-7ab9813ea308%402ndquadrant.com
parent 42aa1f0a
...@@ -460,7 +460,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid, ...@@ -460,7 +460,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
MemSet(proc, 0, sizeof(PGPROC)); MemSet(proc, 0, sizeof(PGPROC));
proc->pgprocno = gxact->pgprocno; proc->pgprocno = gxact->pgprocno;
SHMQueueElemInit(&(proc->links)); SHMQueueElemInit(&(proc->links));
proc->waitStatus = STATUS_OK; proc->waitStatus = PROC_WAIT_STATUS_OK;
/* We set up the gxact's VXID as InvalidBackendId/XID */ /* We set up the gxact's VXID as InvalidBackendId/XID */
proc->lxid = (LocalTransactionId) xid; proc->lxid = (LocalTransactionId) xid;
pgxact->xid = xid; pgxact->xid = xid;
......
...@@ -1856,7 +1856,7 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner) ...@@ -1856,7 +1856,7 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
*/ */
PG_TRY(); PG_TRY();
{ {
if (ProcSleep(locallock, lockMethodTable) != STATUS_OK) if (ProcSleep(locallock, lockMethodTable) != PROC_WAIT_STATUS_OK)
{ {
/* /*
* We failed as a result of a deadlock, see CheckDeadLock(). Quit * We failed as a result of a deadlock, see CheckDeadLock(). Quit
...@@ -1907,7 +1907,7 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner) ...@@ -1907,7 +1907,7 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
/* /*
* Remove a proc from the wait-queue it is on (caller must know it is on one). * Remove a proc from the wait-queue it is on (caller must know it is on one).
* This is only used when the proc has failed to get the lock, so we set its * This is only used when the proc has failed to get the lock, so we set its
* waitStatus to STATUS_ERROR. * waitStatus to PROC_WAIT_STATUS_ERROR.
* *
* Appropriate partition lock must be held by caller. Also, caller is * Appropriate partition lock must be held by caller. Also, caller is
* responsible for signaling the proc if needed. * responsible for signaling the proc if needed.
...@@ -1923,7 +1923,7 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode) ...@@ -1923,7 +1923,7 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
LOCKMETHODID lockmethodid = LOCK_LOCKMETHOD(*waitLock); LOCKMETHODID lockmethodid = LOCK_LOCKMETHOD(*waitLock);
/* Make sure proc is waiting */ /* Make sure proc is waiting */
Assert(proc->waitStatus == STATUS_WAITING); Assert(proc->waitStatus == PROC_WAIT_STATUS_WAITING);
Assert(proc->links.next != NULL); Assert(proc->links.next != NULL);
Assert(waitLock); Assert(waitLock);
Assert(waitLock->waitProcs.size > 0); Assert(waitLock->waitProcs.size > 0);
...@@ -1946,7 +1946,7 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode) ...@@ -1946,7 +1946,7 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
/* Clean up the proc's own state, and pass it the ok/fail signal */ /* Clean up the proc's own state, and pass it the ok/fail signal */
proc->waitLock = NULL; proc->waitLock = NULL;
proc->waitProcLock = NULL; proc->waitProcLock = NULL;
proc->waitStatus = STATUS_ERROR; proc->waitStatus = PROC_WAIT_STATUS_ERROR;
/* /*
* Delete the proclock immediately if it represents no already-held locks. * Delete the proclock immediately if it represents no already-held locks.
......
...@@ -383,7 +383,7 @@ InitProcess(void) ...@@ -383,7 +383,7 @@ InitProcess(void)
* initialized by InitProcGlobal. * initialized by InitProcGlobal.
*/ */
SHMQueueElemInit(&(MyProc->links)); SHMQueueElemInit(&(MyProc->links));
MyProc->waitStatus = STATUS_OK; MyProc->waitStatus = PROC_WAIT_STATUS_OK;
MyProc->lxid = InvalidLocalTransactionId; MyProc->lxid = InvalidLocalTransactionId;
MyProc->fpVXIDLock = false; MyProc->fpVXIDLock = false;
MyProc->fpLocalTransactionId = InvalidLocalTransactionId; MyProc->fpLocalTransactionId = InvalidLocalTransactionId;
...@@ -567,7 +567,7 @@ InitAuxiliaryProcess(void) ...@@ -567,7 +567,7 @@ InitAuxiliaryProcess(void)
* initialized by InitProcGlobal. * initialized by InitProcGlobal.
*/ */
SHMQueueElemInit(&(MyProc->links)); SHMQueueElemInit(&(MyProc->links));
MyProc->waitStatus = STATUS_OK; MyProc->waitStatus = PROC_WAIT_STATUS_OK;
MyProc->lxid = InvalidLocalTransactionId; MyProc->lxid = InvalidLocalTransactionId;
MyProc->fpVXIDLock = false; MyProc->fpVXIDLock = false;
MyProc->fpLocalTransactionId = InvalidLocalTransactionId; MyProc->fpLocalTransactionId = InvalidLocalTransactionId;
...@@ -755,7 +755,7 @@ LockErrorCleanup(void) ...@@ -755,7 +755,7 @@ LockErrorCleanup(void)
* did grant us the lock, we'd better remember it in our local lock * did grant us the lock, we'd better remember it in our local lock
* table. * table.
*/ */
if (MyProc->waitStatus == STATUS_OK) if (MyProc->waitStatus == PROC_WAIT_STATUS_OK)
GrantAwaitedLock(); GrantAwaitedLock();
} }
...@@ -1051,14 +1051,14 @@ ProcQueueInit(PROC_QUEUE *queue) ...@@ -1051,14 +1051,14 @@ ProcQueueInit(PROC_QUEUE *queue)
* The lock table's partition lock must be held at entry, and will be held * The lock table's partition lock must be held at entry, and will be held
* at exit. * at exit.
* *
* Result: STATUS_OK if we acquired the lock, STATUS_ERROR if not (deadlock). * Result: PROC_WAIT_STATUS_OK if we acquired the lock, PROC_WAIT_STATUS_ERROR if not (deadlock).
* *
* ASSUME: that no one will fiddle with the queue until after * ASSUME: that no one will fiddle with the queue until after
* we release the partition lock. * we release the partition lock.
* *
* NOTES: The process queue is now a priority queue for locking. * NOTES: The process queue is now a priority queue for locking.
*/ */
int ProcWaitStatus
ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
{ {
LOCKMODE lockmode = locallock->tag.mode; LOCKMODE lockmode = locallock->tag.mode;
...@@ -1070,7 +1070,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1070,7 +1070,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
LOCKMASK myHeldLocks = MyProc->heldLocks; LOCKMASK myHeldLocks = MyProc->heldLocks;
bool early_deadlock = false; bool early_deadlock = false;
bool allow_autovacuum_cancel = true; bool allow_autovacuum_cancel = true;
int myWaitStatus; ProcWaitStatus myWaitStatus;
PGPROC *proc; PGPROC *proc;
PGPROC *leader = MyProc->lockGroupLeader; PGPROC *leader = MyProc->lockGroupLeader;
int i; int i;
...@@ -1161,7 +1161,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1161,7 +1161,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
/* Skip the wait and just grant myself the lock. */ /* Skip the wait and just grant myself the lock. */
GrantLock(lock, proclock, lockmode); GrantLock(lock, proclock, lockmode);
GrantAwaitedLock(); GrantAwaitedLock();
return STATUS_OK; return PROC_WAIT_STATUS_OK;
} }
/* Break out of loop to put myself before him */ /* Break out of loop to put myself before him */
break; break;
...@@ -1195,7 +1195,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1195,7 +1195,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
MyProc->waitProcLock = proclock; MyProc->waitProcLock = proclock;
MyProc->waitLockMode = lockmode; MyProc->waitLockMode = lockmode;
MyProc->waitStatus = STATUS_WAITING; MyProc->waitStatus = PROC_WAIT_STATUS_WAITING;
/* /*
* If we detected deadlock, give up without waiting. This must agree with * If we detected deadlock, give up without waiting. This must agree with
...@@ -1204,7 +1204,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1204,7 +1204,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
if (early_deadlock) if (early_deadlock)
{ {
RemoveFromWaitQueue(MyProc, hashcode); RemoveFromWaitQueue(MyProc, hashcode);
return STATUS_ERROR; return PROC_WAIT_STATUS_ERROR;
} }
/* mark that we are waiting for a lock */ /* mark that we are waiting for a lock */
...@@ -1236,7 +1236,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1236,7 +1236,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
/* /*
* Set timer so we can wake up after awhile and check for a deadlock. If a * Set timer so we can wake up after awhile and check for a deadlock. If a
* deadlock is detected, the handler sets MyProc->waitStatus = * deadlock is detected, the handler sets MyProc->waitStatus =
* STATUS_ERROR, allowing us to know that we must report failure rather * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure rather
* than success. * than success.
* *
* By delaying the check until we've waited for a bit, we can avoid * By delaying the check until we've waited for a bit, we can avoid
...@@ -1302,11 +1302,11 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1302,11 +1302,11 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
} }
/* /*
* waitStatus could change from STATUS_WAITING to something else * waitStatus could change from PROC_WAIT_STATUS_WAITING to something else
* asynchronously. Read it just once per loop to prevent surprising * asynchronously. Read it just once per loop to prevent surprising
* behavior (such as missing log messages). * behavior (such as missing log messages).
*/ */
myWaitStatus = *((volatile int *) &MyProc->waitStatus); myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
/* /*
* If we are not deadlocked, but are waiting on an autovacuum-induced * If we are not deadlocked, but are waiting on an autovacuum-induced
...@@ -1487,24 +1487,24 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1487,24 +1487,24 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data)))); lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
} }
if (myWaitStatus == STATUS_WAITING) if (myWaitStatus == PROC_WAIT_STATUS_WAITING)
ereport(LOG, ereport(LOG,
(errmsg("process %d still waiting for %s on %s after %ld.%03d ms", (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
MyProcPid, modename, buf.data, msecs, usecs), MyProcPid, modename, buf.data, msecs, usecs),
(errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.", (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
"Processes holding the lock: %s. Wait queue: %s.", "Processes holding the lock: %s. Wait queue: %s.",
lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data)))); lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
else if (myWaitStatus == STATUS_OK) else if (myWaitStatus == PROC_WAIT_STATUS_OK)
ereport(LOG, ereport(LOG,
(errmsg("process %d acquired %s on %s after %ld.%03d ms", (errmsg("process %d acquired %s on %s after %ld.%03d ms",
MyProcPid, modename, buf.data, msecs, usecs))); MyProcPid, modename, buf.data, msecs, usecs)));
else else
{ {
Assert(myWaitStatus == STATUS_ERROR); Assert(myWaitStatus == PROC_WAIT_STATUS_ERROR);
/* /*
* Currently, the deadlock checker always kicks its own * Currently, the deadlock checker always kicks its own
* process, which means that we'll only see STATUS_ERROR when * process, which means that we'll only see PROC_WAIT_STATUS_ERROR when
* deadlock_state == DS_HARD_DEADLOCK, and there's no need to * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
* print redundant messages. But for completeness and * print redundant messages. But for completeness and
* future-proofing, print a message if it looks like someone * future-proofing, print a message if it looks like someone
...@@ -1529,7 +1529,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1529,7 +1529,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
pfree(lock_holders_sbuf.data); pfree(lock_holders_sbuf.data);
pfree(lock_waiters_sbuf.data); pfree(lock_waiters_sbuf.data);
} }
} while (myWaitStatus == STATUS_WAITING); } while (myWaitStatus == PROC_WAIT_STATUS_WAITING);
/* /*
* Disable the timers, if they are still running. As in LockErrorCleanup, * Disable the timers, if they are still running. As in LockErrorCleanup,
...@@ -1568,7 +1568,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1568,7 +1568,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
/* /*
* If we got the lock, be sure to remember it in the locallock table. * If we got the lock, be sure to remember it in the locallock table.
*/ */
if (MyProc->waitStatus == STATUS_OK) if (MyProc->waitStatus == PROC_WAIT_STATUS_OK)
GrantAwaitedLock(); GrantAwaitedLock();
/* /*
...@@ -1590,10 +1590,10 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) ...@@ -1590,10 +1590,10 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
* XXX: presently, this code is only used for the "success" case, and only * XXX: presently, this code is only used for the "success" case, and only
* works correctly for that case. To clean up in failure case, would need * works correctly for that case. To clean up in failure case, would need
* to twiddle the lock's request counts too --- see RemoveFromWaitQueue. * to twiddle the lock's request counts too --- see RemoveFromWaitQueue.
* Hence, in practice the waitStatus parameter must be STATUS_OK. * Hence, in practice the waitStatus parameter must be PROC_WAIT_STATUS_OK.
*/ */
PGPROC * PGPROC *
ProcWakeup(PGPROC *proc, int waitStatus) ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
{ {
PGPROC *retProc; PGPROC *retProc;
...@@ -1601,7 +1601,7 @@ ProcWakeup(PGPROC *proc, int waitStatus) ...@@ -1601,7 +1601,7 @@ ProcWakeup(PGPROC *proc, int waitStatus)
if (proc->links.prev == NULL || if (proc->links.prev == NULL ||
proc->links.next == NULL) proc->links.next == NULL)
return NULL; return NULL;
Assert(proc->waitStatus == STATUS_WAITING); Assert(proc->waitStatus == PROC_WAIT_STATUS_WAITING);
/* Save next process before we zap the list link */ /* Save next process before we zap the list link */
retProc = (PGPROC *) proc->links.next; retProc = (PGPROC *) proc->links.next;
...@@ -1657,7 +1657,7 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock) ...@@ -1657,7 +1657,7 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
{ {
/* OK to waken */ /* OK to waken */
GrantLock(lock, proc->waitProcLock, lockmode); GrantLock(lock, proc->waitProcLock, lockmode);
proc = ProcWakeup(proc, STATUS_OK); proc = ProcWakeup(proc, PROC_WAIT_STATUS_OK);
/* /*
* ProcWakeup removes proc from the lock's waiting process queue * ProcWakeup removes proc from the lock's waiting process queue
...@@ -1737,7 +1737,7 @@ CheckDeadLock(void) ...@@ -1737,7 +1737,7 @@ CheckDeadLock(void)
* preserve the flexibility to kill some other transaction than the * preserve the flexibility to kill some other transaction than the
* one detecting the deadlock.) * one detecting the deadlock.)
* *
* RemoveFromWaitQueue sets MyProc->waitStatus to STATUS_ERROR, so * RemoveFromWaitQueue sets MyProc->waitStatus to PROC_WAIT_STATUS_ERROR, so
* ProcSleep will report an error after we return from the signal * ProcSleep will report an error after we return from the signal
* handler. * handler.
*/ */
......
...@@ -1133,7 +1133,6 @@ typedef union PGAlignedXLogBlock ...@@ -1133,7 +1133,6 @@ typedef union PGAlignedXLogBlock
#define STATUS_OK (0) #define STATUS_OK (0)
#define STATUS_ERROR (-1) #define STATUS_ERROR (-1)
#define STATUS_EOF (-2) #define STATUS_EOF (-2)
#define STATUS_WAITING (2)
/* /*
* gettext support * gettext support
......
...@@ -76,6 +76,13 @@ struct XidCache ...@@ -76,6 +76,13 @@ struct XidCache
*/ */
#define INVALID_PGPROCNO PG_INT32_MAX #define INVALID_PGPROCNO PG_INT32_MAX
typedef enum
{
PROC_WAIT_STATUS_OK,
PROC_WAIT_STATUS_WAITING,
PROC_WAIT_STATUS_ERROR,
} ProcWaitStatus;
/* /*
* Each backend has a PGPROC struct in shared memory. There is also a list of * Each backend has a PGPROC struct in shared memory. There is also a list of
* currently-unused PGPROC structs that will be reallocated to new backends. * currently-unused PGPROC structs that will be reallocated to new backends.
...@@ -99,7 +106,7 @@ struct PGPROC ...@@ -99,7 +106,7 @@ struct PGPROC
PGPROC **procgloballist; /* procglobal list that owns this PGPROC */ PGPROC **procgloballist; /* procglobal list that owns this PGPROC */
PGSemaphore sem; /* ONE semaphore to sleep on */ PGSemaphore sem; /* ONE semaphore to sleep on */
int waitStatus; /* STATUS_WAITING, STATUS_OK or STATUS_ERROR */ ProcWaitStatus waitStatus;
Latch procLatch; /* generic latch for process */ Latch procLatch; /* generic latch for process */
...@@ -315,8 +322,8 @@ extern bool HaveNFreeProcs(int n); ...@@ -315,8 +322,8 @@ extern bool HaveNFreeProcs(int n);
extern void ProcReleaseLocks(bool isCommit); extern void ProcReleaseLocks(bool isCommit);
extern void ProcQueueInit(PROC_QUEUE *queue); extern void ProcQueueInit(PROC_QUEUE *queue);
extern int ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable); extern ProcWaitStatus ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable);
extern PGPROC *ProcWakeup(PGPROC *proc, int waitStatus); extern PGPROC *ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus);
extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock); extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock);
extern void CheckDeadLockAlert(void); extern void CheckDeadLockAlert(void);
extern bool IsWaitingForLock(void); extern bool IsWaitingForLock(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment