Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df1fd92

Browse files
authored
Merge pull request #3 from vorner/signal-ub
Fix the example so it doesn't contain UB
2 parents 45869d1 + fe512e4 commit df1fd92

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

examples/signal.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ extern crate nix;
99
extern crate lazy_static;
1010

1111
use nix::sys::signal;
12-
use std::sync::atomic::AtomicBool;
13-
use std::sync::atomic::Ordering::SeqCst;
12+
use std::sync::atomic::{AtomicBool, Ordering};
1413
use std::time::Duration;
1514

1615
use std::{thread, io};
@@ -21,17 +20,21 @@ use std::sync::Mutex;
2120
lazy_static! {
2221
// global atomic switch drain control
2322
static ref ATOMIC_DRAIN_SWITCH : AtomicSwitchCtrl<(), io::Error> = AtomicSwitch::new(
24-
Discard.map_err(|_| io::Error::new(io::ErrorKind::Other, "should no happen"))
23+
Discard.map_err(|_| io::Error::new(io::ErrorKind::Other, "should not happen"))
2524
).ctrl();
2625

2726
// track current state of the atomic switch drain
2827
static ref ATOMIC_DRAIN_SWITCH_STATE : AtomicBool = AtomicBool::new(false);
28+
29+
// A flag set by a signal handler to please switch the logger
30+
// (It can't be switched inside the signal handler, as that would use non async-signal-safe
31+
// functions).
32+
static ref SWITCH_SCHEDULED: AtomicBool = AtomicBool::new(false);
2933
}
3034

3135
fn atomic_drain_switch() {
32-
// XXX: Not atomic. Race?
33-
let new = !ATOMIC_DRAIN_SWITCH_STATE.load(SeqCst);
34-
ATOMIC_DRAIN_SWITCH_STATE.store(new, SeqCst);
36+
// Negate in place and get the new value.
37+
let new = !ATOMIC_DRAIN_SWITCH_STATE.fetch_nand(true, Ordering::Relaxed);
3538

3639
if new {
3740
ATOMIC_DRAIN_SWITCH.set(Mutex::new(slog_json::Json::new(std::io::stderr()).build())
@@ -47,7 +50,7 @@ fn atomic_drain_switch() {
4750
}
4851

4952
extern "C" fn handle_sigusr1(_: i32) {
50-
atomic_drain_switch();
53+
SWITCH_SCHEDULED.store(true, Ordering::Relaxed);
5154
}
5255

5356
fn main() {
@@ -71,6 +74,10 @@ fn main() {
7174
let pid = nix::unistd::getpid();
7275
info!(log, "kill -SIGUSR1 {}", pid);
7376
loop {
77+
if SWITCH_SCHEDULED.swap(false, Ordering::Relaxed) {
78+
debug!(log, "Switching the logger");
79+
atomic_drain_switch();
80+
}
7481
info!(log, "tick");
7582
thread::sleep(Duration::from_millis(3000));
7683
}

0 commit comments

Comments
 (0)