tokio 0.1.18
i686-pc-windows-gnu
tokio-signal
Recent changes to tokio-signal broke it under Windows and causes a panic. See attached backtrace.
I think it is related to commit cb55bf4012a0a43efe9dd436c079924acdcd0c1c.
To reproduce: build ctrl-c example from tokio-signal crate and run it.
Backtrace:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\libcore\option.rs:345:21
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
0: std::panicking::default_hook::{{closure}}
at src\libstd\sys_common/backtrace.rs:58
at src\libstd/panicking.rs:200
1: std::panicking::default_hook
at src\libstd/panicking.rs:215
2: std::panicking::rust_panic_with_hook
at src\libstd/panicking.rs:478
3: std::panicking::continue_panic_fmt
at src\libstd/panicking.rs:385
4: rust_begin_unwind
at src\libstd/panicking.rs:312
5: core::panicking::panic_fmt
at src\libcore/panicking.rs:85
6: core::panicking::panic
at src\libcore/panicking.rs:49
7: <core::option::Option<T>>::unwrap
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libcore\macros.rs:10
8: tokio_signal::windows::global_init
at src/windows.rs:165
9: tokio_signal::windows::Event::new::{{closure}}
at src/windows.rs:118
10: std::sync::once::Once::call_once::{{closure}}
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\sync\once.rs:220
11: std::sync::once::Once::call_inner
at src\libstd\sync/once.rs:387
12: std::sync::once::Once::call_once
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\sync\once.rs:220
13: tokio_signal::windows::Event::new
at src/windows.rs:117
14: tokio_signal::windows::Event::ctrl_c_handle
at src/windows.rs:96
15: tokio_signal::ctrl_c_handle::ctrl_c_imp::{{closure}}
at src/lib.rs:137
16: <futures::future::lazy::Lazy<F, R>>::get
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/future/lazy.rs:64
17: <futures::future::lazy::Lazy<F, R> as futures::future::Future>::poll
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/future/lazy.rs:82
18: <alloc::boxed::Box<F> as futures::future::Future>::poll
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/future/mod.rs:113
19: <futures::future::flatten_stream::FlattenStream<F> as futures::stream::Stream>::poll
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/future/flatten_stream.rs:63
20: <futures::stream::take::Take<S> as futures::stream::Stream>::poll
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/stream/take.rs:78
21: <futures::stream::for_each::ForEach<S, F, U> as futures::future::Future>::poll
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/stream/for_each.rs:45
22: <futures::task_impl::Spawn<T>>::poll_future_notify::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/task_impl/mod.rs:326
23: <futures::task_impl::Spawn<T>>::enter::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/task_impl/mod.rs:396
24: futures::task_impl::std::set
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/task_impl/std/mod.rs:78
25: <futures::task_impl::Spawn<T>>::enter
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/task_impl/mod.rs:396
26: <futures::task_impl::Spawn<T>>::poll_fn_notify
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/task_impl/mod.rs:288
27: <futures::task_impl::Spawn<T>>::poll_future_notify
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.25/src/task_impl/mod.rs:326
28: <tokio_current_thread::Entered<'a, P>>::block_on::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-current-thread-0.1.6/src/lib.rs:494
29: <tokio_current_thread::Borrow<'a, U>>::enter::{{closure}}::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-current-thread-0.1.6/src/lib.rs:788
30: tokio_current_thread::CurrentRunner::set_spawn
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-current-thread-0.1.6/src/lib.rs:825
31: <tokio_current_thread::Borrow<'a, U>>::enter::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-current-thread-0.1.6/src/lib.rs:788
32: <std::thread::local::LocalKey<T>>::try_with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:299
33: <std::thread::local::LocalKey<T>>::with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:245
34: <tokio_current_thread::Borrow<'a, U>>::enter
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-current-thread-0.1.6/src/lib.rs:786
35: <tokio_current_thread::Entered<'a, P>>::block_on
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-current-thread-0.1.6/src/lib.rs:491
36: tokio::runtime::current_thread::runtime::Runtime::block_on::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:200
37: tokio::runtime::current_thread::runtime::Runtime::enter::{{closure}}::{{closure}}::{{closure}}::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:241
38: tokio_executor::global::with_default::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-executor-0.1.7/src/global.rs:209
39: <std::thread::local::LocalKey<T>>::try_with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:299
40: <std::thread::local::LocalKey<T>>::with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:245
41: tokio_executor::global::with_default
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-executor-0.1.7/src/global.rs:178
42: tokio::runtime::current_thread::runtime::Runtime::enter::{{closure}}::{{closure}}::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:239
43: tokio_timer::timer::handle::with_default::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-timer-0.2.10/src/timer/handle.rs:94
44: <std::thread::local::LocalKey<T>>::try_with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:299
45: <std::thread::local::LocalKey<T>>::with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:245
46: tokio_timer::timer::handle::with_default
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-timer-0.2.10/src/timer/handle.rs:81
47: tokio::runtime::current_thread::runtime::Runtime::enter::{{closure}}::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:232
48: tokio_timer::clock::clock::with_default::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-timer-0.2.10/src/clock/clock.rs:141
49: <std::thread::local::LocalKey<T>>::try_with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:299
50: <std::thread::local::LocalKey<T>>::with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:245
51: tokio_timer::clock::clock::with_default
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-timer-0.2.10/src/clock/clock.rs:124
52: tokio::runtime::current_thread::runtime::Runtime::enter::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:231
53: tokio_reactor::with_default::{{closure}}
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-reactor-0.1.9/src/lib.rs:237
54: <std::thread::local::LocalKey<T>>::try_with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:299
55: <std::thread::local::LocalKey<T>>::with
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\thread\local.rs:245
56: tokio_reactor::with_default
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-reactor-0.1.9/src/lib.rs:217
57: tokio::runtime::current_thread::runtime::Runtime::enter
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:230
58: tokio::runtime::current_thread::runtime::Runtime::block_on
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/runtime.rs:198
59: tokio::runtime::current_thread::block_on_all
at /home/dmitry/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.1.18/src/runtime/current_thread/mod.rs:89
60: ctrl_c::main
at examples/ctrl-c.rs:56
61: std::rt::lang_start::{{closure}}
at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
The panic is thrown here: https://github.com/tokio-rs/tokio/blob/9c5cad037fd78adb087bc4734f7670d5732122c5/tokio-signal/src/windows.rs#L161-L164
I'm not super familiar with this code, but it appears that we expect things to be fully registered when invoking the PollEvented. Since we switched to a lazily initialized reactor, the inner wirings aren't guaranteed to be fully initialized (previously we used Handle::current which spun up a reactor for us, and my guess is that MyRegistration::register isn't being invoked right away).
Figured out the issue, turns out we're expecting the MyRegistration::register call to create the readiness structures which are shared by the driver and the caller's task.
I was able to refactor the code pretty trivially to create the readiness structs first and pass it on to the PollEvented (which will lazily register into the reactor as needed).
I'll submit a PR for this a bit later.
On an unrelated note, the ctrl-c example still doesn't work quite right, even with the fix above, because we're blocking on all futures spawned into the runtime, which includes an immortal driver task which intercepts the OS ctrl-c events. I want to look into refactoring the driver task to possibly die on it's own if there are no more ctrl-c listeners
@carllerche I think we should yank tokio-signal 0.2.8 for now since it will panic for anyone constructing signal streams without an initialized reactor
@Stargateur Carl has yanked the package, we'll probably publish a new version after the fix is merged in
Most helpful comment
@Stargateur Carl has yanked the package, we'll probably publish a new version after the fix is merged in