Skip to main content

gio/auto/
async_initable.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{AsyncResult, Cancellable, ffi};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10    /// init_finish = foo_init_finish;
11    /// }
12    /// ```text
13    ///
14    ///
15    /// # Implements
16    ///
17    /// [`AsyncInitableExt`][trait@crate::prelude::AsyncInitableExt]
18    #[doc(alias = "GAsyncInitable")]
19    pub struct AsyncInitable(Interface<ffi::GAsyncInitable, ffi::GAsyncInitableIface>);
20
21    match fn {
22        type_ => || ffi::g_async_initable_get_type(),
23    }
24}
25
26impl AsyncInitable {
27    pub const NONE: Option<&'static AsyncInitable> = None;
28}
29
30/// Trait containing all [`struct@AsyncInitable`] methods.
31///
32/// # Implementors
33///
34/// [`AsyncInitable`][struct@crate::AsyncInitable], [`DBusConnection`][struct@crate::DBusConnection], [`DBusObjectManagerClient`][struct@crate::DBusObjectManagerClient], [`DBusProxy`][struct@crate::DBusProxy]
35pub trait AsyncInitableExt: IsA<AsyncInitable> + 'static {
36    /// Starts asynchronous initialization of the object implementing the
37    /// interface. This must be done before any real use of the object after
38    /// initial construction. If the object also implements #GInitable you can
39    /// optionally call g_initable_init() instead.
40    ///
41    /// This method is intended for language bindings. If writing in C,
42    /// g_async_initable_new_async() should typically be used instead.
43    ///
44    /// When the initialization is finished, @callback will be called. You can
45    /// then call g_async_initable_init_finish() to get the result of the
46    /// initialization.
47    ///
48    /// Implementations may also support cancellation. If @cancellable is not
49    /// [`None`], then initialization can be cancelled by triggering the cancellable
50    /// object from another thread. If the operation was cancelled, the error
51    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned. If @cancellable is not [`None`], and
52    /// the object doesn't support cancellable initialization, the error
53    /// [`IOErrorEnum::NotSupported`][crate::IOErrorEnum::NotSupported] will be returned.
54    ///
55    /// As with #GInitable, if the object is not initialized, or initialization
56    /// returns with an error, then all operations on the object except
57    /// g_object_ref() and g_object_unref() are considered to be invalid, and
58    /// have undefined behaviour. They will often fail with g_critical() or
59    /// g_warning(), but this must not be relied on.
60    ///
61    /// Callers should not assume that a class which implements #GAsyncInitable can
62    /// be initialized multiple times; for more information, see g_initable_init().
63    /// If a class explicitly supports being initialized multiple times,
64    /// implementation requires yielding all subsequent calls to init_async() on the
65    /// results of the first call.
66    ///
67    /// For classes that also support the #GInitable interface, the default
68    /// implementation of this method will run the g_initable_init() function
69    /// in a thread, so if you want to support asynchronous initialization via
70    /// threads, just implement the #GAsyncInitable interface without overriding
71    /// any interface methods.
72    /// ## `io_priority`
73    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the operation
74    /// ## `cancellable`
75    /// optional #GCancellable object, [`None`] to ignore.
76    /// ## `callback`
77    /// a #GAsyncReadyCallback to call when the request is satisfied
78    #[doc(alias = "g_async_initable_init_async")]
79    unsafe fn init_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
80        &self,
81        io_priority: glib::Priority,
82        cancellable: Option<&impl IsA<Cancellable>>,
83        callback: P,
84    ) {
85        unsafe {
86            let main_context = glib::MainContext::ref_thread_default();
87            let is_main_context_owner = main_context.is_owner();
88            let has_acquired_main_context = (!is_main_context_owner)
89                .then(|| main_context.acquire().ok())
90                .flatten();
91            assert!(
92                is_main_context_owner || has_acquired_main_context.is_some(),
93                "Async operations only allowed if the thread is owning the MainContext"
94            );
95
96            let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
97                Box_::new(glib::thread_guard::ThreadGuard::new(callback));
98            unsafe extern "C" fn init_async_trampoline<
99                P: FnOnce(Result<(), glib::Error>) + 'static,
100            >(
101                _source_object: *mut glib::gobject_ffi::GObject,
102                res: *mut crate::ffi::GAsyncResult,
103                user_data: glib::ffi::gpointer,
104            ) {
105                unsafe {
106                    let mut error = std::ptr::null_mut();
107                    ffi::g_async_initable_init_finish(_source_object as *mut _, res, &mut error);
108                    let result = if error.is_null() {
109                        Ok(())
110                    } else {
111                        Err(from_glib_full(error))
112                    };
113                    let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
114                        Box_::from_raw(user_data as *mut _);
115                    let callback: P = callback.into_inner();
116                    callback(result);
117                }
118            }
119            let callback = init_async_trampoline::<P>;
120            ffi::g_async_initable_init_async(
121                self.as_ref().to_glib_none().0,
122                io_priority.into_glib(),
123                cancellable.map(|p| p.as_ref()).to_glib_none().0,
124                Some(callback),
125                Box_::into_raw(user_data) as *mut _,
126            );
127        }
128    }
129
130    unsafe fn init_future(
131        &self,
132        io_priority: glib::Priority,
133    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
134        Box_::pin(crate::GioFuture::new(
135            self,
136            move |obj, cancellable, send| unsafe {
137                obj.init_async(io_priority, Some(cancellable), move |res| {
138                    send.resolve(res);
139                });
140            },
141        ))
142    }
143}
144
145impl<O: IsA<AsyncInitable>> AsyncInitableExt for O {}