aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2024-03-18 11:35:01 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2024-03-18 11:35:01 +0200
commit14cddee9cce349d4bf024316e014ccf891c39cef (patch)
tree9dded59d877e5134f5f58281c7f67736cfd23371 /src
parentca108be72e7abf1f801c8e49dcffbbbbf412c0d9 (diff)
downloadpostgresql-14cddee9cce349d4bf024316e014ccf891c39cef.tar.gz
postgresql-14cddee9cce349d4bf024316e014ccf891c39cef.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/postmaster.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index a8793fcb0bc..a373e82dd66 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -476,6 +476,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;
@@ -4623,7 +4624,6 @@ internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundW
BackendParameters *param;
SECURITY_ATTRIBUTES sa;
char paramHandleStr[32];
- win32_deadchild_waitinfo *childinfo;
/* Make sure caller set up argv properly */
Assert(argc >= 3);
@@ -4783,26 +4783,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);
@@ -6526,6 +6510,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 */
/*