/* $Id: winchildren.h 3313 2020-03-16 02:31:38Z bird $ */ /** @file * Child process creation and management for kmk. */ /* * Copyright (c) 2018 knut st. osmundsen * * This file is part of kBuild. * * kBuild is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * kBuild is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with kBuild. If not, see * */ #ifndef INCLUDED_WINCHILDREN_H #define INCLUDED_WINCHILDREN_H /** Child processor group allocator state. */ typedef struct MKWINCHILDCPUGROUPALLOCSTATE { /** The group index for the worker allocator. * This is ever increasing and must be modded by g_cProcessorGroups. */ unsigned int idxGroup; /** The processor in group index for the worker allocator. */ unsigned int idxProcessorInGroup; } MKWINCHILDCPUGROUPALLOCSTATE; /** Pointer to a CPU group allocator state. */ typedef MKWINCHILDCPUGROUPALLOCSTATE *PMKWINCHILDCPUGROUPALLOCSTATE; #ifdef DECLARE_HANDLE /** * A childcare worker pipe. */ typedef struct WINCCWPIPE { /** My end of the pipe. */ HANDLE hPipeMine; /** The child end of the pipe. */ HANDLE hPipeChild; /** The event for asynchronous reading. */ HANDLE hEvent; /** Which pipe this is (1 == stdout, 2 == stderr). */ unsigned char iWhich; /** Set if we've got a read pending already. */ BOOL fReadPending; /** Indicator that we've written out something. This is cleared before * we start catching output from a new child and use in the CL.exe * supression heuristics. */ BOOL fHaveWrittenOut; /** Number of bytes at the start of the buffer that we've already * written out. We try write out whole lines. */ DWORD cbWritten; /** The buffer offset of the read currently pending. */ DWORD offPendingRead; /** Read buffer size. */ DWORD cbBuffer; /** The read buffer allocation. */ unsigned char *pbBuffer; /** Overlapped I/O structure. */ OVERLAPPED Overlapped; } WINCCWPIPE; #endif typedef struct WINCCWPIPE *PWINCCWPIPE; void MkWinChildInit(unsigned int cJobSlot); void MkWinChildReExecMake(char **papszArgs, char **papszEnv); intptr_t MkWinChildGetCompleteEventHandle(void); int MkWinChildCreate(char **papszArgs, char **papszEnv, const char *pszShell, struct child *pMkChild, pid_t *pPid); int MkWinChildCreateWithStdOutPipe(char **papszArgs, char **papszEnv, int fdErr, pid_t *pPid, int *pfdReadPipe); void MkWinChildInitCpuGroupAllocator(PMKWINCHILDCPUGROUPALLOCSTATE pState); unsigned int MkWinChildAllocateCpuGroup(PMKWINCHILDCPUGROUPALLOCSTATE pState); #ifdef KMK struct KMKBUILTINENTRY; int MkWinChildCreateBuiltIn(struct KMKBUILTINENTRY const *pBuiltIn, int cArgs, char **papszArgs, char **papszEnv, struct child *pMkChild, pid_t *pPid); int MkWinChildCreateAppend(const char *pszFilename, char **ppszAppend, size_t cbAppend, int fTruncate, struct child *pMkChild, pid_t *pPid); int MkWinChildCreateSubmit(intptr_t hEvent, void *pvSubmitWorker, PWINCCWPIPE pStdOut, PWINCCWPIPE pStdErr, struct child *pMkChild, pid_t *pPid); PWINCCWPIPE MkWinChildcareCreateWorkerPipe(unsigned iWhich, unsigned int idxWorker); void MkWinChildcareWorkerDrainPipes(struct WINCHILD *pChild, PWINCCWPIPE pStdOut, PWINCCWPIPE pStdErr); void MkWinChildcareDeleteWorkerPipe(PWINCCWPIPE pPipe); int MkWinChildCreateRedirect(intptr_t hProcess, pid_t *pPid); # ifdef DECLARE_HANDLE int MkWinChildBuiltInExecChild(void *pvWorker, const char *pszExecutable, char **papszArgs, BOOL fQuotedArgv, char **papszEnvVars, const char *pszCwd, BOOL pafReplace[3], HANDLE pahReplace[3]); # endif #endif /* KMK */ int MkWinChildKill(pid_t pid, int iSignal, struct child *pMkChild); int MkWinChildWait(int fBlock, pid_t *pPid, int *piExitCode, int *piSignal, int *pfCoreDumped, struct child **ppMkChild); void MkWinChildExclusiveAcquire(void); void MkWinChildExclusiveRelease(void); #undef CLOSE_ON_EXEC #define CLOSE_ON_EXEC(a_fd) MkWinChildUnrelatedCloseOnExec(a_fd) int MkWinChildUnrelatedCloseOnExec(int fd); #endif