mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-09 03:51:20 -03:00
Port (and use) ASSERT_IS_BACKGROUND_THREAD/ASSERT_IS_MAIN_THREAD
Rust doesn't have __FUNCTION__ or __func__ (though you can hack around it with a proc macro, but that will require a separate crate and slowing down compilation times with heavy proc macro dependencies), so these are just regular functions (at least for now). Rust's default stack trace on panic (even in release mode) should be enough (and the functions themselves are inlined so the calling function should be the second frame from the top, after the #[cold] panic functions).
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
use crate::{
|
||||
ffi,
|
||||
wchar_ffi::{wstr, WCharFromFFI, WString},
|
||||
};
|
||||
use std::{ffi::c_uint, mem};
|
||||
use crate::ffi;
|
||||
use crate::wchar_ffi::{wstr, WCharFromFFI, WString};
|
||||
use std::ffi::c_uint;
|
||||
use std::mem;
|
||||
|
||||
/// A scoped manager to save the current value of some variable, and optionally set it to a new
|
||||
/// value. When dropped, it restores the variable to its old value.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
use crate::fds::AutoCloseFd;
|
||||
use crate::ffi::void_ptr;
|
||||
use crate::flog::FLOG;
|
||||
use crate::threads::assert_is_background_thread;
|
||||
use crate::wutil::perror;
|
||||
use cxx::SharedPtr;
|
||||
|
||||
@@ -407,6 +408,8 @@ impl BackgroundFdMonitor {
|
||||
/// Starts monitoring the fd set and listening for new fds to add to the set. Takes ownership
|
||||
/// over its instance so that this method cannot be called again.
|
||||
fn run(mut self) {
|
||||
assert_is_background_thread();
|
||||
|
||||
let mut pokelist: Vec<FdMonitorItemId> = Vec::new();
|
||||
let mut fds = FdReadableSet::new();
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ mod ffi2 {
|
||||
fn rust_init() {
|
||||
crate::topic_monitor::topic_monitor_init();
|
||||
crate::future_feature_flags::future_feature_flags_init();
|
||||
crate::threads::init();
|
||||
}
|
||||
|
||||
/// FFI bridge for activate_flog_categories_by_pattern().
|
||||
|
||||
@@ -2,6 +2,65 @@
|
||||
//! ported directly from the cpp code so we can use rust threads instead of using pthreads.
|
||||
|
||||
use crate::flog::FLOG;
|
||||
use std::thread::{self, ThreadId};
|
||||
|
||||
// We don't want to use a full-blown Lazy<T> for the cached main thread id, but we can't use
|
||||
// AtomicU64 since std::thread::ThreadId::as_u64() is a nightly-only feature (issue #67939,
|
||||
// thread_id_value). We also can't safely transmute `ThreadId` to `NonZeroU64` because there's no
|
||||
// guarantee that's what the underlying type will always be on all platforms and in all cases,
|
||||
// `ThreadId` isn't marked `#[repr(transparent)]`. We could generate our own thread-local value, but
|
||||
// `#[thread_local]` is nightly-only while the stable `thread_local!()` macro doesn't generate
|
||||
// efficient/fast/low-overhead code.
|
||||
|
||||
/// The thread id of the main thread, as set by [`init()`] at startup.
|
||||
static mut MAIN_THREAD_ID: Option<ThreadId> = None;
|
||||
|
||||
/// Initialize some global static variables. Must be called at startup from the main thread.
|
||||
pub fn init() {
|
||||
unsafe {
|
||||
if MAIN_THREAD_ID.is_some() {
|
||||
panic!("threads::init() must only be called once (at startup)!");
|
||||
}
|
||||
MAIN_THREAD_ID = Some(thread::current().id());
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn main_thread_id() -> ThreadId {
|
||||
#[cold]
|
||||
fn init_not_called() -> ! {
|
||||
panic!("threads::init() was not called at startup!");
|
||||
}
|
||||
|
||||
match unsafe { MAIN_THREAD_ID } {
|
||||
None => init_not_called(),
|
||||
Some(id) => id,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn assert_is_main_thread() {
|
||||
#[cold]
|
||||
fn not_main_thread() -> ! {
|
||||
panic!("Function is not running on the main thread!");
|
||||
}
|
||||
|
||||
if thread::current().id() != main_thread_id() {
|
||||
not_main_thread();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn assert_is_background_thread() {
|
||||
#[cold]
|
||||
fn not_background_thread() -> ! {
|
||||
panic!("Function is not allowed to be called on the main thread!");
|
||||
}
|
||||
|
||||
if thread::current().id() == main_thread_id() {
|
||||
not_background_thread();
|
||||
}
|
||||
}
|
||||
|
||||
/// The rusty version of `iothreads::make_detached_pthread()`. We will probably need a
|
||||
/// `spawn_scoped` version of the same to handle some more advanced borrow cases safely, and maybe
|
||||
|
||||
Reference in New Issue
Block a user