Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,13 @@ static EXECUTOR_INSTALLED: atomic::AtomicBool = atomic::AtomicBool::new(false);

static ATFORK_INSTALLED: atomic::AtomicBool = atomic::AtomicBool::new(false);

pub fn rt() -> &'static mut BackgroundExecutor {
pub fn rt() -> &'static BackgroundExecutor {
loop {
let ptr = BACKGROUND_EXECUTOR.load(Ordering::SeqCst);
if !ptr.is_null() {
return unsafe { &mut *ptr };
// SAFETY: installed executors are leaked and remain valid for the
// process lifetime. BackgroundExecutor uses shared access only.
return unsafe { &*ptr };
}
if !EXECUTOR_INSTALLED.fetch_or(true, Ordering::SeqCst) {
break;
Expand All @@ -151,7 +153,8 @@ pub fn rt() -> &'static mut BackgroundExecutor {
}
let new_ptr = Box::into_raw(Box::new(create_background_executor()));
BACKGROUND_EXECUTOR.store(new_ptr, Ordering::SeqCst);
unsafe { &mut *new_ptr }
// SAFETY: the executor is leaked and all of its operations take `&self`.
unsafe { &*new_ptr }
}

/// After a fork() operation, force re-creation of the BackgroundExecutor. Note: this function
Expand Down Expand Up @@ -511,3 +514,15 @@ fn ffi_logical_codec_from_pycapsule(obj: Bound<PyAny>) -> PyResult<FFI_LogicalEx

Ok(codec.clone())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn background_executor_is_a_shared_singleton() {
let first: &'static BackgroundExecutor = rt();
let second: &'static BackgroundExecutor = rt();
assert!(std::ptr::eq(first, second));
}
}
Loading