@@ -1603,7 +1603,12 @@ ProcessRepliesIfAny(void)
1603
1603
1604
1604
last_processing = GetCurrentTimestamp ();
1605
1605
1606
- for (;;)
1606
+ /*
1607
+ * If we already received a CopyDone from the frontend, any subsequent
1608
+ * message is the beginning of a new command, and should be processed in
1609
+ * the main processing loop.
1610
+ */
1611
+ while (!streamingDoneReceiving )
1607
1612
{
1608
1613
pq_startmsgread ();
1609
1614
r = pq_getbyte_if_available (& firstchar );
@@ -1632,19 +1637,6 @@ ProcessRepliesIfAny(void)
1632
1637
proc_exit (0 );
1633
1638
}
1634
1639
1635
- /*
1636
- * If we already received a CopyDone from the frontend, the frontend
1637
- * should not send us anything until we've closed our end of the COPY.
1638
- * XXX: In theory, the frontend could already send the next command
1639
- * before receiving the CopyDone, but libpq doesn't currently allow
1640
- * that.
1641
- */
1642
- if (streamingDoneReceiving && firstchar != 'X' )
1643
- ereport (FATAL ,
1644
- (errcode (ERRCODE_PROTOCOL_VIOLATION ),
1645
- errmsg ("unexpected standby message type \"%c\", after receiving CopyDone" ,
1646
- firstchar )));
1647
-
1648
1640
/* Handle the very limited subset of commands expected in this phase */
1649
1641
switch (firstchar )
1650
1642
{
@@ -2212,8 +2204,10 @@ WalSndLoop(WalSndSendDataCallback send_data)
2212
2204
long sleeptime ;
2213
2205
int wakeEvents ;
2214
2206
2215
- wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT |
2216
- WL_SOCKET_READABLE ;
2207
+ wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT ;
2208
+
2209
+ if (!streamingDoneReceiving )
2210
+ wakeEvents |= WL_SOCKET_READABLE ;
2217
2211
2218
2212
/*
2219
2213
* Use fresh timestamp, not last_processed, to reduce the chance
0 commit comments