aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-02-27 19:17:07 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-02-27 19:28:51 +0200
commit3a9e64aa0d96c8ffb6c682b082d0f72b1d373327 (patch)
tree868e56e125b00ec17a0bda8514e7e3c4c4adfcab /src
parent5ddf38f21d3f34c794de2d1c9b61ba92a7d6f39c (diff)
downloadpostgresql-3a9e64aa0d96c8ffb6c682b082d0f72b1d373327.tar.gz
postgresql-3a9e64aa0d96c8ffb6c682b082d0f72b1d373327.zip
Cannot use WL_SOCKET_WRITEABLE without WL_SOCKET_READABLE.
In copy-out mode, the frontend should not send any messages until the backend has finished streaming, by sending a CopyDone message. I'm not sure if it would be legal for the client to send a new query before receiving the CopyDone message from the backend, but trying to support that would require bigger changes to the backend code structure. Fixes an assertion failure reported by Fujii Masao.
Diffstat (limited to 'src')
-rw-r--r--src/backend/replication/walsender.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 490b121362f..266cd64f6fa 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -674,12 +674,7 @@ ProcessRepliesIfAny(void)
int r;
bool received = false;
- /*
- * If we already received a CopyDone from the frontend, any subsequent
- * message is the beginning of a new command, and should be processed in
- * the main processing loop.
- */
- while (!streamingDoneReceiving)
+ for (;;)
{
r = pq_getbyte_if_available(&firstchar);
if (r < 0)
@@ -696,6 +691,19 @@ ProcessRepliesIfAny(void)
break;
}
+ /*
+ * If we already received a CopyDone from the frontend, the frontend
+ * should not send us anything until we've closed our end of the COPY.
+ * XXX: In theory, the frontend could already send the next command
+ * before receiving the CopyDone, but libpq doesn't currently allow
+ * that.
+ */
+ if (streamingDoneReceiving && firstchar != 'X')
+ ereport(FATAL,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("unexpected standby message type \"%c\", after receiving CopyDone",
+ firstchar)));
+
/* Handle the very limited subset of commands expected in this phase */
switch (firstchar)
{
@@ -1048,10 +1056,8 @@ WalSndLoop(void)
long sleeptime = 10000; /* 10 s */
int wakeEvents;
- wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT;
-
- if (!streamingDoneReceiving)
- wakeEvents |= WL_SOCKET_READABLE;
+ wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT |
+ WL_SOCKET_READABLE;
if (pq_is_send_pending())
wakeEvents |= WL_SOCKET_WRITEABLE;