v5-0004-Extract-registration-of-Win32-deadchild-callback-.patch

text/x-patch

Filename: v5-0004-Extract-registration-of-Win32-deadchild-callback-.patch
Type: text/x-patch
Part: 3
Message: Re: Refactoring backend fork+exec code

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v5-0004
Subject: Extract registration of Win32 deadchild callback to separate function
File+
src/backend/postmaster/postmaster.c 30 19
From e67d56ca87f300d24cb1b56cf67a9063a496b70e Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Fri, 8 Dec 2023 10:31:49 +0200
Subject: [PATCH v5 4/8] Extract registration of Win32 deadchild callback to
 separate function

The next commits will move the internal_forkexec() function to
different source file, but it makes sense to keep all the code related
to the win32 waitpid() emulation in postmaster.c. Split it off to a
separate function now, to make the commit that moves
internal_forkexec() more mechanical.
---
 src/backend/postmaster/postmaster.c | 49 ++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 257a1bee331..4022c3c750a 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -471,6 +471,7 @@ static void InitPostmasterDeathWatchHandle(void);
 
 static pid_t waitpid(pid_t pid, int *exitstatus, int options);
 static void WINAPI pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
+static void pgwin32_register_deadchild_callback(HANDLE procHandle, DWORD procId);
 
 static HANDLE win32ChildQueue;
 
@@ -4735,26 +4736,10 @@ retry:
 		return -1;
 	}
 
-	/*
-	 * Queue a waiter to signal when this child dies. The wait will be handled
-	 * automatically by an operating system thread pool.  The memory will be
-	 * freed by a later call to waitpid().
-	 */
-	childinfo = palloc(sizeof(win32_deadchild_waitinfo));
-	childinfo->procHandle = pi.hProcess;
-	childinfo->procId = pi.dwProcessId;
-
-	if (!RegisterWaitForSingleObject(&childinfo->waitHandle,
-									 pi.hProcess,
-									 pgwin32_deadchild_callback,
-									 childinfo,
-									 INFINITE,
-									 WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD))
-		ereport(FATAL,
-				(errmsg_internal("could not register process for wait: error code %lu",
-								 GetLastError())));
+	/* Set up notification when the child process dies */
+	pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
 
-	/* Don't close pi.hProcess here - waitpid() needs access to it */
+	/* Don't close pi.hProcess, it's owned by the deadchild callback now */
 
 	CloseHandle(pi.hThread);
 
@@ -6441,6 +6426,32 @@ pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
 	/* Queue SIGCHLD signal. */
 	pg_queue_signal(SIGCHLD);
 }
+
+/*
+ * Queue a waiter to signal when this child dies.  The wait will be handled
+ * automatically by an operating system thread pool.  The memory and the
+ * process handle will be freed by a later call to waitpid().
+ */
+static void
+pgwin32_register_deadchild_callback(HANDLE procHandle, DWORD procId)
+{
+	win32_deadchild_waitinfo *childinfo;
+
+	childinfo = palloc(sizeof(win32_deadchild_waitinfo));
+	childinfo->procHandle = procHandle;
+	childinfo->procId = procId;
+
+	if (!RegisterWaitForSingleObject(&childinfo->waitHandle,
+									 procHandle,
+									 pgwin32_deadchild_callback,
+									 childinfo,
+									 INFINITE,
+									 WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD))
+		ereport(FATAL,
+				(errmsg_internal("could not register process for wait: error code %lu",
+								 GetLastError())));
+}
+
 #endif							/* WIN32 */
 
 /*
-- 
2.39.2