mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 00:01:41 -04:00
Compare commits
No commits in common. "81038228582aa92718be2afcb7ddb67a5a19fa43" and "d29a4fbacfb7998df16b6fabcd33400a5ae07c43" have entirely different histories.
8103822858
...
d29a4fbacf
@ -485,7 +485,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
|
||||
proc->roleId = owner;
|
||||
proc->tempNamespaceId = InvalidOid;
|
||||
proc->isBackgroundWorker = false;
|
||||
proc->lwWaiting = LW_WS_NOT_WAITING;
|
||||
proc->lwWaiting = false;
|
||||
proc->lwWaitMode = 0;
|
||||
proc->waitLock = NULL;
|
||||
proc->waitProcLock = NULL;
|
||||
|
@ -290,7 +290,6 @@ pgwin32_socket(int af, int type, int protocol)
|
||||
if (ioctlsocket(s, FIONBIO, &on))
|
||||
{
|
||||
TranslateSocketError();
|
||||
closesocket(s);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
errno = 0;
|
||||
|
@ -913,15 +913,6 @@ LWLockWakeup(LWLock *lock)
|
||||
wokeup_somebody = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal that the process isn't on the wait list anymore. This allows
|
||||
* LWLockDequeueSelf() to remove itself of the waitlist with a
|
||||
* proclist_delete(), rather than having to check if it has been
|
||||
* removed from the list.
|
||||
*/
|
||||
Assert(waiter->lwWaiting == LW_WS_WAITING);
|
||||
waiter->lwWaiting = LW_WS_PENDING_WAKEUP;
|
||||
|
||||
/*
|
||||
* Once we've woken up an exclusive lock, there's no point in waking
|
||||
* up anybody else.
|
||||
@ -979,7 +970,7 @@ LWLockWakeup(LWLock *lock)
|
||||
* another lock.
|
||||
*/
|
||||
pg_write_barrier();
|
||||
waiter->lwWaiting = LW_WS_NOT_WAITING;
|
||||
waiter->lwWaiting = false;
|
||||
PGSemaphoreUnlock(waiter->sem);
|
||||
}
|
||||
}
|
||||
@ -1000,7 +991,7 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
|
||||
if (MyProc == NULL)
|
||||
elog(PANIC, "cannot wait without a PGPROC structure");
|
||||
|
||||
if (MyProc->lwWaiting != LW_WS_NOT_WAITING)
|
||||
if (MyProc->lwWaiting)
|
||||
elog(PANIC, "queueing for lock while waiting on another one");
|
||||
|
||||
LWLockWaitListLock(lock);
|
||||
@ -1008,7 +999,7 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
|
||||
/* setting the flag is protected by the spinlock */
|
||||
pg_atomic_fetch_or_u32(&lock->state, LW_FLAG_HAS_WAITERS);
|
||||
|
||||
MyProc->lwWaiting = LW_WS_WAITING;
|
||||
MyProc->lwWaiting = true;
|
||||
MyProc->lwWaitMode = mode;
|
||||
|
||||
/* LW_WAIT_UNTIL_FREE waiters are always at the front of the queue */
|
||||
@ -1036,7 +1027,8 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
|
||||
static void
|
||||
LWLockDequeueSelf(LWLock *lock)
|
||||
{
|
||||
bool on_waitlist;
|
||||
bool found = false;
|
||||
proclist_mutable_iter iter;
|
||||
|
||||
#ifdef LWLOCK_STATS
|
||||
lwlock_stats *lwstats;
|
||||
@ -1049,13 +1041,18 @@ LWLockDequeueSelf(LWLock *lock)
|
||||
LWLockWaitListLock(lock);
|
||||
|
||||
/*
|
||||
* Remove ourselves from the waitlist, unless we've already been
|
||||
* removed. The removal happens with the wait list lock held, so there's
|
||||
* no race in this check.
|
||||
* Can't just remove ourselves from the list, but we need to iterate over
|
||||
* all entries as somebody else could have dequeued us.
|
||||
*/
|
||||
on_waitlist = MyProc->lwWaiting == LW_WS_WAITING;
|
||||
if (on_waitlist)
|
||||
proclist_delete(&lock->waiters, MyProc->pgprocno, lwWaitLink);
|
||||
proclist_foreach_modify(iter, &lock->waiters, lwWaitLink)
|
||||
{
|
||||
if (iter.cur == MyProc->pgprocno)
|
||||
{
|
||||
found = true;
|
||||
proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (proclist_is_empty(&lock->waiters) &&
|
||||
(pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS) != 0)
|
||||
@ -1067,8 +1064,8 @@ LWLockDequeueSelf(LWLock *lock)
|
||||
LWLockWaitListUnlock(lock);
|
||||
|
||||
/* clear waiting state again, nice for debugging */
|
||||
if (on_waitlist)
|
||||
MyProc->lwWaiting = LW_WS_NOT_WAITING;
|
||||
if (found)
|
||||
MyProc->lwWaiting = false;
|
||||
else
|
||||
{
|
||||
int extraWaits = 0;
|
||||
@ -1092,7 +1089,7 @@ LWLockDequeueSelf(LWLock *lock)
|
||||
for (;;)
|
||||
{
|
||||
PGSemaphoreLock(MyProc->sem);
|
||||
if (MyProc->lwWaiting == LW_WS_NOT_WAITING)
|
||||
if (!MyProc->lwWaiting)
|
||||
break;
|
||||
extraWaits++;
|
||||
}
|
||||
@ -1242,7 +1239,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
|
||||
for (;;)
|
||||
{
|
||||
PGSemaphoreLock(proc->sem);
|
||||
if (proc->lwWaiting == LW_WS_NOT_WAITING)
|
||||
if (!proc->lwWaiting)
|
||||
break;
|
||||
extraWaits++;
|
||||
}
|
||||
@ -1402,7 +1399,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
|
||||
for (;;)
|
||||
{
|
||||
PGSemaphoreLock(proc->sem);
|
||||
if (proc->lwWaiting == LW_WS_NOT_WAITING)
|
||||
if (!proc->lwWaiting)
|
||||
break;
|
||||
extraWaits++;
|
||||
}
|
||||
@ -1614,7 +1611,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
|
||||
for (;;)
|
||||
{
|
||||
PGSemaphoreLock(proc->sem);
|
||||
if (proc->lwWaiting == LW_WS_NOT_WAITING)
|
||||
if (!proc->lwWaiting)
|
||||
break;
|
||||
extraWaits++;
|
||||
}
|
||||
@ -1693,10 +1690,6 @@ LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
|
||||
|
||||
proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
|
||||
proclist_push_tail(&wakeup, iter.cur, lwWaitLink);
|
||||
|
||||
/* see LWLockWakeup() */
|
||||
Assert(waiter->lwWaiting == LW_WS_WAITING);
|
||||
waiter->lwWaiting = LW_WS_PENDING_WAKEUP;
|
||||
}
|
||||
|
||||
/* We are done updating shared state of the lock itself. */
|
||||
@ -1712,7 +1705,7 @@ LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
|
||||
proclist_delete(&wakeup, iter.cur, lwWaitLink);
|
||||
/* check comment in LWLockWakeup() about this barrier */
|
||||
pg_write_barrier();
|
||||
waiter->lwWaiting = LW_WS_NOT_WAITING;
|
||||
waiter->lwWaiting = false;
|
||||
PGSemaphoreUnlock(waiter->sem);
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ InitProcess(void)
|
||||
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
|
||||
if (IsAutoVacuumWorkerProcess())
|
||||
MyPgXact->vacuumFlags |= PROC_IS_AUTOVACUUM;
|
||||
MyProc->lwWaiting = LW_WS_NOT_WAITING;
|
||||
MyProc->lwWaiting = false;
|
||||
MyProc->lwWaitMode = 0;
|
||||
MyProc->waitLock = NULL;
|
||||
MyProc->waitProcLock = NULL;
|
||||
@ -583,7 +583,7 @@ InitAuxiliaryProcess(void)
|
||||
MyPgXact->delayChkpt = false;
|
||||
MyProc->delayChkptEnd = false;
|
||||
MyPgXact->vacuumFlags = 0;
|
||||
MyProc->lwWaiting = LW_WS_NOT_WAITING;
|
||||
MyProc->lwWaiting = false;
|
||||
MyProc->lwWaitMode = 0;
|
||||
MyProc->waitLock = NULL;
|
||||
MyProc->waitProcLock = NULL;
|
||||
|
@ -24,14 +24,6 @@
|
||||
|
||||
struct PGPROC;
|
||||
|
||||
/* what state of the wait process is a backend in */
|
||||
typedef enum LWLockWaitState
|
||||
{
|
||||
LW_WS_NOT_WAITING, /* not currently waiting / woken up */
|
||||
LW_WS_WAITING, /* currently waiting */
|
||||
LW_WS_PENDING_WAKEUP /* removed from waitlist, but not yet signalled */
|
||||
} LWLockWaitState;
|
||||
|
||||
/*
|
||||
* Code outside of lwlock.c should not manipulate the contents of this
|
||||
* structure directly, but we have to declare it here to allow LWLocks to be
|
||||
|
@ -134,7 +134,7 @@ struct PGPROC
|
||||
bool recoveryConflictPending;
|
||||
|
||||
/* Info about LWLock the process is currently waiting for, if any. */
|
||||
uint8 lwWaiting; /* see LWLockWaitState */
|
||||
bool lwWaiting; /* true if waiting for an LW lock */
|
||||
uint8 lwWaitMode; /* lwlock mode being waited for */
|
||||
proclist_node lwWaitLink; /* position in LW lock wait list */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user