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

Commit87abcb4

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 parent4f33572 commit87abcb4

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
void*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);
@@ -403,6 +405,8 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
403405
{
404406
if (nowait)
405407
{
408+
if (shm_mq_counterparty_gone(mq,mqh->mqh_handle))
409+
returnSHM_MQ_DETACHED;
406410
if (shm_mq_get_sender(mq)==NULL)
407411
returnSHM_MQ_WOULD_BLOCK;
408412
}
@@ -689,6 +693,11 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, void *data, bool nowait,
689693
*/
690694
if (nowait)
691695
{
696+
if (shm_mq_counterparty_gone(mq,mqh->mqh_handle))
697+
{
698+
*bytes_written=sent;
699+
returnSHM_MQ_DETACHED;
700+
}
692701
if (shm_mq_get_receiver(mq)==NULL)
693702
{
694703
*bytes_written=sent;
@@ -842,6 +851,45 @@ shm_mq_receive_bytes(shm_mq *mq, Size bytes_needed, bool nowait,
842851
}
843852
}
844853

854+
/*
855+
* Test whether a counterparty who may not even be alive yet is definitely gone.
856+
*/
857+
staticbool
858+
shm_mq_counterparty_gone(volatileshm_mq*mq,BackgroundWorkerHandle*handle)
859+
{
860+
booldetached;
861+
pid_tpid;
862+
863+
/* Acquire the lock just long enough to check the pointer. */
864+
SpinLockAcquire(&mq->mq_mutex);
865+
detached=mq->mq_detached;
866+
SpinLockRelease(&mq->mq_mutex);
867+
868+
/* If the queue has been detached, counterparty is definitely gone. */
869+
if (detached)
870+
return true;
871+
872+
/* If there's a handle, check worker status. */
873+
if (handle!=NULL)
874+
{
875+
BgwHandleStatusstatus;
876+
877+
/* Check for unexpected worker death. */
878+
status=GetBackgroundWorkerPid(handle,&pid);
879+
if (status!=BGWH_STARTED&&status!=BGWH_NOT_YET_STARTED)
880+
{
881+
/* Mark it detached, just to make it official. */
882+
SpinLockAcquire(&mq->mq_mutex);
883+
mq->mq_detached= true;
884+
SpinLockRelease(&mq->mq_mutex);
885+
return true;
886+
}
887+
}
888+
889+
/* Counterparty is not definitively gone. */
890+
return false;
891+
}
892+
845893
/*
846894
* This is used when a process is waiting for its counterpart to attach to the
847895
* queue. We exit when the other process attaches as expected, or, if

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp