@@ -1609,7 +1609,12 @@ ProcessRepliesIfAny(void)
1609
1609
1610
1610
last_processing = GetCurrentTimestamp ();
1611
1611
1612
- for (;;)
1612
+ /*
1613
+ * If we already received a CopyDone from the frontend, any subsequent
1614
+ * message is the beginning of a new command, and should be processed in
1615
+ * the main processing loop.
1616
+ */
1617
+ while (!streamingDoneReceiving )
1613
1618
{
1614
1619
pq_startmsgread ();
1615
1620
r = pq_getbyte_if_available (& firstchar );
@@ -1638,19 +1643,6 @@ ProcessRepliesIfAny(void)
1638
1643
proc_exit (0 );
1639
1644
}
1640
1645
1641
- /*
1642
- * If we already received a CopyDone from the frontend, the frontend
1643
- * should not send us anything until we've closed our end of the COPY.
1644
- * XXX: In theory, the frontend could already send the next command
1645
- * before receiving the CopyDone, but libpq doesn't currently allow
1646
- * that.
1647
- */
1648
- if (streamingDoneReceiving && firstchar != 'X' )
1649
- ereport (FATAL ,
1650
- (errcode (ERRCODE_PROTOCOL_VIOLATION ),
1651
- errmsg ("unexpected standby message type \"%c\", after receiving CopyDone" ,
1652
- firstchar )));
1653
-
1654
1646
/* Handle the very limited subset of commands expected in this phase */
1655
1647
switch (firstchar )
1656
1648
{
@@ -2251,8 +2243,10 @@ WalSndLoop(WalSndSendDataCallback send_data)
2251
2243
long sleeptime ;
2252
2244
int wakeEvents ;
2253
2245
2254
- wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_TIMEOUT |
2255
- WL_SOCKET_READABLE ;
2246
+ wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_TIMEOUT ;
2247
+
2248
+ if (!streamingDoneReceiving )
2249
+ wakeEvents |= WL_SOCKET_READABLE ;
2256
2250
2257
2251
/*
2258
2252
* Use fresh timestamp, not last_processed, to reduce the chance
0 commit comments