Do not return from PQrequestCancel until postmaster has finished
authorTom Lane
Thu, 2 Oct 2003 19:52:44 +0000 (19:52 +0000)
committerTom Lane
Thu, 2 Oct 2003 19:52:44 +0000 (19:52 +0000)
processing the request; this ensures that the request won't be taken
to cancel a subsequently-issued query.  Race condition originally
noted by Oliver Jowett in the context of JDBC, but libpq has it too.

src/interfaces/libpq/fe-connect.c

index c0526b75bf3990070cd586e20c4b75481d3f22e7..cd235a1276839b97e358d9e343b6d516bf24055a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.261 2003/09/22 00:23:35 petere Exp $
+ *   $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.262 2003/10/02 19:52:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2262,7 +2262,23 @@ retry4:
        goto cancel_errReturn;
    }
 
-   /* Sent it, done */
+   /*
+    * Wait for the postmaster to close the connection, which indicates that
+    * it's processed the request.  Without this delay, we might issue another
+    * command only to find that our cancel zaps that command instead of the
+    * one we thought we were canceling.  Note we don't actually expect this
+    * read to obtain any data, we are just waiting for EOF to be signaled.
+    */
+retry5:
+   if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
+   {
+       if (SOCK_ERRNO == EINTR)
+           /* Interrupted system call - we'll just try again */
+           goto retry5;
+       /* we ignore other error conditions */
+   }
+
+   /* All done */
    closesocket(tmpsock);
 #ifdef WIN32
    WSASetLastError(save_errno);