Skip to content

Allow FnMut handler functions and placate clippy #5

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

Merged
merged 1 commit into from
Apr 15, 2021

Conversation

bossmc
Copy link

@bossmc bossmc commented Apr 15, 2021

Started as "the handler function can be a FnMut without any other changes"... went down a bit of a rabbit hole while I was there:

  • Fixed up various clippy warnings
  • Removed the nightly feature since static_mutex/static_condvar has disappeared in nightly (you might consider keeping the feature name as a no-op so this isn't a breaking change?)
  • Replaced some deprecated code (AtomicUint::compare_and_swap)

I also considered but managed to stop myself from:

  • Running cargo fmt - but it broken up a lot of single lines into three lines in an annoying way, could still be worth doing
  • Adding clippy/fmt to the travis-ci script - couldn't add fmt due to previous bullet and didn't add clippy because it's annoying to add (do you enable -Dwarnings? do you allow_failure? what if clippy adds a new lint?)

let mut signal_count = 0;
super::set_handler(&signals, move |signals| {
signal_count += signals.len();
println!("Handled {} signals", signal_count);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Is this "println!" here for a reason or it is just kind of debugging forgotten?

Copy link
Author

@bossmc bossmc Apr 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's there for a reason, but not a great one 😄 I wanted to prove the handler could be FnMut by testing with one that mutates captured variables, so I added the signal_count variable - then rust complained that it was unreferenced (since the code only increments it).

I added the printf to "use" the variable (and you can see the output with cargo test -- --nocapture) - I considered sending the current value out of the closure on a new channel and asserting the current count on the outside (as the test already does for the signals), but that's not really testing anything meaningful.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay, I got it :)

I doubt that the handler could really be FnMut, I have a strong feeling that we cannot directly mutate anything from another (detached) thread via &mut reference.

For example consider the main thread has exited before the one in set_handler, then any access from it will trigger segmentation fault.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FnMut allows mutation of captured variables, which is independent to accessing &mut references. The use case I wanted was something like:

async fn main() {
  let (rx, tx) = tokio::sync::oneshot();
  let mut tx = Some(tx);
  set_handler(&signals, move |_| {
    if let Some(tx) = tx.take() {        // `take` needs `FnMut`
      tx.send("shutdown now please");
    }
  })

  tokio::spawn(...); // etc.

  rx.await;

  info!("Shutting down now");
}

As the handler is 'static it can't capture references (mutable or otherwise) which prevents the segfault you were thinking about.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay that sounds perfectly reasonable!

@swizard0 swizard0 merged commit 3696555 into swizard0:master Apr 15, 2021
@bossmc bossmc deleted the fn-mut-handler branch February 26, 2025 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants