Skip to content

Commit 038aa89

Browse files
committed
shm_mq: Third attempt at fixing nowait behavior in shm_mq_receive.
Commit a1480ec purported to fix the problems with commit b2ccb5f, but it didn't completely fix them. The problem is that the checks were performed in the wrong order, leading to a race condition. If the sender attached, sent a message, and detached after the receiver called shm_mq_get_sender and before the receiver called shm_mq_counterparty_gone, we'd incorrectly return SHM_MQ_DETACHED before all messages were read. Repair by reversing the order of operations, and add a long comment explaining why this new logic is (hopefully) correct.
1 parent 11e7f9d commit 038aa89

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/backend/storage/ipc/shm_mq.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,11 +405,26 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
405405
{
406406
if (nowait)
407407
{
408+
int counterparty_gone;
409+
410+
/*
411+
* We shouldn't return at this point at all unless the sender
412+
* hasn't attached yet. However, the correct return value depends
413+
* on whether the sender is still attached. If we first test
414+
* whether the sender has ever attached and then test whether the
415+
* sender has detached, there's a race condition: a sender that
416+
* attaches and detaches very quickly might fool us into thinking
417+
* the sender never attached at all. So, test whether our
418+
* counterparty is definitively gone first, and only afterwards
419+
* check whether the sender ever attached in the first place.
420+
*/
421+
counterparty_gone = shm_mq_counterparty_gone(mq, mqh->mqh_handle);
408422
if (shm_mq_get_sender(mq) == NULL)
409423
{
410-
if (shm_mq_counterparty_gone(mq, mqh->mqh_handle))
424+
if (counterparty_gone)
411425
return SHM_MQ_DETACHED;
412-
return SHM_MQ_WOULD_BLOCK;
426+
else
427+
return SHM_MQ_WOULD_BLOCK;
413428
}
414429
}
415430
else if (!shm_mq_wait_internal(mq, &mq->mq_sender, mqh->mqh_handle)

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