Skip to content

Commit 4d3d3ee

Browse files
committed
Global main thread ID
1 parent cadfd16 commit 4d3d3ee

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

godot-core/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ fn main() {
1717
println!("cargo:rerun-if-changed=build.rs");
1818

1919
godot_bindings::emit_godot_version_cfg();
20+
godot_bindings::emit_wasm_nothreads_cfg();
2021
}

godot-core/src/init/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ pub unsafe fn __gdext_load_library<E: ExtensionLibrary>(
3434
Some(false) => sys::linux_reload_workaround::disable_hot_reload(),
3535
}
3636

37+
// We want to initialize the main thread ID as early as possible, but it has to happen after the hot-reload workaround.
38+
//
39+
// SAFETY: We set the main thread ID exactly once during library initialization and never again.
40+
#[cfg(not(wasm_nothreads))]
41+
unsafe {
42+
crate::meta::MAIN_THREAD_ID.set(std::thread::current().id())
43+
};
44+
3745
let tool_only_in_editor = match E::editor_run_behavior() {
3846
EditorRunBehavior::ToolClassesOnly => true,
3947
EditorRunBehavior::AllClasses => false,

godot-core/src/meta/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ pub use signature::trace;
8181
pub use method_info::MethodInfo;
8282
pub use property_info::{PropertyHintInfo, PropertyInfo};
8383

84+
#[cfg(not(wasm_nothreads))]
85+
pub(crate) static MAIN_THREAD_ID: crate::sys::ManualInitCell<std::thread::ThreadId> =
86+
crate::sys::ManualInitCell::new();
87+
88+
/// Get the [`ThreadId`](std::thread::ThreadId) of the main thread.
89+
#[cfg(not(wasm_nothreads))]
90+
pub fn main_thread_id() -> std::thread::ThreadId {
91+
// SAFETY: We initialized the cell during library initialization, before any other code is executed.
92+
let thread_id = unsafe { MAIN_THREAD_ID.get_unchecked() };
93+
94+
*thread_id
95+
}
96+
8497
// ----------------------------------------------------------------------------------------------------------------------------------------------
8598

8699
/// Clean up various resources at end of usage.

godot-ffi/src/toolbox.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ mod manual_init_cell {
439439
/// seems able to optimize `OnceLock` to equivalent code. But this guaranteed does not have any overhead at runtime.
440440
///
441441
/// This cell additionally allows to deinitialize the value. Access to uninitialized values is UB, but checked in Debug mode.
442-
pub(crate) struct ManualInitCell<T> {
442+
pub struct ManualInitCell<T> {
443443
// Invariant: Is `None` until initialized, and then never modified after (except, possibly, through interior mutability).
444444
cell: UnsafeCell<Option<T>>,
445445
}
@@ -529,9 +529,15 @@ mod manual_init_cell {
529529
unsafe impl<T: Send + Sync> Sync for ManualInitCell<T> {}
530530
// SAFETY: See `Sync` impl.
531531
unsafe impl<T: Send> Send for ManualInitCell<T> {}
532+
533+
impl<T> Default for ManualInitCell<T> {
534+
fn default() -> Self {
535+
Self::new()
536+
}
537+
}
532538
}
533539

534-
pub(crate) use manual_init_cell::ManualInitCell;
540+
pub use manual_init_cell::ManualInitCell;
535541

536542
// ----------------------------------------------------------------------------------------------------------------------------------------------
537543
// Unit tests

0 commit comments

Comments
 (0)