1 // Take a look at the license at the top of the repository in the LICENSE file. 2 3 //! General — Library initialization and miscellaneous functions 4 5 use std::cell::Cell; 6 use std::ptr; 7 use std::sync::atomic::{AtomicBool, Ordering}; 8 9 thread_local! { 10 static IS_MAIN_THREAD: Cell<bool> = Cell::new(false) 11 } 12 13 static INITIALIZED: AtomicBool = AtomicBool::new(false); 14 15 /// Asserts that this is the main thread and either `gdk::init` or `gtk::init` has been called. 16 macro_rules! assert_initialized_main_thread { 17 () => { 18 if !crate::rt::is_initialized_main_thread() { 19 if crate::rt::is_initialized() { 20 panic!("GDK may only be used from the main thread."); 21 } else { 22 panic!("GDK has not been initialized. Call `gdk::init` or `gtk::init` first."); 23 } 24 } 25 }; 26 } 27 28 /// No-op. 29 macro_rules! skip_assert_initialized { 30 () => {}; 31 } 32 33 /// Asserts that neither `gdk::init` nor `gtk::init` has been called. 34 macro_rules! assert_not_initialized { 35 () => { 36 if crate::rt::is_initialized() { 37 panic!("This function has to be called before `gdk::init` or `gtk::init`."); 38 } 39 }; 40 } 41 42 /// Returns `true` if GDK has been initialized. 43 #[inline] is_initialized() -> bool44pub fn is_initialized() -> bool { 45 skip_assert_initialized!(); 46 INITIALIZED.load(Ordering::Acquire) 47 } 48 49 /// Returns `true` if GDK has been initialized and this is the main thread. 50 #[inline] is_initialized_main_thread() -> bool51pub fn is_initialized_main_thread() -> bool { 52 skip_assert_initialized!(); 53 IS_MAIN_THREAD.with(|c| c.get()) 54 } 55 56 /// Informs this crate that GDK has been initialized and the current thread is the main one. set_initialized()57pub unsafe fn set_initialized() { 58 skip_assert_initialized!(); 59 if is_initialized_main_thread() { 60 return; 61 } else if is_initialized() { 62 panic!("Attempted to initialize GDK from two different threads."); 63 } 64 INITIALIZED.store(true, Ordering::Release); 65 IS_MAIN_THREAD.with(|c| c.set(true)); 66 } 67 68 #[doc(alias = "gdk_init")] init()69pub fn init() { 70 assert_not_initialized!(); 71 unsafe { 72 ffi::gdk_init(ptr::null_mut(), ptr::null_mut()); 73 set_initialized(); 74 } 75 } 76