-
Notifications
You must be signed in to change notification settings - Fork 1.6k
adding RFC process-handle-for-async #2823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
How does this differ from the |
@sfackler Windows-Handles are the perfect way, the Unix-PIDs are a nightmare, citing from tokio-process https://github.com/alexcrichton/tokio-process/blob/master/src/unix/mod.rs
This breaks the ownership concept and relies heavily on signal-hander setups. So, instead of using the hairy signal concept of legacy Unix, Rust should rely on the newer Unix APIs for process handling, such as pidfd, pdfork, anf forkfd, providing now a similar functionality as Windows-Handle. For each child-process Windows provides both, a PID and a HANDLE. On Unix Rust API just supports a PID per child. So using the new concepts of pidfd, pdfork, etc. we may extend the public API of std::process:Process now to provide both |
I'd love to see this change, but I don't know if we can reasonably handle the non-pidfd case or the POSIX case without placing requirements on the caller that we don't want to place. @thiagomacieira, can you weigh in regarding the Qt code for the non-pidfd compatibility case? We talked about the requirements the self-pipe and SIGCHLD approach had, to avoid disrupting any other code in the same program (given all the issues with signal handling). Can you talk about some of those requirements here? |
The code I have at https://github.com/qt/qtbase/tree/dev/src/3rdparty/forkfd works pretty well for all Unix operating systems. The pidfd version of it will come soon, as soon as I can find the time to test on a Linux 5.4.0 to make sure things still run (change is at https://codereview.qt-project.org/c/qt/qtbase/+/108456). Here's what you need to know:
But:
Glib's GSpawn code is guilty of both cooperation shortcomings. Therefore, if there's a chance that GSpawn will be used in the same process, the forkfd signal handler should be installed after Glib's. |
An alternative implementation is to have a babysitter, intermediary process. Instead of the process that is the final objective being the direct child of the main process, it's a grandchild, with the intermediate child stopped at Advantages:
Disadvantages:
The minimum cost of an intermediary babysitter, for a very, very tiny, statically-linked executable, is 1 shared page + 2 pages per process thus launched (1 for .data/.bss and one for the stack, which could be bigger since the environment is stored there). |
Finally, a third alternative is to dedicate a thread of the main process to But threads aren't free. You do consume at least one page per thread, for the thread's stack. Like the babysitter case, this means you have more Linux processes[*] running at any point in time, which means you could get much closer to your fork limit. One big disadvantage of this method is that, unlike the other two, you can't simply abandon a child after the threaded [*] "process" here is the kernel term: any userspace thread. |
As already stated in the associated issue-ticket: #2817 As for the question, how to deal with child-processes on older Linux/Posix-Systems (the non-pidfd compatibility case), the following code illustrates the way, the QProcess implementation is working in this legacy environment successfully. The code can be executed in two modes 1) Not-Qt-Mode, keeping the read-end inparent-process and write-end in child-process. 2) Qt-Mode, closing both ends in forked child-process and keeping both ends in parent-process. Compile the code using "gcc -o a.out test_dath_pipe.c" And execute as "./a.out not-qt-mode" or "./a.out qt-mode" It shows, that in both modes the parent-process receives the termination signal as POLLIN-event. The way QProcess has been implemented is favourable, indeed, as it does not leak file-descriptors to sub-sub-processes. I hope, this short code snippet illustrates the mechanisms, implementing the death-pipe on top of basic POSIX API in case the underlying OS does not provide a suitable native functionality. |
Co-Authored-By: the8472 <the8472@users.noreply.github.com>
Co-Authored-By: the8472 <the8472@users.noreply.github.com>
Co-Authored-By: the8472 <the8472@users.noreply.github.com>
Co-Authored-By: the8472 <the8472@users.noreply.github.com>
Rendered