diff --git a/src/lib.rs b/src/lib.rs index c28a059ac955d78a353a66b8217207803c50748b..b758479ac295f07bd26cacc0127dc4f842c7bb58 100644 --- a/src/lib.rs +++ b/src/lib.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] diff --git a/src/main.rs b/src/main.rs index d575fb6367f7fcb9f582119d801cc4ac2e83f81a..36928eb31f4e61a9c3e49e7e8933dcb7c0049a5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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)] diff --git a/src/shell/pipe_exec/foreground.rs b/src/shell/pipe_exec/foreground.rs index 30c9caebb3a04cbb98dc22303f03925622d8dc97..319725327f54cdb0cfc64612af8c813735a58f94 100644 --- a/src/shell/pipe_exec/foreground.rs +++ b/src/shell/pipe_exec/foreground.rs @@ -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 } }