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)
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)
{
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;