Permalink
Browse files

Use integer_atomics feature

Rather than using AtomicUsize and AtomicBool fields within
our ForegroundSignals structure, I'm switching this over
to using AtomicU32 and AtomicU8 values instead.
  • Loading branch information...
mmstick committed Oct 26, 2017
1 parent 5e2b08a commit e5d307401e65a08507fbf23b3124265c21fd9d38
Showing with 23 additions and 28 deletions.
  1. +1 −0 src/lib.rs
  2. +1 −0 src/main.rs
  3. +21 −28 src/shell/pipe_exec/foreground.rs
@@ -1,6 +1,7 @@
#![allow(unknown_lints)]
#![allow(while_let_on_iterator)]
#![feature(conservative_impl_trait)]
#![feature(integer_atomics)]
extern crate app_dirs;
#[macro_use]
@@ -1,6 +1,7 @@
#![allow(unknown_lints)]
#![allow(while_let_on_iterator)]
#![feature(conservative_impl_trait)]
#![feature(integer_atomics)]
// For a performance boost on Linux
// #![feature(alloc_system)]
@@ -1,64 +1,57 @@
//! Contains the logic for enabling foreground management.
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::atomic::{AtomicU32, AtomicU8, Ordering};
pub(crate) enum BackgroundResult {
Errored,
Status(u8),
}
const REPLIED: u8 = 1;
const ERRORED: u8 = 2;
/// An atomic structure that can safely be shared across threads, which serves to provide
/// communication between the shell and background threads. The `fg` command uses this
/// structure to notify a background thread that it needs to wait for and return
/// the exit status back to the `fg` function.
pub(crate) struct ForegroundSignals {
grab: AtomicUsize, // TODO: Use AtomicU32 when stable
status: AtomicUsize, // TODO: Use AtomicU8 when stable
reply: AtomicBool,
errored: AtomicBool, // TODO: Combine with reply when U8 is stable
grab: AtomicU32,
status: AtomicU8,
reply: AtomicU8,
}
impl ForegroundSignals {
pub(crate) fn new() -> ForegroundSignals {
ForegroundSignals {
grab: AtomicUsize::new(0),
status: AtomicUsize::new(0),
reply: AtomicBool::new(false),
errored: AtomicBool::new(false),
grab: AtomicU32::new(0),
status: AtomicU8::new(0),
reply: AtomicU8::new(0),
}
}
pub(crate) fn signal_to_grab(&self, pid: u32) {
self.grab.store(pid as usize, Ordering::Relaxed);
}
pub(crate) fn signal_to_grab(&self, pid: u32) { self.grab.store(pid, Ordering::Relaxed); }
pub(crate) fn reply_with(&self, status: i8) {
self.grab.store(0, Ordering::Relaxed);
self.status.store(status as usize, Ordering::Relaxed);
self.reply.store(true, Ordering::Relaxed);
self.status.store(status as u8, Ordering::Relaxed);
self.reply.store(REPLIED, Ordering::Relaxed);
}
pub(crate) fn errored(&self) {
self.grab.store(0, Ordering::Relaxed);
self.errored.store(true, Ordering::Relaxed);
self.reply.store(true, Ordering::Relaxed);
self.reply.store(ERRORED, Ordering::Relaxed);
}
pub(crate) fn was_processed(&self) -> Option<BackgroundResult> {
if self.reply.load(Ordering::Relaxed) {
self.reply.store(false, Ordering::Relaxed);
if self.errored.load(Ordering::Relaxed) {
self.errored.store(false, Ordering::Relaxed);
Some(BackgroundResult::Errored)
} else {
Some(BackgroundResult::Status(self.status.load(Ordering::Relaxed) as u8))
}
let reply = self.reply.load(Ordering::Relaxed);
self.reply.store(0, Ordering::Relaxed);
if reply & ERRORED != 0 {
Some(BackgroundResult::Errored)
} else if reply & REPLIED != 0 {
Some(BackgroundResult::Status(self.status.load(Ordering::Relaxed) as u8))
} else {
None
}
}
pub(crate) fn was_grabbed(&self, pid: u32) -> bool {
self.grab.load(Ordering::Relaxed) == pid as usize
}
pub(crate) fn was_grabbed(&self, pid: u32) -> bool { self.grab.load(Ordering::Relaxed) == pid }
}

0 comments on commit e5d3074

Please sign in to comment.