Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 44339b8

Browse files
committed
shm_mq: After a send fails with SHM_MQ_DETACHED, later ones should too.
Prior to this patch, it was occasionally possible, after shm_mq_sendv had previously returned SHM_MQ_DETACHED, for a later shm_mq_sendv operation to fail an assertion instead of just again returning SHM_MQ_ATTACHED. From the shm_mq code's point of view, it was expecting to be called again with the same arguments, since the previous operation had only partially completed. However, a caller who isn't using non-blocking mode won't be prepared to repeat the call with the same arguments, and this code shouldn't expect that they will. Repair in such a way that we'll be OK whether the next call uses the same arguments or not. Found by Andreas Seltenreich. Analysis and sketch of fix by Amit Kapila. Patch by me, reviewed by Amit Kapila.
1 parent e191a69 commit 44339b8

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

src/backend/storage/ipc/shm_mq.c

+30-2
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,15 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
366366
res = shm_mq_send_bytes(mqh, sizeof(Size) - mqh->mqh_partial_bytes,
367367
((char *) &nbytes) +mqh->mqh_partial_bytes,
368368
nowait, &bytes_written);
369-
mqh->mqh_partial_bytes += bytes_written;
370-
if (res != SHM_MQ_SUCCESS)
369+
370+
if (res == SHM_MQ_DETACHED)
371+
{
372+
/* Reset state in case caller tries to send another message. */
373+
mqh->mqh_partial_bytes = 0;
374+
mqh->mqh_length_word_complete = false;
371375
return res;
376+
}
377+
mqh->mqh_partial_bytes += bytes_written;
372378

373379
if (mqh->mqh_partial_bytes >= sizeof(Size))
374380
{
@@ -378,6 +384,9 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
378384
mqh->mqh_length_word_complete = true;
379385
}
380386

387+
if (res != SHM_MQ_SUCCESS)
388+
return res;
389+
381390
/* Length word can't be split unless bigger than required alignment. */
382391
Assert(mqh->mqh_length_word_complete || sizeof(Size) > MAXIMUM_ALIGNOF);
383392
}
@@ -432,7 +441,17 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
432441
break;
433442
}
434443
}
444+
435445
res = shm_mq_send_bytes(mqh, j, tmpbuf, nowait, &bytes_written);
446+
447+
if (res == SHM_MQ_DETACHED)
448+
{
449+
/* Reset state in case caller tries to send another message. */
450+
mqh->mqh_partial_bytes = 0;
451+
mqh->mqh_length_word_complete = false;
452+
return res;
453+
}
454+
436455
mqh->mqh_partial_bytes += bytes_written;
437456
if (res != SHM_MQ_SUCCESS)
438457
return res;
@@ -449,6 +468,15 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
449468
chunksize = MAXALIGN_DOWN(chunksize);
450469
res = shm_mq_send_bytes(mqh, chunksize, &iov[which_iov].data[offset],
451470
nowait, &bytes_written);
471+
472+
if (res == SHM_MQ_DETACHED)
473+
{
474+
/* Reset state in case caller tries to send another message. */
475+
mqh->mqh_length_word_complete = false;
476+
mqh->mqh_partial_bytes = 0;
477+
return res;
478+
}
479+
452480
mqh->mqh_partial_bytes += bytes_written;
453481
offset += bytes_written;
454482
if (res != SHM_MQ_SUCCESS)

0 commit comments

Comments
 (0)