Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb2ccb5f

Browse files
committed
shm_mq: Fix failure to notice a dead counterparty when nowait is used.
The shm_mq mechanism was intended to optionally notice when the processon the other end of the queue fails to attach to the queue. It doesthis by allowing the user to pass a BackgroundWorkerHandle; if thebackground worker in question is launched and dies without attachingto the queue, then we know it never will. This logic works OK inblocking mode, but when called with nowait = true we fail to noticethat this has happened due to an asymmetry in the logic. Repair.Reported off-list by Rushabh Lathia. Patch by me.
1 parent31ba62c commitb2ccb5f

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

‎src/backend/storage/ipc/shm_mq.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ static shm_mq_result shm_mq_send_bytes(shm_mq_handle *mq, Size nbytes,
142142
constvoid*data,boolnowait,Size*bytes_written);
143143
staticshm_mq_resultshm_mq_receive_bytes(shm_mq*mq,Sizebytes_needed,
144144
boolnowait,Size*nbytesp,void**datap);
145+
staticboolshm_mq_counterparty_gone(volatileshm_mq*mq,
146+
BackgroundWorkerHandle*handle);
145147
staticboolshm_mq_wait_internal(volatileshm_mq*mq,PGPROC*volatile*ptr,
146148
BackgroundWorkerHandle*handle);
147149
staticuint64shm_mq_get_bytes_read(volatileshm_mq*mq,bool*detached);
@@ -499,6 +501,8 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
499501
{
500502
if (nowait)
501503
{
504+
if (shm_mq_counterparty_gone(mq,mqh->mqh_handle))
505+
returnSHM_MQ_DETACHED;
502506
if (shm_mq_get_sender(mq)==NULL)
503507
returnSHM_MQ_WOULD_BLOCK;
504508
}
@@ -794,6 +798,11 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data,
794798
*/
795799
if (nowait)
796800
{
801+
if (shm_mq_counterparty_gone(mq,mqh->mqh_handle))
802+
{
803+
*bytes_written=sent;
804+
returnSHM_MQ_DETACHED;
805+
}
797806
if (shm_mq_get_receiver(mq)==NULL)
798807
{
799808
*bytes_written=sent;
@@ -947,6 +956,45 @@ shm_mq_receive_bytes(shm_mq *mq, Size bytes_needed, bool nowait,
947956
}
948957
}
949958

959+
/*
960+
* Test whether a counterparty who may not even be alive yet is definitely gone.
961+
*/
962+
staticbool
963+
shm_mq_counterparty_gone(volatileshm_mq*mq,BackgroundWorkerHandle*handle)
964+
{
965+
booldetached;
966+
pid_tpid;
967+
968+
/* Acquire the lock just long enough to check the pointer. */
969+
SpinLockAcquire(&mq->mq_mutex);
970+
detached=mq->mq_detached;
971+
SpinLockRelease(&mq->mq_mutex);
972+
973+
/* If the queue has been detached, counterparty is definitely gone. */
974+
if (detached)
975+
return true;
976+
977+
/* If there's a handle, check worker status. */
978+
if (handle!=NULL)
979+
{
980+
BgwHandleStatusstatus;
981+
982+
/* Check for unexpected worker death. */
983+
status=GetBackgroundWorkerPid(handle,&pid);
984+
if (status!=BGWH_STARTED&&status!=BGWH_NOT_YET_STARTED)
985+
{
986+
/* Mark it detached, just to make it official. */
987+
SpinLockAcquire(&mq->mq_mutex);
988+
mq->mq_detached= true;
989+
SpinLockRelease(&mq->mq_mutex);
990+
return true;
991+
}
992+
}
993+
994+
/* Counterparty is not definitively gone. */
995+
return false;
996+
}
997+
950998
/*
951999
* This is used when a process is waiting for its counterpart to attach to the
9521000
* queue. We exit when the other process attaches as expected, or, if

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp