haskell / haskell/process

Use pidfd to track processes on Linux >= 5.4

Open
#190 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
91
Forks
91
PR merge metrics
No merged PRs in 30d

Description

Background:

* https://lwn.net/Articles/789023/
* https://lwn.net/Articles/794707/

The problem `Pid`s in [`ProcessHandle`](https://hackage.haskell.org/package/process-1.6.10.0/docs/System-Process.html#t:ProcessHandle)s is that on most system they are limited to 2^16 many by default. If you spawn many short-lived processes quickly, the pid namespace can wrap around and you will accidentally [`waitForProcess`](https://hackage.haskell.org/package/process-1.6.10.0/docs/System-Process.html#v:waitForProcess) (`wait()`) on the wrong process, or `terminateProcess` the wrong one.

Linux 5.4 solves this with pidfds (which are per-process, and 32-bit many). They can point to zombie processes so they will never accidentally point to a different process.

The `process` library could use them on newer Linux by simply tracking the pidfd in a `Maybe` field inside `ProcessHandle`.

* After being spawned, a pid can be converted to a `pidfd` using [`pidfd_open()`](https://man7.org/linux/man-pages/man2/pidfd_open.2.html) -- but this is still slightly racy, and better is to get it atomically directly from `clone()`. But it's an easy migration path that's a strict improvement already.
* pidfds can be waited on with `select()`, `epoll()` and so on, which means we can use the GHC IO manager to wait for them more efficiently than with the usual `waitForProcess`.

This Rust library https://github.com/pop-os/pidfd shows how you can [wait for a program to finish using `waitid()`](https://github.com/pop-os/pidfd/blob/28301e25caa80cb7cfc1f32453ef23e28203e867/src/lib.rs#L171-L182).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.