From e5d307401e65a08507fbf23b3124265c21fd9d38 Mon Sep 17 00:00:00 2001
From: Michael Aaron Murphy <mmstickman@gmail.com>
Date: Thu, 26 Oct 2017 10:57:02 -0400
Subject: [PATCH] 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.

---
 src/lib.rs                        |  1 +
 src/main.rs                       |  1 +
 src/shell/pipe_exec/foreground.rs | 49 +++++++++++++------------------
 3 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index c28a059a..b758479a 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 d575fb63..36928eb3 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 30c9caeb..31972532 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 }
 }
-- 
GitLab