summaryrefslogtreecommitdiffstats
path: root/tokio-signal/examples
diff options
context:
space:
mode:
Diffstat (limited to 'tokio-signal/examples')
-rw-r--r--tokio-signal/examples/ctrl-c.rs63
-rw-r--r--tokio-signal/examples/multiple.rs38
-rw-r--r--tokio-signal/examples/sighup-example.rs39
3 files changed, 140 insertions, 0 deletions
diff --git a/tokio-signal/examples/ctrl-c.rs b/tokio-signal/examples/ctrl-c.rs
new file mode 100644
index 00000000..df821a3f
--- /dev/null
+++ b/tokio-signal/examples/ctrl-c.rs
@@ -0,0 +1,63 @@
+extern crate futures;
+extern crate tokio_core;
+extern crate tokio_signal;
+
+use futures::{Future, Stream};
+use tokio_core::reactor::Core;
+
+/// how many signals to handle before exiting
+const STOP_AFTER: u64 = 10;
+
+fn main() {
+ // set up a Tokio event loop
+ let mut core = Core::new().unwrap();
+
+ // tokio_signal provides a convenience builder for Ctrl+C
+ // this even works cross-platform: linux and windows!
+ //
+ // `fn ctrl_c()` produces a `Future` of the actual stream-initialisation
+ // the `flatten_stream()` convenience method lazily defers that
+ // initialisation, allowing us to use it 'as if' it is already the
+ // stream we want, reducing boilerplate Future-handling.
+ let endless_stream = tokio_signal::ctrl_c().flatten_stream();
+ // don't keep going forever: convert the endless stream to a bounded one.
+ let limited_stream = endless_stream.take(STOP_AFTER);
+
+ // how many Ctrl+C have we received so far?
+ let mut counter = 0;
+
+ println!(
+ "This program is now waiting for you to press Ctrl+C {0} times.
+ * If running via `cargo run --example ctrl-c`, Ctrl+C also kills it, \
+ due to https://github.com/rust-lang-nursery/rustup.rs/issues/806
+ * If running the binary directly, the Ctrl+C is properly trapped.
+ Terminate by repeating Ctrl+C {0} times, or ahead of time by \
+ opening a second terminal and issuing `pkill -sigkil ctrl-c`",
+ STOP_AFTER
+ );
+
+ // Stream::for_each is a powerful primitive provided by the Futures crate.
+ // It turns a Stream into a Future that completes after all stream-items
+ // have been completed, or the first time the closure returns an error
+ let future = limited_stream.for_each(|()| {
+ // Note how we manipulate the counter without any fancy synchronisation.
+ // The borrowchecker realises there can't be any conflicts, so the closure
+ // can just capture it.
+ counter += 1;
+ println!(
+ "Ctrl+C received {} times! {} more before exit",
+ counter,
+ STOP_AFTER - counter
+ );
+
+ // return Ok-result to continue handling the stream
+ Ok(())
+ });
+
+ // Up until now, we haven't really DONE anything, just prepared
+ // now it's time to actually schedule, and thus execute, the stream
+ // on our event loop
+ core.run(future).unwrap();
+
+ println!("Stream ended, quiting the program.");
+}
diff --git a/tokio-signal/examples/multiple.rs b/tokio-signal/examples/multiple.rs
new file mode 100644
index 00000000..38052318
--- /dev/null
+++ b/tokio-signal/examples/multiple.rs
@@ -0,0 +1,38 @@
+//! A small example of how to listen for two signals at the same time
+
+extern crate futures;
+extern crate tokio_core;
+extern crate tokio_signal;
+
+use futures::{Future, Stream};
+use tokio_core::reactor::Core;
+use tokio_signal::unix::{Signal, SIGINT, SIGTERM};
+
+fn main() {
+ let mut core = Core::new().unwrap();
+
+ // Create a stream for each of the signals we'd like to handle.
+ let sigint = Signal::new(SIGINT).flatten_stream();
+ let sigterm = Signal::new(SIGTERM).flatten_stream();
+
+ // Use the `select` combinator to merge these two streams into one
+ let stream = sigint.select(sigterm);
+
+ // Wait for a signal to arrive
+ println!("Waiting for SIGINT or SIGTERM");
+ println!(
+ " TIP: use `pkill -sigint multiple` from a second terminal \
+ to send a SIGINT to all processes named 'multiple' \
+ (i.e. this binary)"
+ );
+ let (item, _rest) = core.run(stream.into_future()).ok().unwrap();
+
+ // Figure out which signal we received
+ let item = item.unwrap();
+ if item == SIGINT {
+ println!("received SIGINT");
+ } else {
+ assert_eq!(item, SIGTERM);
+ println!("received SIGTERM");
+ }
+}
diff --git a/tokio-signal/examples/sighup-example.rs b/tokio-signal/examples/sighup-example.rs
new file mode 100644
index 00000000..e48e23ea
--- /dev/null
+++ b/tokio-signal/examples/sighup-example.rs
@@ -0,0 +1,39 @@
+extern crate futures;
+extern crate tokio_core;
+extern crate tokio_signal;
+
+use futures::{Future, Stream};
+use tokio_core::reactor::Core;
+use tokio_signal::unix::{Signal, SIGHUP};
+
+fn main() {
+ // set up a Tokio event loop
+ let mut core = Core::new().unwrap();
+
+ // on Unix, we can listen to whatever signal we want, in this case: SIGHUP
+ let stream = Signal::new(SIGHUP).flatten_stream();
+
+ println!("Waiting for SIGHUPS (Ctrl+C to quit)");
+ println!(
+ " TIP: use `pkill -sighup sighup-example` from a second terminal \
+ to send a SIGHUP to all processes named 'sighup-example' \
+ (i.e. this binary)"
+ );
+
+ // for_each is a powerful primitive provided by the Futures crate
+ // it turns a Stream into a Future that completes after all stream-items
+ // have been completed.
+ let future = stream.for_each(|the_signal| {
+ println!(
+ "*Got signal {:#x}* I should probably reload my config \
+ or something",
+ the_signal
+ );
+ Ok(())
+ });
+
+ // Up until now, we haven't really DONE anything, just prepared
+ // now it's time to actually schedule, and thus execute, the stream
+ // on our event loop, and loop forever
+ core.run(future).unwrap();
+}