Add support for spawning processes using posix_spawn() - #56
Open
guillerodriguez wants to merge 4 commits into
Open
Add support for spawning processes using posix_spawn()#56guillerodriguez wants to merge 4 commits into
guillerodriguez wants to merge 4 commits into
Conversation
Move the child-side process spawning implementation to a separate source file, so that it can later be reused by the spawn helper in the forthcoming posix_spawn implementation. Make sure all child-side functions called after fork() are static and live in the same translation unit, so that calls between them cannot be lazily bound (resolving a lazy binding runs the dynamic linker, which can deadlock the child). The entry point itself (cpproc_child_fork_exec) is called before fork(), so its binding is resolved safely in the parent. This commit introduces no functional changes. Signed-off-by: Guillermo Rodríguez <grodriguez@ingelabs.com>
Spawning through fork() can be expensive when the parent process is large. Add support for spawning using posix_spawn(), if available. The portable posix_spawn() interface cannot perform the whole child setup, though: there is no way to ask it to mark every remaining descriptor close-on-exec or to run our existing PATH search. Execute the target through a small helper program, cpspawnhelper, which reuses the same child-side code as the fork path. Invoke posix_spawn() without file actions or attributes, so that older versions of glibc use vfork() instead of fork() internally. Pass the descriptor numbers, the working directory, the parent's PATH and the target arguments in the helper's argv. Launch the helper with an empty environment to prevent the dynamic linker from acting on the target's loader settings before main(). The target environment is sent through a dedicated pipe to keep it out of the helper's command line. The new posix_spawn-based mechanism is selected in VMProcess, but it is disabled for now. Signed-off-by: Guillermo Rodríguez <grodriguez@ingelabs.com>
POSIX allows posix_spawn() to report an exec failure in the child only through an exit status of 127, with the call itself returning success (glibc did this before 2.24; see glibc #18433). That status cannot be distinguished from a successfully executed target that later exits with 127. The helper can also die after its own exec succeeds but before main() runs, for example if its dynamic loader fails. In either failure case, the parent would read EOF from the fail pipe and report a successful spawn even though the target never ran. Make the helper write a readiness marker to the fail pipe after parsing its arguments, and require the parent to receive it before treating a subsequent EOF as success. EOF without the marker now reports an error instead of a successful spawn. Signed-off-by: Guillermo Rodríguez <grodriguez@ingelabs.com>
Allow selecting the process spawning mechanism through the gnu.lang.process.posixSpawn system property: "false" forces fork(), any other value (including empty) forces posix_spawn(), and an unset property selects the platform default. Default to posix_spawn() on Linux and macOS, and to fork() on other platforms, where the behavior of posix_spawn() has not been verified. Signed-off-by: Guillermo Rodríguez <grodriguez@ingelabs.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.