In Windows pg_dump, ensure idle workers will shut down during error exit.
authorTom Lane <[email protected]>
Thu, 26 May 2016 14:50:30 +0000 (10:50 -0400)
committerTom Lane <[email protected]>
Thu, 26 May 2016 14:50:46 +0000 (10:50 -0400)
The Windows coding of ShutdownWorkersHard() thought that setting termEvent
was sufficient to make workers exit after an error.  But that only helps
if a worker is busy and passes through checkAborting().  An idle worker
will just sit, resulting in pg_dump failing to exit until the user gives up
and hits control-C.  We should close the write end of the command pipe
so that idle workers will see socket EOF and exit, as the Unix coding was
already doing.

Back-patch to 9.3 where parallel pg_dump was introduced.

Kyotaro Horiguchi

src/bin/pg_dump/parallel.c

index 8184ffdf8d09b8698235f9b480240d6f01af5646..6debe9d4e5bc0f0f32ba318ed3b6b9ceb7f8d2ee 100644 (file)
@@ -301,28 +301,26 @@ checkAborting(ArchiveHandle *AH)
 }
 
 /*
- * Shut down any remaining workers, this has an implicit do_wait == true.
- *
- * The fastest way we can make the workers terminate gracefully is when
- * they are listening for new commands and we just tell them to terminate.
+ * Shut down any remaining workers, waiting for them to finish.
  */
 static void
 ShutdownWorkersHard(ParallelState *pstate)
 {
-#ifndef WIN32
        int                     i;
 
        /*
-        * Close our write end of the sockets so that the workers know they can
-        * exit.
+        * Close our write end of the sockets so that any workers waiting for
+        * commands know they can exit.
         */
        for (i = 0; i < pstate->numWorkers; i++)
                closesocket(pstate->parallelSlot[i].pipeWrite);
 
+#ifndef WIN32
+       /* On non-Windows, send SIGTERM to abort commands-in-progress. */
        for (i = 0; i < pstate->numWorkers; i++)
                kill(pstate->parallelSlot[i].pid, SIGTERM);
 #else
-       /* The workers monitor this event via checkAborting(). */
+       /* Non-idle workers monitor this event via checkAborting(). */
        SetEvent(termEvent);
 #endif