From c0a1d9cc1fe73c4217c19432a8691bd15e6108fe Mon Sep 17 00:00:00 2001
From: Greg Burd <greg@burd.me>
Date: Thu, 12 Nov 2026 12:49:32 -0500
Subject: [PATCH v4 21/21] pg_dump: Don't close the shared archive file in
 _ReopenArchive().

_ReopenArchive() closed the original FILE before opening a private
one, except on Windows, where parallel workers were already threads
sharing the leader's FILE through their cloned ArchiveHandle.  Now
that workers are threads everywhere, the first worker to reopen
closed the file under the others, and parallel restore of a
custom-format archive failed or hung.  pg_dump/t/011_restore.pl's
"restore -j2" tests show it.  Use the Windows behavior everywhere.
---
 src/bin/pg_dump/pg_backup_custom.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index ab1954c3312..895dea5592b 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -784,9 +784,8 @@ _CloseArchive(ArchiveHandle *AH)
 /*
  * Reopen the archive's file handle.
  *
- * We close the original file handle, except on Windows.  (The difference
- * is because on Windows, this is used within a multithreading context,
- * and we don't want a thread closing the parent file handle.)
+ * We don't close the original file handle, because parallel workers are
+ * threads whose cloned ArchiveHandles share it with the leader.
  */
 static void
 _ReopenArchive(ArchiveHandle *AH)
@@ -810,11 +809,6 @@ _ReopenArchive(ArchiveHandle *AH)
 	if (tpos < 0)
 		pg_fatal("could not determine seek position in archive file: %m");
 
-#ifndef WIN32
-	if (fclose(AH->FH) != 0)
-		pg_fatal("could not close archive file: %m");
-#endif
-
 	AH->FH = fopen(AH->fSpec, PG_BINARY_R);
 	if (!AH->FH)
 		pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
-- 
2.54.0

