Skip to content

Commit 733fa9a

Browse files
committed
Allow WaitLatch() to be used without a latch.
Due to flaws in commit 3347c98, 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
1 parent 2e3c194 commit 733fa9a

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

src/backend/storage/ipc/latch.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,22 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
924924

925925
if (events == WL_LATCH_SET)
926926
{
927+
if (latch && latch->owner_pid != MyProcPid)
928+
elog(ERROR, "cannot wait on a latch owned by another process");
927929
set->latch = latch;
930+
/*
931+
* On Unix, we don't need to modify the kernel object because the
932+
* underlying pipe is the same for all latches so we can return
933+
* immediately. On Windows, we need to update our array of handles,
934+
* but we leave the old one in place and tolerate spurious wakeups if
935+
* the latch is disabled.
936+
*/
937+
#if defined(WAIT_USE_WIN32)
938+
if (!latch)
939+
return;
940+
#else
941+
return;
942+
#endif
928943
}
929944

930945
#if defined(WAIT_USE_EPOLL)
@@ -1386,7 +1401,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
13861401
/* There's data in the self-pipe, clear it. */
13871402
drainSelfPipe();
13881403

1389-
if (set->latch->is_set)
1404+
if (set->latch && set->latch->is_set)
13901405
{
13911406
occurred_events->fd = PGINVALID_SOCKET;
13921407
occurred_events->events = WL_LATCH_SET;
@@ -1536,7 +1551,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
15361551
/* There's data in the self-pipe, clear it. */
15371552
drainSelfPipe();
15381553

1539-
if (set->latch->is_set)
1554+
if (set->latch && set->latch->is_set)
15401555
{
15411556
occurred_events->fd = PGINVALID_SOCKET;
15421557
occurred_events->events = WL_LATCH_SET;
@@ -1645,7 +1660,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
16451660
/* There's data in the self-pipe, clear it. */
16461661
drainSelfPipe();
16471662

1648-
if (set->latch->is_set)
1663+
if (set->latch && set->latch->is_set)
16491664
{
16501665
occurred_events->fd = PGINVALID_SOCKET;
16511666
occurred_events->events = WL_LATCH_SET;
@@ -1812,7 +1827,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
18121827
if (!ResetEvent(set->latch->event))
18131828
elog(ERROR, "ResetEvent failed: error code %lu", GetLastError());
18141829

1815-
if (set->latch->is_set)
1830+
if (set->latch && set->latch->is_set)
18161831
{
18171832
occurred_events->fd = PGINVALID_SOCKET;
18181833
occurred_events->events = WL_LATCH_SET;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy