diff --git a/src/io.rs b/src/io.rs index a133e5de2..487f186ff 100644 --- a/src/io.rs +++ b/src/io.rs @@ -13,7 +13,7 @@ use crate::proc::JobGroupRef; use crate::redirection::{RedirectionMode, RedirectionSpecList}; use crate::signal::SigChecker; -use crate::topic_monitor::topic_t; +use crate::topic_monitor::Topic; use crate::wchar::prelude::*; use crate::wutil::{perror, perror_io, wdirname, wstat, wwrite_to_fd}; use errno::Errno; @@ -878,7 +878,7 @@ pub fn new(fd: RawFd) -> Self { assert!(fd >= 0, "Invalid fd"); FdOutputStream { fd, - sigcheck: SigChecker::new(topic_t::sighupint), + sigcheck: SigChecker::new(Topic::sighupint), errored: false, } } diff --git a/src/proc.rs b/src/proc.rs index 2dc5c19a8..cb52931fd 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -20,7 +20,7 @@ use crate::redirection::RedirectionSpecList; use crate::signal::{signal_set_handlers_once, Signal}; use crate::threads::MainThread; -use crate::topic_monitor::{topic_monitor_principal, topic_t, GenerationsList}; +use crate::topic_monitor::{topic_monitor_principal, GenerationsList, Topic}; use crate::wait_handle::{InternalJobId, WaitHandle, WaitHandleRef, WaitHandleStore}; use crate::wchar::{wstr, WString, L}; use crate::wchar_ext::ToWString; @@ -285,7 +285,7 @@ pub fn mark_exited(&self, status: &ProcStatus) { assert!(!self.exited(), "Process is already exited"); self.status.update(status); self.exited.store(true, Ordering::Release); - topic_monitor_principal().post(topic_t::internal_exit); + topic_monitor_principal().post(Topic::internal_exit); FLOG!( proc_internal_proc, "Internal proc", @@ -1382,13 +1382,13 @@ fn process_mark_finished_children(parser: &Parser, block_ok: bool) { if proc.has_pid() { // Reaps with a pid. - reapgens.set_min_from(topic_t::sigchld, &proc.gens); - reapgens.set_min_from(topic_t::sighupint, &proc.gens); + reapgens.set_min_from(Topic::sigchld, &proc.gens); + reapgens.set_min_from(Topic::sighupint, &proc.gens); } if proc.internal_proc.borrow().is_some() { // Reaps with an internal process. - reapgens.set_min_from(topic_t::internal_exit, &proc.gens); - reapgens.set_min_from(topic_t::sighupint, &proc.gens); + reapgens.set_min_from(Topic::internal_exit, &proc.gens); + reapgens.set_min_from(Topic::sighupint, &proc.gens); } } } diff --git a/src/signal.rs b/src/signal.rs index 951c932e9..629e0ca5a 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -6,7 +6,7 @@ use crate::nix::getpid; use crate::reader::{reader_handle_sigint, reader_sighup}; use crate::termsize::TermsizeContainer; -use crate::topic_monitor::{generation_t, topic_monitor_principal, topic_t, GenerationsList}; +use crate::topic_monitor::{topic_monitor_principal, Generation, GenerationsList, Topic}; use crate::wchar::prelude::*; use crate::wutil::{fish_wcstoi, perror}; use errno::{errno, set_errno}; @@ -83,7 +83,7 @@ extern "C" fn fish_signal_handler( if !observed { reader_sighup(); } - topic_monitor_principal().post(topic_t::sighupint); + topic_monitor_principal().post(Topic::sighupint); } libc::SIGTERM => { // Handle sigterm. The only thing we do is restore the front process ID, then die. @@ -103,11 +103,11 @@ extern "C" fn fish_signal_handler( CANCELLATION_SIGNAL.store(libc::SIGINT, Ordering::Relaxed); } reader_handle_sigint(); - topic_monitor_principal().post(topic_t::sighupint); + topic_monitor_principal().post(Topic::sighupint); } libc::SIGCHLD => { // A child process stopped or exited. - topic_monitor_principal().post(topic_t::sigchld); + topic_monitor_principal().post(Topic::sigchld); } libc::SIGALRM => { // We have a sigalarm handler that does nothing. This is used in the signal torture @@ -302,13 +302,13 @@ pub fn signal_unblock_all() { /// A Sigchecker can be used to check if a SIGINT (or SIGHUP) has been delivered. pub struct SigChecker { - topic: topic_t, - gen: generation_t, + topic: Topic, + gen: Generation, } impl SigChecker { /// Create a new checker for the given topic. - pub fn new(topic: topic_t) -> Self { + pub fn new(topic: Topic) -> Self { let mut res = SigChecker { topic, gen: 0 }; // Call check() to update our generation. res.check(); @@ -317,7 +317,7 @@ pub fn new(topic: topic_t) -> Self { /// Create a new checker for SIGHUP and SIGINT. pub fn new_sighupint() -> Self { - Self::new(topic_t::sighupint) + Self::new(Topic::sighupint) } /// Check if a sigint has been delivered since the last call to check(), or since the detector diff --git a/src/tests/topic_monitor.rs b/src/tests/topic_monitor.rs index 1f84bbb5b..8be7f3f2f 100644 --- a/src/tests/topic_monitor.rs +++ b/src/tests/topic_monitor.rs @@ -1,5 +1,5 @@ use crate::tests::prelude::*; -use crate::topic_monitor::{topic_monitor_t, topic_t, GenerationsList}; +use crate::topic_monitor::{GenerationsList, Topic, TopicMonitor}; use std::sync::{ atomic::{AtomicU32, AtomicU64, Ordering}, Arc, @@ -9,9 +9,9 @@ #[serial] fn test_topic_monitor() { let _cleanup = test_init(); - let monitor = topic_monitor_t::default(); + let monitor = TopicMonitor::default(); let gens = GenerationsList::new(); - let t = topic_t::sigchld; + let t = Topic::sigchld; gens.sigchld.set(0); assert_eq!(monitor.generation_for_topic(t), 0); let changed = monitor.check(&gens, false /* wait */); @@ -35,10 +35,10 @@ fn test_topic_monitor() { #[serial] fn test_topic_monitor_torture() { let _cleanup = test_init(); - let monitor = Arc::new(topic_monitor_t::default()); + let monitor = Arc::new(TopicMonitor::default()); const THREAD_COUNT: usize = 64; - let t1 = topic_t::sigchld; - let t2 = topic_t::sighupint; + let t1 = Topic::sigchld; + let t2 = Topic::sighupint; let mut gens_list = vec![GenerationsList::invalid(); THREAD_COUNT]; let post_count = Arc::new(AtomicU64::new(0)); for gen in &mut gens_list { diff --git a/src/topic_monitor.rs b/src/topic_monitor.rs index cbb011e03..bd39a8e75 100644 --- a/src/topic_monitor.rs +++ b/src/topic_monitor.rs @@ -15,7 +15,7 @@ generation only increases by 1. The only guarantee is that after a topic post, the current generation value is larger than any value previously queried. -Tying this all together is the topic_monitor_t. This provides the current topic generations, and +Tying this all together is the TopicMonitor. This provides the current topic generations, and also provides the ability to perform a blocking wait for any topic to change in a particular topic set. This is the real power of topics: you can wait for a sigchld signal OR a thread exit. */ @@ -36,7 +36,7 @@ /// The list of topics which may be observed. #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum topic_t { +pub enum Topic { sighupint = 0, // Corresponds to both SIGHUP and SIGINT signals. sigchld = 1, // Corresponds to SIGCHLD signal. internal_exit = 2, // Corresponds to an internal process exit. @@ -51,7 +51,7 @@ pub struct GenerationsList { } /// Simple value type containing the values for a topic. -/// This should be kept in sync with topic_t. +/// This should be kept in sync with Topic. impl GenerationsList { /// Update `self` gen counts to match those of `other`. pub fn update(&self, other: &Self) { @@ -61,15 +61,15 @@ pub fn update(&self, other: &Self) { } } -pub type generation_t = u64; +pub type Generation = u64; -impl FloggableDebug for topic_t {} +impl FloggableDebug for Topic {} /// A generation value which indicates the topic is not of interest. -pub const INVALID_GENERATION: generation_t = u64::MAX; +pub const INVALID_GENERATION: Generation = u64::MAX; -pub fn all_topics() -> [topic_t; 3] { - [topic_t::sighupint, topic_t::sigchld, topic_t::internal_exit] +pub fn all_topics() -> [Topic; 3] { + [Topic::sighupint, Topic::sigchld, Topic::internal_exit] } impl GenerationsList { @@ -103,25 +103,25 @@ fn describe(&self) -> WString { } /// Sets the generation for `topic` to `value`. - pub fn set(&self, topic: topic_t, value: generation_t) { + pub fn set(&self, topic: Topic, value: Generation) { match topic { - topic_t::sighupint => self.sighupint.set(value), - topic_t::sigchld => self.sigchld.set(value), - topic_t::internal_exit => self.internal_exit.set(value), + Topic::sighupint => self.sighupint.set(value), + Topic::sigchld => self.sigchld.set(value), + Topic::internal_exit => self.internal_exit.set(value), } } /// Return the value for a topic. - pub fn get(&self, topic: topic_t) -> generation_t { + pub fn get(&self, topic: Topic) -> Generation { match topic { - topic_t::sighupint => self.sighupint.get(), - topic_t::sigchld => self.sigchld.get(), - topic_t::internal_exit => self.internal_exit.get(), + Topic::sighupint => self.sighupint.get(), + Topic::sigchld => self.sigchld.get(), + Topic::internal_exit => self.internal_exit.get(), } } /// Return ourselves as an array. - pub fn as_array(&self) -> [generation_t; 3] { + pub fn as_array(&self) -> [Generation; 3] { [ self.sighupint.get(), self.sigchld.get(), @@ -130,14 +130,14 @@ pub fn get(&self, topic: topic_t) -> generation_t { } /// Set the value of `topic` to the smaller of our value and the value in `other`. - pub fn set_min_from(&mut self, topic: topic_t, other: &Self) { + pub fn set_min_from(&mut self, topic: Topic, other: &Self) { if self.get(topic) > other.get(topic) { self.set(topic, other.get(topic)); } } /// Return whether a topic is valid. - pub fn is_valid(&self, topic: topic_t) -> bool { + pub fn is_valid(&self, topic: Topic) -> bool { self.get(topic) != INVALID_GENERATION } @@ -292,9 +292,9 @@ fn default() -> Self { /// up. If if failed, then either a post() call updated the status values (so perhaps there is a /// new topic post) or some other thread won the race and called wait() on the semaphore. Here our /// thread will wait on the data_notifier_ queue. -type topic_bitmask_t = u8; +type TopicBitmask = u8; -fn topic_to_bit(t: topic_t) -> topic_bitmask_t { +fn topic_to_bit(t: Topic) -> TopicBitmask { 1 << (t as u8) } @@ -312,10 +312,10 @@ struct data_t { /// Sentinel status value indicating that a thread is waiting and needs a wakeup. /// Note it is an error for this bit to be set and also any topic bit. const STATUS_NEEDS_WAKEUP: u8 = 128; -type status_bits_t = u8; +type StatusBits = u8; #[derive(Default)] -pub struct topic_monitor_t { +pub struct TopicMonitor { data_: Mutex, /// Condition variable for broadcasting notifications. @@ -337,13 +337,13 @@ pub struct topic_monitor_t { } // safety: this is only needed for tests -unsafe impl Sync for topic_monitor_t {} +unsafe impl Sync for TopicMonitor {} /// The principal topic monitor. /// Do not attempt to move this into a lazy_static, it must be accessed from a signal handler. -static mut s_principal: *const topic_monitor_t = std::ptr::null(); +static mut s_principal: *const TopicMonitor = std::ptr::null(); -impl topic_monitor_t { +impl TopicMonitor { /// Initialize the principal monitor, and return it. /// This should be called only on the main thread. pub fn initialize() -> &'static Self { @@ -356,14 +356,14 @@ pub fn initialize() -> &'static Self { } } - pub fn post(&self, topic: topic_t) { + pub fn post(&self, topic: Topic) { // Beware, we may be in a signal handler! // Atomically update the pending topics. let topicbit = topic_to_bit(topic); const relaxed: Ordering = Ordering::Relaxed; // CAS in our bit, capturing the old status value. - let mut oldstatus: status_bits_t = 0; + let mut oldstatus: StatusBits = 0; let mut cas_success = false; while !cas_success { oldstatus = self.status_.load(relaxed); @@ -404,7 +404,7 @@ fn updated_gens_in_data(&self, data: &mut MutexGuard) -> GenerationsList // If there are no pending updates (likely) or a thread is waiting, just return. // Otherwise CAS in 0 and update our topics. const relaxed: Ordering = Ordering::Relaxed; - let mut changed_topic_bits: topic_bitmask_t = 0; + let mut changed_topic_bits: TopicBitmask = 0; let mut cas_success = false; while !cas_success { changed_topic_bits = self.status_.load(relaxed); @@ -446,12 +446,12 @@ fn updated_gens(&self) -> GenerationsList { } /// Access the current generations. - pub fn current_generations(self: &topic_monitor_t) -> GenerationsList { + pub fn current_generations(self: &TopicMonitor) -> GenerationsList { self.updated_gens() } /// Access the generation for a topic. - pub fn generation_for_topic(self: &topic_monitor_t, topic: topic_t) -> generation_t { + pub fn generation_for_topic(self: &TopicMonitor, topic: Topic) -> Generation { self.current_generations().get(topic) } @@ -490,7 +490,7 @@ fn try_update_gens_maybe_becoming_reader(&self, gens: &mut GenerationsList) -> b "No thread should be waiting" ); // Try becoming the reader by marking the reader bit. - let expected_old: status_bits_t = 0; + let expected_old: StatusBits = 0; if self .status_ .compare_exchange( @@ -587,10 +587,10 @@ pub fn check(&self, gens: &GenerationsList, wait: bool) -> bool { } pub fn topic_monitor_init() { - topic_monitor_t::initialize(); + TopicMonitor::initialize(); } -pub fn topic_monitor_principal() -> &'static topic_monitor_t { +pub fn topic_monitor_principal() -> &'static TopicMonitor { unsafe { assert!( !s_principal.is_null(),