diff options
Diffstat (limited to 'src/backend/postmaster/postmaster.c')
-rw-r--r-- | src/backend/postmaster/postmaster.c | 752 |
1 files changed, 10 insertions, 742 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index a373e82dd66..6610bd5f866 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -129,9 +129,7 @@ #include "utils/varlena.h" #ifdef EXEC_BACKEND -#include "nodes/queryjumble.h" #include "storage/pg_shmem.h" -#include "storage/spin.h" #endif @@ -186,7 +184,7 @@ typedef struct bkend static dlist_head BackendList = DLIST_STATIC_INIT(BackendList); #ifdef EXEC_BACKEND -static Backend *ShmemBackendArray; +Backend *ShmemBackendArray; #endif BackgroundWorker *MyBgworkerEntry = NULL; @@ -476,7 +474,6 @@ 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; @@ -489,85 +486,11 @@ typedef struct #endif /* WIN32 */ static pid_t backend_forkexec(ClientSocket *client_sock, CAC_state cac); -static pid_t internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker); -/* Type for a socket that can be inherited to a client process */ -#ifdef WIN32 -typedef struct -{ - SOCKET origsocket; /* Original socket value, or PGINVALID_SOCKET - * if not a socket */ - WSAPROTOCOL_INFO wsainfo; -} InheritableSocket; -#else -typedef int InheritableSocket; -#endif - -/* - * Structure contains all variables passed to exec:ed backends - */ -typedef struct -{ - bool has_client_sock; - ClientSocket client_sock; - InheritableSocket inh_sock; - - bool has_bgworker; - BackgroundWorker bgworker; - - char DataDir[MAXPGPATH]; - int32 MyCancelKey; - int MyPMChildSlot; -#ifndef WIN32 - unsigned long UsedShmemSegID; -#else - void *ShmemProtectiveRegion; - HANDLE UsedShmemSegID; -#endif - void *UsedShmemSegAddr; - slock_t *ShmemLock; - Backend *ShmemBackendArray; -#ifndef HAVE_SPINLOCKS - PGSemaphore *SpinlockSemaArray; -#endif - int NamedLWLockTrancheRequests; - NamedLWLockTranche *NamedLWLockTrancheArray; - LWLockPadded *MainLWLockArray; - slock_t *ProcStructLock; - PROC_HDR *ProcGlobal; - PGPROC *AuxiliaryProcs; - PGPROC *PreparedXactProcs; - PMSignalData *PMSignalState; - pid_t PostmasterPid; - TimestampTz PgStartTime; - TimestampTz PgReloadTime; - pg_time_t first_syslogger_file_time; - bool redirection_done; - bool IsBinaryUpgrade; - bool query_id_enabled; - int max_safe_fds; - int MaxBackends; -#ifdef WIN32 - HANDLE PostmasterHandle; - HANDLE initial_signal_pipe; - HANDLE syslogPipe[2]; -#else - int postmaster_alive_fds[2]; - int syslogPipe[2]; -#endif - char my_exec_path[MAXPGPATH]; - char pkglib_path[MAXPGPATH]; -} BackendParameters; -static void read_backend_variables(char *id, ClientSocket **client_sock, BackgroundWorker **worker); -static void restore_backend_variables(BackendParameters *param, ClientSocket **client_sock, BackgroundWorker **worker); - -#ifndef WIN32 -static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker); -#else -static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker, - HANDLE childProcess, pid_t childPid); -#endif +/* in launch_backend.c */ +extern pid_t internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker); +extern void read_backend_variables(char *id, ClientSocket **client_sock, BackgroundWorker **worker); static void ShmemBackendArrayAdd(Backend *bn); static void ShmemBackendArrayRemove(Backend *bn); @@ -1117,11 +1040,11 @@ PostmasterMain(int argc, char *argv[]) /* * Clean out the temp directory used to transmit parameters to child - * processes (see internal_forkexec, below). We must do this before - * launching any child processes, else we have a race condition: we could - * remove a parameter file before the child can read it. It should be - * safe to do so now, because we verified earlier that there are no - * conflicting Postgres processes in this data directory. + * processes (see internal_forkexec). We must do this before launching + * any child processes, else we have a race condition: we could remove a + * parameter file before the child can read it. It should be safe to do + * so now, because we verified earlier that there are no conflicting + * Postgres processes in this data directory. */ RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false); #endif @@ -4503,298 +4426,6 @@ backend_forkexec(ClientSocket *client_sock, CAC_state cac) return internal_forkexec(ac, av, client_sock, NULL); } -#ifndef WIN32 - -/* - * internal_forkexec non-win32 implementation - * - * - writes out backend variables to the parameter file - * - fork():s, and then exec():s the child process - */ -static pid_t -internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker) -{ - static unsigned long tmpBackendFileNum = 0; - pid_t pid; - char tmpfilename[MAXPGPATH]; - BackendParameters param; - FILE *fp; - - /* - * Make sure padding bytes are initialized, to prevent Valgrind from - * complaining about writing uninitialized bytes to the file. This isn't - * performance critical, and the win32 implementation initializes the - * padding bytes to zeros, so do it even when not using Valgrind. - */ - memset(¶m, 0, sizeof(BackendParameters)); - - if (!save_backend_variables(¶m, client_sock, worker)) - return -1; /* log made by save_backend_variables */ - - /* Calculate name for temp file */ - snprintf(tmpfilename, MAXPGPATH, "%s/%s.backend_var.%d.%lu", - PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX, - MyProcPid, ++tmpBackendFileNum); - - /* Open file */ - fp = AllocateFile(tmpfilename, PG_BINARY_W); - if (!fp) - { - /* - * As in OpenTemporaryFileInTablespace, try to make the temp-file - * directory, ignoring errors. - */ - (void) MakePGDirectory(PG_TEMP_FILES_DIR); - - fp = AllocateFile(tmpfilename, PG_BINARY_W); - if (!fp) - { - ereport(LOG, - (errcode_for_file_access(), - errmsg("could not create file \"%s\": %m", - tmpfilename))); - return -1; - } - } - - if (fwrite(¶m, sizeof(param), 1, fp) != 1) - { - ereport(LOG, - (errcode_for_file_access(), - errmsg("could not write to file \"%s\": %m", tmpfilename))); - FreeFile(fp); - return -1; - } - - /* Release file */ - if (FreeFile(fp)) - { - ereport(LOG, - (errcode_for_file_access(), - errmsg("could not write to file \"%s\": %m", tmpfilename))); - return -1; - } - - /* Make sure caller set up argv properly */ - Assert(argc >= 3); - Assert(argv[argc] == NULL); - Assert(strncmp(argv[1], "--fork", 6) == 0); - Assert(argv[2] == NULL); - - /* Insert temp file name after --fork argument */ - argv[2] = tmpfilename; - - /* Fire off execv in child */ - if ((pid = fork_process()) == 0) - { - if (execv(postgres_exec_path, argv) < 0) - { - ereport(LOG, - (errmsg("could not execute server process \"%s\": %m", - postgres_exec_path))); - /* We're already in the child process here, can't return */ - exit(1); - } - } - - return pid; /* Parent returns pid, or -1 on fork failure */ -} -#else /* WIN32 */ - -/* - * internal_forkexec win32 implementation - * - * - starts backend using CreateProcess(), in suspended state - * - writes out backend variables to the parameter file - * - during this, duplicates handles and sockets required for - * inheritance into the new process - * - resumes execution of the new process once the backend parameter - * file is complete. - */ -static pid_t -internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker) -{ - int retry_count = 0; - STARTUPINFO si; - PROCESS_INFORMATION pi; - int i; - int j; - char cmdLine[MAXPGPATH * 2]; - HANDLE paramHandle; - BackendParameters *param; - SECURITY_ATTRIBUTES sa; - char paramHandleStr[32]; - - /* Make sure caller set up argv properly */ - Assert(argc >= 3); - Assert(argv[argc] == NULL); - Assert(strncmp(argv[1], "--fork", 6) == 0); - Assert(argv[2] == NULL); - - /* Resume here if we need to retry */ -retry: - - /* Set up shared memory for parameter passing */ - ZeroMemory(&sa, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE, - &sa, - PAGE_READWRITE, - 0, - sizeof(BackendParameters), - NULL); - if (paramHandle == INVALID_HANDLE_VALUE) - { - ereport(LOG, - (errmsg("could not create backend parameter file mapping: error code %lu", - GetLastError()))); - return -1; - } - - param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, sizeof(BackendParameters)); - if (!param) - { - ereport(LOG, - (errmsg("could not map backend parameter memory: error code %lu", - GetLastError()))); - CloseHandle(paramHandle); - return -1; - } - - /* Insert temp file name after --fork argument */ -#ifdef _WIN64 - sprintf(paramHandleStr, "%llu", (LONG_PTR) paramHandle); -#else - sprintf(paramHandleStr, "%lu", (DWORD) paramHandle); -#endif - argv[2] = paramHandleStr; - - /* Format the cmd line */ - cmdLine[sizeof(cmdLine) - 1] = '\0'; - cmdLine[sizeof(cmdLine) - 2] = '\0'; - snprintf(cmdLine, sizeof(cmdLine) - 1, "\"%s\"", postgres_exec_path); - i = 0; - while (argv[++i] != NULL) - { - j = strlen(cmdLine); - snprintf(cmdLine + j, sizeof(cmdLine) - 1 - j, " \"%s\"", argv[i]); - } - if (cmdLine[sizeof(cmdLine) - 2] != '\0') - { - ereport(LOG, - (errmsg("subprocess command line too long"))); - UnmapViewOfFile(param); - CloseHandle(paramHandle); - return -1; - } - - memset(&pi, 0, sizeof(pi)); - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - - /* - * Create the subprocess in a suspended state. This will be resumed later, - * once we have written out the parameter file. - */ - if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED, - NULL, NULL, &si, &pi)) - { - ereport(LOG, - (errmsg("CreateProcess() call failed: %m (error code %lu)", - GetLastError()))); - UnmapViewOfFile(param); - CloseHandle(paramHandle); - return -1; - } - - if (!save_backend_variables(param, client_sock, worker, pi.hProcess, pi.dwProcessId)) - { - /* - * log made by save_backend_variables, but we have to clean up the - * mess with the half-started process - */ - if (!TerminateProcess(pi.hProcess, 255)) - ereport(LOG, - (errmsg_internal("could not terminate unstarted process: error code %lu", - GetLastError()))); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - UnmapViewOfFile(param); - CloseHandle(paramHandle); - return -1; /* log made by save_backend_variables */ - } - - /* Drop the parameter shared memory that is now inherited to the backend */ - if (!UnmapViewOfFile(param)) - ereport(LOG, - (errmsg("could not unmap view of backend parameter file: error code %lu", - GetLastError()))); - if (!CloseHandle(paramHandle)) - ereport(LOG, - (errmsg("could not close handle to backend parameter file: error code %lu", - GetLastError()))); - - /* - * Reserve the memory region used by our main shared memory segment before - * we resume the child process. Normally this should succeed, but if ASLR - * is active then it might sometimes fail due to the stack or heap having - * gotten mapped into that range. In that case, just terminate the - * process and retry. - */ - if (!pgwin32_ReserveSharedMemoryRegion(pi.hProcess)) - { - /* pgwin32_ReserveSharedMemoryRegion already made a log entry */ - if (!TerminateProcess(pi.hProcess, 255)) - ereport(LOG, - (errmsg_internal("could not terminate process that failed to reserve memory: error code %lu", - GetLastError()))); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - if (++retry_count < 100) - goto retry; - ereport(LOG, - (errmsg("giving up after too many tries to reserve shared memory"), - errhint("This might be caused by ASLR or antivirus software."))); - return -1; - } - - /* - * Now that the backend variables are written out, we start the child - * thread so it can start initializing while we set up the rest of the - * parent state. - */ - if (ResumeThread(pi.hThread) == -1) - { - if (!TerminateProcess(pi.hProcess, 255)) - { - ereport(LOG, - (errmsg_internal("could not terminate unstartable process: error code %lu", - GetLastError()))); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return -1; - } - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - ereport(LOG, - (errmsg_internal("could not resume thread of unstarted process: error code %lu", - GetLastError()))); - return -1; - } - - /* Set up notification when the child process dies */ - pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId); - - /* Don't close pi.hProcess, it's owned by the deadchild callback now */ - - CloseHandle(pi.hThread); - - return pi.dwProcessId; -} -#endif /* WIN32 */ - - /* * SubPostmasterMain -- Get the fork/exec'd process into a state equivalent * to what it would be if we'd simply forked on Unix, and then @@ -6026,369 +5657,6 @@ PostmasterMarkPIDForWorkerNotify(int pid) #ifdef EXEC_BACKEND -/* - * The following need to be available to the save/restore_backend_variables - * functions. They are marked NON_EXEC_STATIC in their home modules. - */ -extern slock_t *ShmemLock; -extern slock_t *ProcStructLock; -extern PGPROC *AuxiliaryProcs; -extern PMSignalData *PMSignalState; -extern pg_time_t first_syslogger_file_time; - -#ifndef WIN32 -#define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true) -#define read_inheritable_socket(dest, src) (*(dest) = *(src)) -#else -static bool write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE child); -static bool write_inheritable_socket(InheritableSocket *dest, SOCKET src, - pid_t childPid); -static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src); -#endif - - -/* Save critical backend variables into the BackendParameters struct */ -#ifndef WIN32 -static bool -save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker) -#else -static bool -save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker, - HANDLE childProcess, pid_t childPid) -#endif -{ - if (client_sock) - { - memcpy(¶m->client_sock, client_sock, sizeof(ClientSocket)); - if (!write_inheritable_socket(¶m->inh_sock, client_sock->sock, childPid)) - return false; - param->has_client_sock = true; - } - else - { - memset(¶m->client_sock, 0, sizeof(ClientSocket)); - param->has_client_sock = false; - } - - if (worker) - { - memcpy(¶m->bgworker, worker, sizeof(BackgroundWorker)); - param->has_bgworker = true; - } - else - { - memset(¶m->bgworker, 0, sizeof(BackgroundWorker)); - param->has_bgworker = false; - } - - strlcpy(param->DataDir, DataDir, MAXPGPATH); - - param->MyCancelKey = MyCancelKey; - param->MyPMChildSlot = MyPMChildSlot; - -#ifdef WIN32 - param->ShmemProtectiveRegion = ShmemProtectiveRegion; -#endif - param->UsedShmemSegID = UsedShmemSegID; - param->UsedShmemSegAddr = UsedShmemSegAddr; - - param->ShmemLock = ShmemLock; - param->ShmemBackendArray = ShmemBackendArray; - -#ifndef HAVE_SPINLOCKS - param->SpinlockSemaArray = SpinlockSemaArray; -#endif - param->NamedLWLockTrancheRequests = NamedLWLockTrancheRequests; - param->NamedLWLockTrancheArray = NamedLWLockTrancheArray; - param->MainLWLockArray = MainLWLockArray; - param->ProcStructLock = ProcStructLock; - param->ProcGlobal = ProcGlobal; - param->AuxiliaryProcs = AuxiliaryProcs; - param->PreparedXactProcs = PreparedXactProcs; - param->PMSignalState = PMSignalState; - - param->PostmasterPid = PostmasterPid; - param->PgStartTime = PgStartTime; - param->PgReloadTime = PgReloadTime; - param->first_syslogger_file_time = first_syslogger_file_time; - - param->redirection_done = redirection_done; - param->IsBinaryUpgrade = IsBinaryUpgrade; - param->query_id_enabled = query_id_enabled; - param->max_safe_fds = max_safe_fds; - - param->MaxBackends = MaxBackends; - -#ifdef WIN32 - param->PostmasterHandle = PostmasterHandle; - if (!write_duplicated_handle(¶m->initial_signal_pipe, - pgwin32_create_signal_listener(childPid), - childProcess)) - return false; -#else - memcpy(¶m->postmaster_alive_fds, &postmaster_alive_fds, - sizeof(postmaster_alive_fds)); -#endif - - memcpy(¶m->syslogPipe, &syslogPipe, sizeof(syslogPipe)); - - strlcpy(param->my_exec_path, my_exec_path, MAXPGPATH); - - strlcpy(param->pkglib_path, pkglib_path, MAXPGPATH); - - return true; -} - - -#ifdef WIN32 -/* - * Duplicate a handle for usage in a child process, and write the child - * process instance of the handle to the parameter file. - */ -static bool -write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE childProcess) -{ - HANDLE hChild = INVALID_HANDLE_VALUE; - - if (!DuplicateHandle(GetCurrentProcess(), - src, - childProcess, - &hChild, - 0, - TRUE, - DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) - { - ereport(LOG, - (errmsg_internal("could not duplicate handle to be written to backend parameter file: error code %lu", - GetLastError()))); - return false; - } - - *dest = hChild; - return true; -} - -/* - * Duplicate a socket for usage in a child process, and write the resulting - * structure to the parameter file. - * This is required because a number of LSPs (Layered Service Providers) very - * common on Windows (antivirus, firewalls, download managers etc) break - * straight socket inheritance. - */ -static bool -write_inheritable_socket(InheritableSocket *dest, SOCKET src, pid_t childpid) -{ - dest->origsocket = src; - if (src != 0 && src != PGINVALID_SOCKET) - { - /* Actual socket */ - if (WSADuplicateSocket(src, childpid, &dest->wsainfo) != 0) - { - ereport(LOG, - (errmsg("could not duplicate socket %d for use in backend: error code %d", - (int) src, WSAGetLastError()))); - return false; - } - } - return true; -} - -/* - * Read a duplicate socket structure back, and get the socket descriptor. - */ -static void -read_inheritable_socket(SOCKET *dest, InheritableSocket *src) -{ - SOCKET s; - - if (src->origsocket == PGINVALID_SOCKET || src->origsocket == 0) - { - /* Not a real socket! */ - *dest = src->origsocket; - } - else - { - /* Actual socket, so create from structure */ - s = WSASocket(FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &src->wsainfo, - 0, - 0); - if (s == INVALID_SOCKET) - { - write_stderr("could not create inherited socket: error code %d\n", - WSAGetLastError()); - exit(1); - } - *dest = s; - - /* - * To make sure we don't get two references to the same socket, close - * the original one. (This would happen when inheritance actually - * works.. - */ - closesocket(src->origsocket); - } -} -#endif - -static void -read_backend_variables(char *id, ClientSocket **client_sock, BackgroundWorker **worker) -{ - BackendParameters param; - -#ifndef WIN32 - /* Non-win32 implementation reads from file */ - FILE *fp; - - /* Open file */ - fp = AllocateFile(id, PG_BINARY_R); - if (!fp) - { - write_stderr("could not open backend variables file \"%s\": %m\n", id); - exit(1); - } - - if (fread(¶m, sizeof(param), 1, fp) != 1) - { - write_stderr("could not read from backend variables file \"%s\": %m\n", id); - exit(1); - } - - /* Release file */ - FreeFile(fp); - if (unlink(id) != 0) - { - write_stderr("could not remove file \"%s\": %m\n", id); - exit(1); - } -#else - /* Win32 version uses mapped file */ - HANDLE paramHandle; - BackendParameters *paramp; - -#ifdef _WIN64 - paramHandle = (HANDLE) _atoi64(id); -#else - paramHandle = (HANDLE) atol(id); -#endif - paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0); - if (!paramp) - { - write_stderr("could not map view of backend variables: error code %lu\n", - GetLastError()); - exit(1); - } - - memcpy(¶m, paramp, sizeof(BackendParameters)); - - if (!UnmapViewOfFile(paramp)) - { - write_stderr("could not unmap view of backend variables: error code %lu\n", - GetLastError()); - exit(1); - } - - if (!CloseHandle(paramHandle)) - { - write_stderr("could not close handle to backend parameter variables: error code %lu\n", - GetLastError()); - exit(1); - } -#endif - - restore_backend_variables(¶m, client_sock, worker); -} - -/* Restore critical backend variables from the BackendParameters struct */ -static void -restore_backend_variables(BackendParameters *param, ClientSocket **client_sock, BackgroundWorker **worker) -{ - if (param->has_client_sock) - { - *client_sock = (ClientSocket *) MemoryContextAlloc(TopMemoryContext, sizeof(ClientSocket)); - memcpy(*client_sock, ¶m->client_sock, sizeof(ClientSocket)); - read_inheritable_socket(&(*client_sock)->sock, ¶m->inh_sock); - } - else - *client_sock = NULL; - - if (param->has_bgworker) - { - *worker = (BackgroundWorker *) - MemoryContextAlloc(TopMemoryContext, sizeof(BackgroundWorker)); - memcpy(*worker, ¶m->bgworker, sizeof(BackgroundWorker)); - } - else - *worker = NULL; - - SetDataDir(param->DataDir); - - MyCancelKey = param->MyCancelKey; - MyPMChildSlot = param->MyPMChildSlot; - -#ifdef WIN32 - ShmemProtectiveRegion = param->ShmemProtectiveRegion; -#endif - UsedShmemSegID = param->UsedShmemSegID; - UsedShmemSegAddr = param->UsedShmemSegAddr; - - ShmemLock = param->ShmemLock; - ShmemBackendArray = param->ShmemBackendArray; - -#ifndef HAVE_SPINLOCKS - SpinlockSemaArray = param->SpinlockSemaArray; -#endif - NamedLWLockTrancheRequests = param->NamedLWLockTrancheRequests; - NamedLWLockTrancheArray = param->NamedLWLockTrancheArray; - MainLWLockArray = param->MainLWLockArray; - ProcStructLock = param->ProcStructLock; - ProcGlobal = param->ProcGlobal; - AuxiliaryProcs = param->AuxiliaryProcs; - PreparedXactProcs = param->PreparedXactProcs; - PMSignalState = param->PMSignalState; - - PostmasterPid = param->PostmasterPid; - PgStartTime = param->PgStartTime; - PgReloadTime = param->PgReloadTime; - first_syslogger_file_time = param->first_syslogger_file_time; - - redirection_done = param->redirection_done; - IsBinaryUpgrade = param->IsBinaryUpgrade; - query_id_enabled = param->query_id_enabled; - max_safe_fds = param->max_safe_fds; - - MaxBackends = param->MaxBackends; - -#ifdef WIN32 - PostmasterHandle = param->PostmasterHandle; - pgwin32_initial_signal_pipe = param->initial_signal_pipe; -#else - memcpy(&postmaster_alive_fds, ¶m->postmaster_alive_fds, - sizeof(postmaster_alive_fds)); -#endif - - memcpy(&syslogPipe, ¶m->syslogPipe, sizeof(syslogPipe)); - - strlcpy(my_exec_path, param->my_exec_path, MAXPGPATH); - - strlcpy(pkglib_path, param->pkglib_path, MAXPGPATH); - - /* - * We need to restore fd.c's counts of externally-opened FDs; to avoid - * confusion, be sure to do this after restoring max_safe_fds. (Note: - * BackendInitialize will handle this for (*client_sock)->sock.) - */ -#ifndef WIN32 - if (postmaster_alive_fds[0] >= 0) - ReserveExternalFD(); - if (postmaster_alive_fds[1] >= 0) - ReserveExternalFD(); -#endif -} - - Size ShmemBackendArraySize(void) { @@ -6516,7 +5784,7 @@ pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) * automatically by an operating system thread pool. The memory and the * process handle will be freed by a later call to waitpid(). */ -static void +void pgwin32_register_deadchild_callback(HANDLE procHandle, DWORD procId) { win32_deadchild_waitinfo *childinfo; |