Skip to content

Commit caf89b3

Browse files
committed
Fix attach-related race condition in shm_mq_send_bytes.
Spotted by Antonin Houska.
1 parent 37163e2 commit caf89b3

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

src/backend/storage/ipc/shm_mq.c

+21-17
Original file line numberDiff line numberDiff line change
@@ -777,33 +777,37 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
777777
return SHM_MQ_DETACHED;
778778
}
779779

780-
if (available == 0)
780+
if (available == 0 && !mqh->mqh_counterparty_attached)
781781
{
782-
shm_mq_result res;
783-
784782
/*
785783
* The queue is full, so if the receiver isn't yet known to be
786784
* attached, we must wait for that to happen.
787785
*/
788-
if (!mqh->mqh_counterparty_attached)
786+
if (nowait)
789787
{
790-
if (nowait)
788+
if (shm_mq_get_receiver(mq) == NULL)
791789
{
792-
if (shm_mq_get_receiver(mq) == NULL)
793-
{
794-
*bytes_written = sent;
795-
return SHM_MQ_WOULD_BLOCK;
796-
}
797-
}
798-
else if (!shm_mq_wait_internal(mq, &mq->mq_receiver,
799-
mqh->mqh_handle))
800-
{
801-
mq->mq_detached = true;
802790
*bytes_written = sent;
803-
return SHM_MQ_DETACHED;
791+
return SHM_MQ_WOULD_BLOCK;
804792
}
805-
mqh->mqh_counterparty_attached = true;
806793
}
794+
else if (!shm_mq_wait_internal(mq, &mq->mq_receiver,
795+
mqh->mqh_handle))
796+
{
797+
mq->mq_detached = true;
798+
*bytes_written = sent;
799+
return SHM_MQ_DETACHED;
800+
}
801+
mqh->mqh_counterparty_attached = true;
802+
803+
/*
804+
* The receiver may have read some data after attaching, so we
805+
* must not wait without rechecking the queue state.
806+
*/
807+
}
808+
else if (available == 0)
809+
{
810+
shm_mq_result res;
807811

808812
/* Let the receiver know that we need them to read some data. */
809813
res = shm_mq_notify_receiver(mq);

0 commit comments

Comments
 (0)