From 5eb58dda79879dc66f31e808d5cebdafae6f4e43 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 8 Dec 2023 10:31:49 +0200 Subject: [PATCH v12 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 446dc738d97..f79bb3a526b 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -478,6 +478,7 @@ static void MaybeStartSlotSyncWorker(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; @@ -4793,26 +4794,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); @@ -6539,6 +6524,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