Allow WaitLatch() to be used without a latch.
Due to flaws in commit 3347c982ba
, using WaitLatch() without
WL_LATCH_SET could cause an assertion failure or crash. Repair.
While here, also add a check that the latch we're switching to belongs
to this backend, when changing from one latch to another.
Discussion: https://postgr.es/m/CA%2BhUKGK1607VmtrDUHQXrsooU%3Dap4g4R2yaoByWOOA3m8xevUQ%40mail.gmail.com
This commit is contained in:
parent
2e3c19462d
commit
733fa9aa51
|
@ -924,7 +924,22 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
|
|||
|
||||
if (events == WL_LATCH_SET)
|
||||
{
|
||||
if (latch && latch->owner_pid != MyProcPid)
|
||||
elog(ERROR, "cannot wait on a latch owned by another process");
|
||||
set->latch = latch;
|
||||
/*
|
||||
* On Unix, we don't need to modify the kernel object because the
|
||||
* underlying pipe is the same for all latches so we can return
|
||||
* immediately. On Windows, we need to update our array of handles,
|
||||
* but we leave the old one in place and tolerate spurious wakeups if
|
||||
* the latch is disabled.
|
||||
*/
|
||||
#if defined(WAIT_USE_WIN32)
|
||||
if (!latch)
|
||||
return;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WAIT_USE_EPOLL)
|
||||
|
@ -1386,7 +1401,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
|
|||
/* There's data in the self-pipe, clear it. */
|
||||
drainSelfPipe();
|
||||
|
||||
if (set->latch->is_set)
|
||||
if (set->latch && set->latch->is_set)
|
||||
{
|
||||
occurred_events->fd = PGINVALID_SOCKET;
|
||||
occurred_events->events = WL_LATCH_SET;
|
||||
|
@ -1536,7 +1551,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
|
|||
/* There's data in the self-pipe, clear it. */
|
||||
drainSelfPipe();
|
||||
|
||||
if (set->latch->is_set)
|
||||
if (set->latch && set->latch->is_set)
|
||||
{
|
||||
occurred_events->fd = PGINVALID_SOCKET;
|
||||
occurred_events->events = WL_LATCH_SET;
|
||||
|
@ -1645,7 +1660,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
|
|||
/* There's data in the self-pipe, clear it. */
|
||||
drainSelfPipe();
|
||||
|
||||
if (set->latch->is_set)
|
||||
if (set->latch && set->latch->is_set)
|
||||
{
|
||||
occurred_events->fd = PGINVALID_SOCKET;
|
||||
occurred_events->events = WL_LATCH_SET;
|
||||
|
@ -1812,7 +1827,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
|
|||
if (!ResetEvent(set->latch->event))
|
||||
elog(ERROR, "ResetEvent failed: error code %lu", GetLastError());
|
||||
|
||||
if (set->latch->is_set)
|
||||
if (set->latch && set->latch->is_set)
|
||||
{
|
||||
occurred_events->fd = PGINVALID_SOCKET;
|
||||
occurred_events->events = WL_LATCH_SET;
|
||||
|
|
Loading…
Reference in New Issue