Skip to content

Commit 3696555

Browse files
authored
Merge pull request #5 from bossmc/fn-mut-handler
Allow `FnMut` handler functions and placate clippy
2 parents 19d8577 + e0d6800 commit 3696555

File tree

3 files changed

+23
-53
lines changed

3 files changed

+23
-53
lines changed

Cargo.toml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,4 @@ name = "simple_signal"
1414

1515
[dependencies]
1616
libc = "0.2"
17-
18-
[dependencies.lazy_static]
19-
version = "1.0"
20-
optional = true
21-
22-
[features]
23-
default = ["stable"]
24-
nightly = []
25-
stable = ["lazy_static"]
17+
lazy_static = "1.4"

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,3 @@ fn main() {
2323

2424
#### Try the example yourself
2525
`cargo run --example readme_example`
26-
27-
## Building
28-
If you're using a nightly compiler, I suggest building with `cargo build --features nightly` to avoid the dependency on *lazy_static*. On stable and beta compilers, just run `cargo build`.

src/lib.rs

Lines changed: 22 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
//! A simple wrapper for handling Unix process signals.
22
3-
#![cfg_attr(feature="nightly", feature(static_condvar))]
4-
#![cfg_attr(feature="nightly", feature(static_mutex))]
5-
6-
#[cfg(feature="stable")]
7-
#[macro_use]
8-
extern crate lazy_static;
9-
103
use std::sync::atomic::Ordering;
11-
use std::thread;
124

135
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
146
pub enum Signal {
@@ -25,35 +17,20 @@ pub enum Signal {
2517
Term,
2618
}
2719

28-
#[cfg(feature="nightly")]
29-
mod features {
30-
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
31-
use std::sync::{StaticCondvar, CONDVAR_INIT, StaticMutex, MUTEX_INIT};
32-
pub static CVAR: StaticCondvar = CONDVAR_INIT;
33-
pub static MUTEX: StaticMutex = MUTEX_INIT;
34-
pub static MASK: AtomicUsize = ATOMIC_USIZE_INIT;
20+
use std::sync::atomic::AtomicUsize;
21+
use std::sync::{Condvar, Mutex};
22+
lazy_static::lazy_static! {
23+
pub static ref CVAR: Condvar = Condvar::new();
24+
pub static ref MUTEX: Mutex<()> = Mutex::new(());
3525
}
36-
37-
#[cfg(not(feature="nightly"))]
38-
mod features {
39-
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
40-
use std::sync::{Condvar, Mutex};
41-
lazy_static! {
42-
pub static ref CVAR: Condvar = Condvar::new();
43-
pub static ref MUTEX: Mutex<bool> = Mutex::new(false);
44-
}
45-
pub static MASK: AtomicUsize = ATOMIC_USIZE_INIT;
46-
}
47-
48-
use self::features::*;
26+
pub static MASK: AtomicUsize = AtomicUsize::new(0);
4927

5028
#[cfg(unix)]
5129
mod platform {
5230
extern crate libc;
5331

5432
use self::libc::{c_int, signal, sighandler_t};
5533
use self::libc::{SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGKILL, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM};
56-
use std::mem;
5734
use std::sync::atomic::Ordering;
5835
use super::Signal;
5936

@@ -74,13 +51,13 @@ mod platform {
7451
};
7552

7653
loop {
77-
let prev_mask = super::features::MASK.load(Ordering::Relaxed);
54+
let prev_mask = super::MASK.load(Ordering::Relaxed);
7855
let new_mask = prev_mask | mask;
79-
if super::features::MASK.compare_and_swap(prev_mask, new_mask, Ordering::Relaxed) == new_mask {
56+
if super::MASK.compare_exchange(prev_mask, new_mask, Ordering::Relaxed, Ordering::Relaxed).is_ok() {
8057
break;
8158
}
8259
}
83-
super::features::CVAR.notify_all();
60+
super::CVAR.notify_all();
8461
}
8562

8663
#[inline]
@@ -99,7 +76,7 @@ mod platform {
9976
Signal::Term => SIGTERM,
10077
};
10178

102-
signal(os_sig, mem::transmute::<_, sighandler_t>(handler as extern "C" fn(_)));
79+
signal(os_sig, handler as extern "C" fn(_) as sighandler_t);
10380
}
10481
}
10582

@@ -112,17 +89,17 @@ use self::platform::*;
11289
/// use simple_signal::{self, Signal};
11390
/// simple_signal::set_handler(&[Signal::Int, Signal::Term], |signals| println!("Caught: {:?}", signals));
11491
/// ```
115-
pub fn set_handler<F>(signals: &[Signal], user_handler: F) where F: Fn(&[Signal]) + 'static + Send {
92+
pub fn set_handler<F>(signals: &[Signal], mut user_handler: F) where F: FnMut(&[Signal]) + 'static + Send {
11693
for &signal in signals.iter() {
11794
unsafe { set_os_handler(signal) }
11895
}
119-
thread::spawn(move || {
96+
std::thread::spawn(move || {
12097
let mut signals = Vec::new();
98+
let mut guard = MUTEX.lock().unwrap();
12199
loop {
122-
let mask = MASK.load(Ordering::Relaxed);
100+
let mask = MASK.swap(0, Ordering::Relaxed);
123101
if mask == 0 {
124-
let _ = CVAR.wait(MUTEX.lock().unwrap());
125-
thread::yield_now();
102+
guard = CVAR.wait(guard).unwrap();
126103
continue;
127104
}
128105
signals.clear();
@@ -137,7 +114,6 @@ pub fn set_handler<F>(signals: &[Signal], user_handler: F) where F: Fn(&[Signal]
137114
if mask & 256 != 0 { signals.push(Signal::Pipe) }
138115
if mask & 512 != 0 { signals.push(Signal::Alrm) }
139116
if mask & 1024 != 0 { signals.push(Signal::Term) }
140-
MASK.store(0, Ordering::Relaxed);
141117
user_handler(&signals);
142118
}
143119
});
@@ -150,7 +126,7 @@ mod test {
150126
use std::sync::mpsc::sync_channel;
151127
use self::libc::c_int;
152128
use self::libc::{SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGKILL, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM};
153-
use super::{Signal};
129+
use super::Signal;
154130
use super::platform::handler;
155131

156132
fn to_os_signal(signal: Signal) -> c_int {
@@ -173,7 +149,12 @@ mod test {
173149
fn all_signals() {
174150
let signals = [Signal::Hup, Signal::Int, Signal::Quit, Signal::Abrt, Signal::Term];
175151
let (tx, rx) = sync_channel(0);
176-
super::set_handler(&signals, move |signals| tx.send(signals.to_owned()).unwrap());
152+
let mut signal_count = 0;
153+
super::set_handler(&signals, move |signals| {
154+
signal_count += signals.len();
155+
println!("Handled {} signals", signal_count);
156+
tx.send(signals.to_owned()).unwrap();
157+
});
177158
// Check all signals one-by-one.
178159
for &signal in signals.iter() {
179160
handler(to_os_signal(signal));

0 commit comments

Comments
 (0)