aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2018-03-05 15:12:49 -0500
committerRobert Haas <rhaas@postgresql.org>2018-03-05 15:12:49 -0500
commit42d7074ebb832e511d1edec8091cd474d169eef1 (patch)
tree8a280a8c71ebe0e82c018230207f8193052925ef
parent2f3e2340cd1b67e91cefdf45e4c915297d1034e2 (diff)
downloadpostgresql-42d7074ebb832e511d1edec8091cd474d169eef1.tar.gz
postgresql-42d7074ebb832e511d1edec8091cd474d169eef1.zip
shm_mq: Fix detach race condition.
Commit 34db06ef9a1d7f36391c64293bf1e0ce44a33915 adopted a lock-free design for shm_mq.c, but it introduced a race condition that could lose messages. When shm_mq_receive_bytes() detects that the other end has detached, it must make sure that it has seen the final version of mq_bytes_written, or it might miss a message sent before detaching. Thomas Munro Discussion: https://postgr.es/m/CAEepm%3D2myZ4qxpt1a%3DC%2BwEv3o188K13K3UvD-44FK0SdAzHy%2Bw%40mail.gmail.com
-rw-r--r--src/backend/storage/ipc/shm_mq.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index 40df8e1251e..3faace249ff 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -1058,7 +1058,19 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait,
* detached.
*/
if (mq->mq_detached)
+ {
+ /*
+ * If the writer advanced mq_bytes_written and then set
+ * mq_detached, we might not have read the final value of
+ * mq_bytes_written above. Insert a read barrier and then check
+ * again if mq_bytes_written has advanced.
+ */
+ pg_read_barrier();
+ if (written != pg_atomic_read_u64(&mq->mq_bytes_written))
+ continue;
+
return SHM_MQ_DETACHED;
+ }
/*
* We didn't get enough data to satisfy the request, so mark any data