Commit Graph

14 Commits

Author SHA1 Message Date
John Nunley 420c303921
ci: Add a test that sleeps
I think this catches errors in notification for the Linux backend.

Signed-off-by: John Nunley <dev@notgull.net>
2024-03-30 08:31:01 -07:00
John Nunley f733a83c22
feat: Add a way to run without the async-process thread
I know I said that I wouldn't add any more features, but I
think this is important enough.

Right now, a thread called "async-process" is responsible for listening
for SIGCHLD and reaping zombie processes. This listens for the SIGCHLD
signal in Unix and uses a channel connected to the waitable handle on
Windows. While this works, we can do better. Through async-signal, the
signal was already asynchronous on Unix; we were already just using
async_io::block_on to wait on the signal. After swapping out the channel
used on Windows with async-channel, the process reaping function "reap"
can be reimplemented as a fully asynchronous future.

From here we must make sure this future is being polled at all times. To
facilitate this, a function named "driver()" is added to the public API.
This future acquires a lock on the reaper structure and calls the
"reap()" future indefinitely. Multiple drivers can be created at once;
they will just wait forever on this lock. This future is intended to be
spawned onto an executor and left to run forever, making sure all child
processes are signalled whenever necessary. If no tasks are running the
driver future, the "async-process" thread is spawned and runs the
"reap()" future itself.

I've added the following controls to make sure that this system is
robust:

- If a "driver" task is dropped, another "driver" task will acquire the
  lock and keep the reaper active.
- Before being dropped, the task checks to see if it is the last driver.
  If it is, it will spawn the "async-process" thread to be the driver.
- When a Child is being created, it checks if there are any active
  drivers. If there are none, it spawns the "async-process" thread
  itself.
- One concern is that the driver future wil try to spawn the
  "async-process" thread as the application exits and the task is being
  dropped, which will be unnecessary and lead to slower shutdowns. To
  prevent this, the future checks to see if there are any extant `Child`
  instances (a new refcount is added to Reaper to facilitate this). If
  there are none, and if there are no zombie processes, it does not
  spawn the additional thread.
- Someone can still `mem::forget()` the driver thread. This does not
  lead to undefined behavior and just leads to processes being left
  dangling. At this point they're asking for wacky behavior.

This strategy might also be viable for `async-io`, if we want to try to
avoid needing to spawn the additional thread there as well.

Closes #7
cc smol-rs/async-io#40

Signed-off-by: John Nunley <dev@notgull.net>
2023-10-10 17:47:46 -07:00
Taiki Endo d9d97d0299 Fix clippy::needless_borrow warning
```
error: the borrowed expression implements the required traits
   --> src/lib.rs:212:57
    |
212 |                     signal_hook::iterator::Signals::new(&[signal_hook::consts::SIGCHLD])
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: change this to: `[signal_hook::consts::SIGCHLD]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
    = note: `-D clippy::needless-borrow` implied by `-D warnings`

error: the borrowed expression implements the required traits
  --> tests/std.rs:14:38
   |
14 |             Command::new("cmd").args(&["/C", "exit 0"]).spawn()
   |                                      ^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "exit 0"]`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
   = note: `-D clippy::needless-borrow` implied by `-D warnings`

error: the borrowed expression implements the required traits
  --> tests/std.rs:35:38
   |
35 |             Command::new("cmd").args(&["/C", "exit 1"]).spawn()
   |                                      ^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "exit 1"]`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
  --> tests/std.rs:87:22
   |
87 |             cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped());
   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "echo foobar"]`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:145:23
    |
145 |                 .args(&["/C", "exit 1"])
    |                       ^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "exit 1"]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:156:23
    |
156 |                 .args(&["/C", "exit 0"])
    |                       ^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "exit 0"]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:189:23
    |
189 |                 .args(&["/C", "echo hello"])
    |                       ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "echo hello"]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:213:23
    |
213 |                 .args(&["/C", "mkdir ."])
    |                       ^^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "mkdir ."]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:231:38
    |
231 |             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
    |                                      ^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "exit 1"]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:243:38
    |
243 |             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
    |                                      ^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "exit 1"]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

error: the borrowed expression implements the required traits
   --> tests/std.rs:257:23
    |
257 |                 .args(&["/C", "echo hello"])
    |                       ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `["/C", "echo hello"]`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
```
2023-06-11 22:26:44 +09:00
Taiki Endo 73f3f8f308 Fix clippy::needless_borrow warning
```
warning: the borrowed expression implements the required traits
   --> tests/std.rs:311:29
    |
311 |             cmd.env("PATH", &p);
    |                             ^^ help: change this to: `p`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
    = note: `#[warn(clippy::needless_borrow)]` on by default
```
2022-12-30 13:43:50 +09:00
John Nunley de1071784e
Port to windows-sys (#27) 2022-11-26 21:14:01 -08:00
Taiki Endo d9b78cb400 Fix clippy::needless_return warning in test
```
warning: unneeded `return` statement
  --> tests/std.rs:80:5
   |
80 |     return ret;
   |     ^^^^^^^^^^^ help: remove `return`: `ret`
   |
   = note: `#[warn(clippy::needless_return)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
```
2022-07-17 21:32:20 +09:00
Taiki Endo fbc300608c Fix clippy::single_match warning in test
```
warning: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
  --> tests/std.rs:26:5
   |
26 | /     match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
27 | |         Ok(..) => panic!(),
28 | |         Err(..) => {}
29 | |     }
   | |_____^ help: try this: `if let Ok(..) = Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() { panic!() }`
   |
   = note: `#[warn(clippy::single_match)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_match
```
2022-07-17 21:31:38 +09:00
Jesse Luehrs afff8c533d don't unconfigure stdio streams on spawn 2021-12-30 22:13:17 -05:00
Félix Saparelli d91b557db3 Implement AsRawHandle on Child on Windows 2021-07-31 18:45:29 +12:00
Alexandru Macovei 6ea203d787 Fix Child::output to avoid killing the subprocess early when kill_on_drop is given 2021-01-31 22:43:19 +02:00
Stjepan Glavina 974c3cc080 Update futures-lite 2020-10-09 14:37:51 +02:00
Stjepan Glavina 79706e0bc0 Ignore some tests on windows 2020-08-19 13:41:24 +00:00
Stjepan Glavina 71d3dfcbab Initial version 2020-08-19 13:34:03 +00:00
Stjepan Glavina 251ab32f59 Initial commit 2020-08-18 20:19:25 +00:00