futures_glib/
rt.rs

1use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
2use std::cell::Cell;
3
4thread_local! {
5    static IS_MAIN_THREAD: Cell<bool> = Cell::new(false)
6}
7
8static INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT;
9
10/// Asserts that this is the main thread and `futures_glib::init` has been called.
11macro_rules! assert_initialized_main_thread {
12    () => (
13        if !::rt::is_initialized_main_thread() {
14            if ::rt::is_initialized() {
15                panic!("Glib may only be used from the main thread.");
16            }
17            else {
18                panic!("Glib has not been initialized. Call `futures_glib::init` first.");
19            }
20        }
21    )
22}
23
24/// No-op.
25macro_rules! skip_assert_initialized {
26    () => ()
27}
28
29/// Returns `true` if Glib has been initialized and this is the main thread.
30#[inline]
31pub fn is_initialized_main_thread() -> bool {
32    skip_assert_initialized!();
33    IS_MAIN_THREAD.with(|c| c.get())
34}
35
36/// Returns `true` if Glib has been initialized.
37#[inline]
38pub fn is_initialized() -> bool {
39    skip_assert_initialized!();
40    INITIALIZED.load(Ordering::Acquire)
41}
42
43/// Informs this crate that Glib has been initialized and the current thread is the main one.
44pub unsafe fn set_initialized() {
45    skip_assert_initialized!();
46    if is_initialized_main_thread() {
47        return;
48    }
49    else if is_initialized() {
50        panic!("Attempted to initialize Glib from two different threads.");
51    }
52    INITIALIZED.store(true, Ordering::Release);
53    IS_MAIN_THREAD.with(|c| c.set(true));
54}
55
56/// Tries to initialize Glib.
57pub fn init() {
58    skip_assert_initialized!();
59    if is_initialized_main_thread() {
60        return;
61    }
62    else if is_initialized() {
63        panic!("Attempted to initialize Glib from two different threads.");
64    }
65    unsafe {
66        set_initialized();
67    }
68}