Skip to content

Commit 14cddee

Browse files
committed
Split registration of Win32 deadchild callback to separate function
The next commit will move the internal_forkexec() function to a 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 next commit more mechanical. Reviewed-by: Tristan Partin, Andres Freund Discussion: https://www.postgresql.org/message-id/7a59b073-5b5b-151e-7ed3-8b01ff7ce9ef@iki.fi
1 parent ca108be commit 14cddee

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

src/backend/postmaster/postmaster.c

+30-20
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ static void MaybeStartSlotSyncWorker(void);
476476

477477
static pid_t waitpid(pid_t pid, int *exitstatus, int options);
478478
static void WINAPI pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
479+
static void pgwin32_register_deadchild_callback(HANDLE procHandle, DWORD procId);
479480

480481
static HANDLE win32ChildQueue;
481482

@@ -4623,7 +4624,6 @@ internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundW
46234624
BackendParameters *param;
46244625
SECURITY_ATTRIBUTES sa;
46254626
char paramHandleStr[32];
4626-
win32_deadchild_waitinfo *childinfo;
46274627

46284628
/* Make sure caller set up argv properly */
46294629
Assert(argc >= 3);
@@ -4783,26 +4783,10 @@ internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundW
47834783
return -1;
47844784
}
47854785

4786-
/*
4787-
* Queue a waiter to signal when this child dies. The wait will be handled
4788-
* automatically by an operating system thread pool. The memory will be
4789-
* freed by a later call to waitpid().
4790-
*/
4791-
childinfo = palloc(sizeof(win32_deadchild_waitinfo));
4792-
childinfo->procHandle = pi.hProcess;
4793-
childinfo->procId = pi.dwProcessId;
4794-
4795-
if (!RegisterWaitForSingleObject(&childinfo->waitHandle,
4796-
pi.hProcess,
4797-
pgwin32_deadchild_callback,
4798-
childinfo,
4799-
INFINITE,
4800-
WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD))
4801-
ereport(FATAL,
4802-
(errmsg_internal("could not register process for wait: error code %lu",
4803-
GetLastError())));
4786+
/* Set up notification when the child process dies */
4787+
pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
48044788

4805-
/* Don't close pi.hProcess here - waitpid() needs access to it */
4789+
/* Don't close pi.hProcess, it's owned by the deadchild callback now */
48064790

48074791
CloseHandle(pi.hThread);
48084792

@@ -6526,6 +6510,32 @@ pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
65266510
/* Queue SIGCHLD signal. */
65276511
pg_queue_signal(SIGCHLD);
65286512
}
6513+
6514+
/*
6515+
* Queue a waiter to signal when this child dies. The wait will be handled
6516+
* automatically by an operating system thread pool. The memory and the
6517+
* process handle will be freed by a later call to waitpid().
6518+
*/
6519+
static void
6520+
pgwin32_register_deadchild_callback(HANDLE procHandle, DWORD procId)
6521+
{
6522+
win32_deadchild_waitinfo *childinfo;
6523+
6524+
childinfo = palloc(sizeof(win32_deadchild_waitinfo));
6525+
childinfo->procHandle = procHandle;
6526+
childinfo->procId = procId;
6527+
6528+
if (!RegisterWaitForSingleObject(&childinfo->waitHandle,
6529+
procHandle,
6530+
pgwin32_deadchild_callback,
6531+
childinfo,
6532+
INFINITE,
6533+
WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD))
6534+
ereport(FATAL,
6535+
(errmsg_internal("could not register process for wait: error code %lu",
6536+
GetLastError())));
6537+
}
6538+
65296539
#endif /* WIN32 */
65306540

65316541
/*

0 commit comments

Comments
 (0)