Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
3 changed files
with
23 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } | ||
} |