gio/auto/
dbus_connection.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#![allow(deprecated)]
5
6#[cfg(unix)]
7#[cfg_attr(docsrs, doc(cfg(unix)))]
8use crate::UnixFDList;
9use crate::{
10    AsyncInitable, AsyncResult, Cancellable, Credentials, DBusAuthObserver, DBusCallFlags,
11    DBusCapabilityFlags, DBusConnectionFlags, DBusMessage, DBusSendMessageFlags, IOStream,
12    Initable, ffi,
13};
14use glib::{
15    object::ObjectType as _,
16    prelude::*,
17    signal::{SignalHandlerId, connect_raw},
18    translate::*,
19};
20use std::{boxed::Box as Box_, pin::Pin};
21
22glib::wrapper! {
23    /// The `GDBusConnection` type is used for D-Bus connections to remote
24    /// peers such as a message buses.
25    ///
26    /// It is a low-level API that offers a lot of flexibility. For instance,
27    /// it lets you establish a connection over any transport that can by represented
28    /// as a [`IOStream`][crate::IOStream].
29    ///
30    /// This class is rarely used directly in D-Bus clients. If you are writing
31    /// a D-Bus client, it is often easier to use the `bus_own_name()`,
32    /// `bus_watch_name()` or [`DBusProxy::for_bus()`][crate::DBusProxy::for_bus()] APIs.
33    ///
34    /// As an exception to the usual GLib rule that a particular object must not
35    /// be used by two threads at the same time, `GDBusConnection`s methods may be
36    /// called from any thread. This is so that [`bus_get()`][crate::bus_get()] and
37    /// [`bus_get_sync()`][crate::bus_get_sync()] can safely return the same `GDBusConnection` when
38    /// called from any thread.
39    ///
40    /// Most of the ways to obtain a `GDBusConnection` automatically initialize it
41    /// (i.e. connect to D-Bus): for instance, [`new()`][Self::new()] and
42    /// [`bus_get()`][crate::bus_get()], and the synchronous versions of those methods, give you
43    /// an initialized connection. Language bindings for GIO should use
44    /// [`Initable::new()`][crate::Initable::new()] or [`AsyncInitable::new_async()`][crate::AsyncInitable::new_async()], which also
45    /// initialize the connection.
46    ///
47    /// If you construct an uninitialized `GDBusConnection`, such as via
48    /// [`glib::Object::new()`][crate::glib::Object::new()], you must initialize it via [`InitableExt::init()`][crate::prelude::InitableExt::init()] or
49    /// [`AsyncInitableExt::init_async()`][crate::prelude::AsyncInitableExt::init_async()] before using its methods or properties.
50    /// Calling methods or accessing properties on a `GDBusConnection` that has not
51    /// completed initialization successfully is considered to be invalid, and leads
52    /// to undefined behaviour. In particular, if initialization fails with a
53    /// `GError`, the only valid thing you can do with that `GDBusConnection` is to
54    /// free it with `GObject::Object::unref()`.
55    ///
56    /// ## An example D-Bus server
57    ///
58    /// Here is an example for a D-Bus server:
59    /// [gdbus-example-server.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-server.c)
60    ///
61    /// ## An example for exporting a subtree
62    ///
63    /// Here is an example for exporting a subtree:
64    /// [gdbus-example-subtree.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-subtree.c)
65    ///
66    /// ## An example for file descriptor passing
67    ///
68    /// Here is an example for passing UNIX file descriptors:
69    /// [gdbus-unix-fd-client.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-unix-fd-client.c)
70    ///
71    /// ## An example for exporting a GObject
72    ///
73    /// Here is an example for exporting a #GObject:
74    /// [gdbus-example-export.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-export.c)
75    ///
76    /// ## Properties
77    ///
78    ///
79    /// #### `address`
80    ///  A D-Bus address specifying potential endpoints that can be used
81    /// when establishing the connection.
82    ///
83    /// Writeable | Construct Only
84    ///
85    ///
86    /// #### `authentication-observer`
87    ///  A #GDBusAuthObserver object to assist in the authentication process or [`None`].
88    ///
89    /// Writeable | Construct Only
90    ///
91    ///
92    /// #### `capabilities`
93    ///  Flags from the #GDBusCapabilityFlags enumeration
94    /// representing connection features negotiated with the other peer.
95    ///
96    /// Readable
97    ///
98    ///
99    /// #### `closed`
100    ///  A boolean specifying whether the connection has been closed.
101    ///
102    /// Readable
103    ///
104    ///
105    /// #### `exit-on-close`
106    ///  A boolean specifying whether the process will be terminated (by
107    /// calling `raise(SIGTERM)`) if the connection is closed by the
108    /// remote peer.
109    ///
110    /// Note that #GDBusConnection objects returned by g_bus_get_finish()
111    /// and g_bus_get_sync() will (usually) have this property set to [`true`].
112    ///
113    /// Readable | Writeable
114    ///
115    ///
116    /// #### `flags`
117    ///  Flags from the #GDBusConnectionFlags enumeration.
118    ///
119    /// Readable | Writeable | Construct Only
120    ///
121    ///
122    /// #### `guid`
123    ///  The GUID of the peer performing the role of server when
124    /// authenticating.
125    ///
126    /// If you are constructing a #GDBusConnection and pass
127    /// [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER] in the
128    /// #GDBusConnection:flags property then you **must** also set this
129    /// property to a valid guid.
130    ///
131    /// If you are constructing a #GDBusConnection and pass
132    /// [`DBusConnectionFlags::AUTHENTICATION_CLIENT`][crate::DBusConnectionFlags::AUTHENTICATION_CLIENT] in the
133    /// #GDBusConnection:flags property you will be able to read the GUID
134    /// of the other peer here after the connection has been successfully
135    /// initialized.
136    ///
137    /// Note that the
138    /// [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses)
139    /// uses the term ‘UUID’ to refer to this, whereas GLib consistently uses the
140    /// term ‘GUID’ for historical reasons.
141    ///
142    /// Despite its name, the format of #GDBusConnection:guid does not follow
143    /// [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) or the Microsoft
144    /// GUID format.
145    ///
146    /// Readable | Writeable | Construct Only
147    ///
148    ///
149    /// #### `stream`
150    ///  The underlying #GIOStream used for I/O.
151    ///
152    /// If this is passed on construction and is a #GSocketConnection,
153    /// then the corresponding #GSocket will be put into non-blocking mode.
154    ///
155    /// While the #GDBusConnection is active, it will interact with this
156    /// stream from a worker thread, so it is not safe to interact with
157    /// the stream directly.
158    ///
159    /// Readable | Writeable | Construct Only
160    ///
161    ///
162    /// #### `unique-name`
163    ///  The unique name as assigned by the message bus or [`None`] if the
164    /// connection is not open or not a message bus connection.
165    ///
166    /// Readable
167    ///
168    /// ## Signals
169    ///
170    ///
171    /// #### `closed`
172    ///  Emitted when the connection is closed.
173    ///
174    /// The cause of this event can be
175    ///
176    /// - If g_dbus_connection_close() is called. In this case
177    ///   @remote_peer_vanished is set to [`false`] and @error is [`None`].
178    ///
179    /// - If the remote peer closes the connection. In this case
180    ///   @remote_peer_vanished is set to [`true`] and @error is set.
181    ///
182    /// - If the remote peer sends invalid or malformed data. In this
183    ///   case @remote_peer_vanished is set to [`false`] and @error is set.
184    ///
185    /// Upon receiving this signal, you should give up your reference to
186    /// @connection. You are guaranteed that this signal is emitted only
187    /// once.
188    ///
189    ///
190    ///
191    /// # Implements
192    ///
193    /// [`trait@glib::ObjectExt`], [`AsyncInitableExt`][trait@crate::prelude::AsyncInitableExt], [`InitableExt`][trait@crate::prelude::InitableExt]
194    #[doc(alias = "GDBusConnection")]
195    pub struct DBusConnection(Object<ffi::GDBusConnection>) @implements AsyncInitable, Initable;
196
197    match fn {
198        type_ => || ffi::g_dbus_connection_get_type(),
199    }
200}
201
202impl DBusConnection {
203    /// Synchronously connects and sets up a D-Bus client connection for
204    /// exchanging D-Bus messages with an endpoint specified by @address
205    /// which must be in the
206    /// [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses).
207    ///
208    /// This constructor can only be used to initiate client-side
209    /// connections - use g_dbus_connection_new_sync() if you need to act
210    /// as the server. In particular, @flags cannot contain the
211    /// [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER],
212    /// [`DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS`][crate::DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS] or
213    /// [`DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER`][crate::DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER] flags.
214    ///
215    /// This is a synchronous failable constructor. See
216    /// g_dbus_connection_new_for_address() for the asynchronous version.
217    ///
218    /// If @observer is not [`None`] it may be used to control the
219    /// authentication process.
220    /// ## `address`
221    /// a D-Bus address
222    /// ## `flags`
223    /// flags describing how to make the connection
224    /// ## `observer`
225    /// a #GDBusAuthObserver or [`None`]
226    /// ## `cancellable`
227    /// a #GCancellable or [`None`]
228    ///
229    /// # Returns
230    ///
231    /// a #GDBusConnection or [`None`] if @error is set.
232    ///     Free with g_object_unref().
233    #[doc(alias = "g_dbus_connection_new_for_address_sync")]
234    #[doc(alias = "new_for_address_sync")]
235    pub fn for_address_sync(
236        address: &str,
237        flags: DBusConnectionFlags,
238        observer: Option<&DBusAuthObserver>,
239        cancellable: Option<&impl IsA<Cancellable>>,
240    ) -> Result<DBusConnection, glib::Error> {
241        unsafe {
242            let mut error = std::ptr::null_mut();
243            let ret = ffi::g_dbus_connection_new_for_address_sync(
244                address.to_glib_none().0,
245                flags.into_glib(),
246                observer.to_glib_none().0,
247                cancellable.map(|p| p.as_ref()).to_glib_none().0,
248                &mut error,
249            );
250            if error.is_null() {
251                Ok(from_glib_full(ret))
252            } else {
253                Err(from_glib_full(error))
254            }
255        }
256    }
257
258    /// Synchronously sets up a D-Bus connection for exchanging D-Bus messages
259    /// with the end represented by @stream.
260    ///
261    /// If @stream is a #GSocketConnection, then the corresponding #GSocket
262    /// will be put into non-blocking mode.
263    ///
264    /// The D-Bus connection will interact with @stream from a worker thread.
265    /// As a result, the caller should not interact with @stream after this
266    /// method has been called, except by calling g_object_unref() on it.
267    ///
268    /// If @observer is not [`None`] it may be used to control the
269    /// authentication process.
270    ///
271    /// This is a synchronous failable constructor. See
272    /// g_dbus_connection_new() for the asynchronous version.
273    /// ## `stream`
274    /// a #GIOStream
275    /// ## `guid`
276    /// the GUID to use if authenticating as a server or [`None`]
277    /// ## `flags`
278    /// flags describing how to make the connection
279    /// ## `observer`
280    /// a #GDBusAuthObserver or [`None`]
281    /// ## `cancellable`
282    /// a #GCancellable or [`None`]
283    ///
284    /// # Returns
285    ///
286    /// a #GDBusConnection or [`None`] if @error is set.
287    ///     Free with g_object_unref().
288    #[doc(alias = "g_dbus_connection_new_sync")]
289    pub fn new_sync(
290        stream: &impl IsA<IOStream>,
291        guid: Option<&str>,
292        flags: DBusConnectionFlags,
293        observer: Option<&DBusAuthObserver>,
294        cancellable: Option<&impl IsA<Cancellable>>,
295    ) -> Result<DBusConnection, glib::Error> {
296        unsafe {
297            let mut error = std::ptr::null_mut();
298            let ret = ffi::g_dbus_connection_new_sync(
299                stream.as_ref().to_glib_none().0,
300                guid.to_glib_none().0,
301                flags.into_glib(),
302                observer.to_glib_none().0,
303                cancellable.map(|p| p.as_ref()).to_glib_none().0,
304                &mut error,
305            );
306            if error.is_null() {
307                Ok(from_glib_full(ret))
308            } else {
309                Err(from_glib_full(error))
310            }
311        }
312    }
313
314    /// Asynchronously invokes the @method_name method on the
315    /// @interface_name D-Bus interface on the remote object at
316    /// @object_path owned by @bus_name.
317    ///
318    /// If @self is closed then the operation will fail with
319    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the operation will
320    /// fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @parameters contains a value
321    /// not compatible with the D-Bus protocol, the operation fails with
322    /// [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
323    ///
324    /// If @reply_type is non-[`None`] then the reply will be checked for having this type and an
325    /// error will be raised if it does not match.  Said another way, if you give a @reply_type
326    /// then any non-[`None`] return value will be of this type. Unless it’s
327    /// `G_VARIANT_TYPE_UNIT`, the @reply_type will be a tuple containing one or more
328    /// values.
329    ///
330    /// If the @parameters #GVariant is floating, it is consumed. This allows
331    /// convenient 'inline' use of g_variant_new(), e.g.:
332    ///
333    ///
334    /// **⚠️ The following code is in C ⚠️**
335    ///
336    /// ```C
337    ///  g_dbus_connection_call (connection,
338    ///                          "org.freedesktop.StringThings",
339    ///                          "/org/freedesktop/StringThings",
340    ///                          "org.freedesktop.StringThings",
341    ///                          "TwoStrings",
342    ///                          g_variant_new ("(ss)",
343    ///                                         "Thing One",
344    ///                                         "Thing Two"),
345    ///                          NULL,
346    ///                          G_DBUS_CALL_FLAGS_NONE,
347    ///                          -1,
348    ///                          NULL,
349    ///                          (GAsyncReadyCallback) two_strings_done,
350    ///                          NULL);
351    /// ```
352    ///
353    /// This is an asynchronous method. When the operation is finished,
354    /// @callback will be invoked in the thread-default main context
355    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
356    /// of the thread you are calling this method from. You can then call
357    /// g_dbus_connection_call_finish() to get the result of the operation.
358    /// See g_dbus_connection_call_sync() for the synchronous version of this
359    /// function.
360    ///
361    /// If @callback is [`None`] then the D-Bus method call message will be sent with
362    /// the [`DBusMessageFlags::NO_REPLY_EXPECTED`][crate::DBusMessageFlags::NO_REPLY_EXPECTED] flag set.
363    /// ## `bus_name`
364    /// a unique or well-known bus name or [`None`] if
365    ///     @self is not a message bus connection
366    /// ## `object_path`
367    /// path of remote object
368    /// ## `interface_name`
369    /// D-Bus interface to invoke method on
370    /// ## `method_name`
371    /// the name of the method to invoke
372    /// ## `parameters`
373    /// a #GVariant tuple with parameters for the method
374    ///     or [`None`] if not passing parameters
375    /// ## `reply_type`
376    /// the expected type of the reply (which will be a
377    ///     tuple), or [`None`]
378    /// ## `flags`
379    /// flags from the #GDBusCallFlags enumeration
380    /// ## `timeout_msec`
381    /// the timeout in milliseconds, -1 to use the default
382    ///     timeout or `G_MAXINT` for no timeout
383    /// ## `cancellable`
384    /// a #GCancellable or [`None`]
385    /// ## `callback`
386    /// a #GAsyncReadyCallback to call when the request
387    ///     is satisfied or [`None`] if you don't care about the result of the
388    ///     method invocation
389    #[doc(alias = "g_dbus_connection_call")]
390    pub fn call<P: FnOnce(Result<glib::Variant, glib::Error>) + 'static>(
391        &self,
392        bus_name: Option<&str>,
393        object_path: &str,
394        interface_name: &str,
395        method_name: &str,
396        parameters: Option<&glib::Variant>,
397        reply_type: Option<&glib::VariantTy>,
398        flags: DBusCallFlags,
399        timeout_msec: i32,
400        cancellable: Option<&impl IsA<Cancellable>>,
401        callback: P,
402    ) {
403        let main_context = glib::MainContext::ref_thread_default();
404        let is_main_context_owner = main_context.is_owner();
405        let has_acquired_main_context = (!is_main_context_owner)
406            .then(|| main_context.acquire().ok())
407            .flatten();
408        assert!(
409            is_main_context_owner || has_acquired_main_context.is_some(),
410            "Async operations only allowed if the thread is owning the MainContext"
411        );
412
413        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
414            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
415        unsafe extern "C" fn call_trampoline<
416            P: FnOnce(Result<glib::Variant, glib::Error>) + 'static,
417        >(
418            _source_object: *mut glib::gobject_ffi::GObject,
419            res: *mut crate::ffi::GAsyncResult,
420            user_data: glib::ffi::gpointer,
421        ) {
422            unsafe {
423                let mut error = std::ptr::null_mut();
424                let ret =
425                    ffi::g_dbus_connection_call_finish(_source_object as *mut _, res, &mut error);
426                let result = if error.is_null() {
427                    Ok(from_glib_full(ret))
428                } else {
429                    Err(from_glib_full(error))
430                };
431                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
432                    Box_::from_raw(user_data as *mut _);
433                let callback: P = callback.into_inner();
434                callback(result);
435            }
436        }
437        let callback = call_trampoline::<P>;
438        unsafe {
439            ffi::g_dbus_connection_call(
440                self.to_glib_none().0,
441                bus_name.to_glib_none().0,
442                object_path.to_glib_none().0,
443                interface_name.to_glib_none().0,
444                method_name.to_glib_none().0,
445                parameters.to_glib_none().0,
446                reply_type.to_glib_none().0,
447                flags.into_glib(),
448                timeout_msec,
449                cancellable.map(|p| p.as_ref()).to_glib_none().0,
450                Some(callback),
451                Box_::into_raw(user_data) as *mut _,
452            );
453        }
454    }
455
456    pub fn call_future(
457        &self,
458        bus_name: Option<&str>,
459        object_path: &str,
460        interface_name: &str,
461        method_name: &str,
462        parameters: Option<&glib::Variant>,
463        reply_type: Option<&glib::VariantTy>,
464        flags: DBusCallFlags,
465        timeout_msec: i32,
466    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Variant, glib::Error>> + 'static>>
467    {
468        let bus_name = bus_name.map(ToOwned::to_owned);
469        let object_path = String::from(object_path);
470        let interface_name = String::from(interface_name);
471        let method_name = String::from(method_name);
472        let parameters = parameters.map(ToOwned::to_owned);
473        let reply_type = reply_type.map(ToOwned::to_owned);
474        Box_::pin(crate::GioFuture::new(
475            self,
476            move |obj, cancellable, send| {
477                obj.call(
478                    bus_name.as_ref().map(::std::borrow::Borrow::borrow),
479                    &object_path,
480                    &interface_name,
481                    &method_name,
482                    parameters.as_ref().map(::std::borrow::Borrow::borrow),
483                    reply_type.as_ref().map(::std::borrow::Borrow::borrow),
484                    flags,
485                    timeout_msec,
486                    Some(cancellable),
487                    move |res| {
488                        send.resolve(res);
489                    },
490                );
491            },
492        ))
493    }
494
495    /// Synchronously invokes the @method_name method on the
496    /// @interface_name D-Bus interface on the remote object at
497    /// @object_path owned by @bus_name.
498    ///
499    /// If @self is closed then the operation will fail with
500    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the
501    /// operation will fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @parameters
502    /// contains a value not compatible with the D-Bus protocol, the operation
503    /// fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
504    ///
505    /// If @reply_type is non-[`None`] then the reply will be checked for having
506    /// this type and an error will be raised if it does not match.  Said
507    /// another way, if you give a @reply_type then any non-[`None`] return
508    /// value will be of this type.
509    ///
510    /// If the @parameters #GVariant is floating, it is consumed.
511    /// This allows convenient 'inline' use of g_variant_new(), e.g.:
512    ///
513    ///
514    /// **⚠️ The following code is in C ⚠️**
515    ///
516    /// ```C
517    ///  g_dbus_connection_call_sync (connection,
518    ///                               "org.freedesktop.StringThings",
519    ///                               "/org/freedesktop/StringThings",
520    ///                               "org.freedesktop.StringThings",
521    ///                               "TwoStrings",
522    ///                               g_variant_new ("(ss)",
523    ///                                              "Thing One",
524    ///                                              "Thing Two"),
525    ///                               NULL,
526    ///                               G_DBUS_CALL_FLAGS_NONE,
527    ///                               -1,
528    ///                               NULL,
529    ///                               &error);
530    /// ```
531    ///
532    /// The calling thread is blocked until a reply is received. See
533    /// g_dbus_connection_call() for the asynchronous version of
534    /// this method.
535    /// ## `bus_name`
536    /// a unique or well-known bus name or [`None`] if
537    ///     @self is not a message bus connection
538    /// ## `object_path`
539    /// path of remote object
540    /// ## `interface_name`
541    /// D-Bus interface to invoke method on
542    /// ## `method_name`
543    /// the name of the method to invoke
544    /// ## `parameters`
545    /// a #GVariant tuple with parameters for the method
546    ///     or [`None`] if not passing parameters
547    /// ## `reply_type`
548    /// the expected type of the reply, or [`None`]
549    /// ## `flags`
550    /// flags from the #GDBusCallFlags enumeration
551    /// ## `timeout_msec`
552    /// the timeout in milliseconds, -1 to use the default
553    ///     timeout or `G_MAXINT` for no timeout
554    /// ## `cancellable`
555    /// a #GCancellable or [`None`]
556    ///
557    /// # Returns
558    ///
559    /// [`None`] if @error is set. Otherwise a non-floating
560    ///     #GVariant tuple with return values. Free with g_variant_unref().
561    #[doc(alias = "g_dbus_connection_call_sync")]
562    pub fn call_sync(
563        &self,
564        bus_name: Option<&str>,
565        object_path: &str,
566        interface_name: &str,
567        method_name: &str,
568        parameters: Option<&glib::Variant>,
569        reply_type: Option<&glib::VariantTy>,
570        flags: DBusCallFlags,
571        timeout_msec: i32,
572        cancellable: Option<&impl IsA<Cancellable>>,
573    ) -> Result<glib::Variant, glib::Error> {
574        unsafe {
575            let mut error = std::ptr::null_mut();
576            let ret = ffi::g_dbus_connection_call_sync(
577                self.to_glib_none().0,
578                bus_name.to_glib_none().0,
579                object_path.to_glib_none().0,
580                interface_name.to_glib_none().0,
581                method_name.to_glib_none().0,
582                parameters.to_glib_none().0,
583                reply_type.to_glib_none().0,
584                flags.into_glib(),
585                timeout_msec,
586                cancellable.map(|p| p.as_ref()).to_glib_none().0,
587                &mut error,
588            );
589            if error.is_null() {
590                Ok(from_glib_full(ret))
591            } else {
592                Err(from_glib_full(error))
593            }
594        }
595    }
596
597    /// Like g_dbus_connection_call() but also takes a #GUnixFDList object.
598    ///
599    /// The file descriptors normally correspond to `G_VARIANT_TYPE_HANDLE`
600    /// values in the body of the message. For example, if a message contains
601    /// two file descriptors, @fd_list would have length 2, and
602    /// `g_variant_new_handle (0)` and `g_variant_new_handle (1)` would appear
603    /// somewhere in the body of the message (not necessarily in that order!)
604    /// to represent the file descriptors at indexes 0 and 1 respectively.
605    ///
606    /// When designing D-Bus APIs that are intended to be interoperable,
607    /// please note that non-GDBus implementations of D-Bus can usually only
608    /// access file descriptors if they are referenced in this way by a
609    /// value of type `G_VARIANT_TYPE_HANDLE` in the body of the message.
610    ///
611    /// This method is only available on UNIX.
612    /// ## `bus_name`
613    /// a unique or well-known bus name or [`None`] if
614    ///     @self is not a message bus connection
615    /// ## `object_path`
616    /// path of remote object
617    /// ## `interface_name`
618    /// D-Bus interface to invoke method on
619    /// ## `method_name`
620    /// the name of the method to invoke
621    /// ## `parameters`
622    /// a #GVariant tuple with parameters for the method
623    ///     or [`None`] if not passing parameters
624    /// ## `reply_type`
625    /// the expected type of the reply, or [`None`]
626    /// ## `flags`
627    /// flags from the #GDBusCallFlags enumeration
628    /// ## `timeout_msec`
629    /// the timeout in milliseconds, -1 to use the default
630    ///     timeout or `G_MAXINT` for no timeout
631    /// ## `fd_list`
632    /// a #GUnixFDList or [`None`]
633    /// ## `cancellable`
634    /// a #GCancellable or [`None`]
635    /// ## `callback`
636    /// a #GAsyncReadyCallback to call when the request is
637    ///     satisfied or [`None`] if you don't * care about the result of the
638    ///     method invocation
639    #[cfg(unix)]
640    #[cfg_attr(docsrs, doc(cfg(unix)))]
641    #[doc(alias = "g_dbus_connection_call_with_unix_fd_list")]
642    pub fn call_with_unix_fd_list<
643        P: FnOnce(Result<(glib::Variant, Option<UnixFDList>), glib::Error>) + 'static,
644    >(
645        &self,
646        bus_name: Option<&str>,
647        object_path: &str,
648        interface_name: &str,
649        method_name: &str,
650        parameters: Option<&glib::Variant>,
651        reply_type: Option<&glib::VariantTy>,
652        flags: DBusCallFlags,
653        timeout_msec: i32,
654        fd_list: Option<&impl IsA<UnixFDList>>,
655        cancellable: Option<&impl IsA<Cancellable>>,
656        callback: P,
657    ) {
658        let main_context = glib::MainContext::ref_thread_default();
659        let is_main_context_owner = main_context.is_owner();
660        let has_acquired_main_context = (!is_main_context_owner)
661            .then(|| main_context.acquire().ok())
662            .flatten();
663        assert!(
664            is_main_context_owner || has_acquired_main_context.is_some(),
665            "Async operations only allowed if the thread is owning the MainContext"
666        );
667
668        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
669            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
670        unsafe extern "C" fn call_with_unix_fd_list_trampoline<
671            P: FnOnce(Result<(glib::Variant, Option<UnixFDList>), glib::Error>) + 'static,
672        >(
673            _source_object: *mut glib::gobject_ffi::GObject,
674            res: *mut crate::ffi::GAsyncResult,
675            user_data: glib::ffi::gpointer,
676        ) {
677            unsafe {
678                let mut error = std::ptr::null_mut();
679                let mut out_fd_list = std::ptr::null_mut();
680                let ret = ffi::g_dbus_connection_call_with_unix_fd_list_finish(
681                    _source_object as *mut _,
682                    &mut out_fd_list,
683                    res,
684                    &mut error,
685                );
686                let result = if error.is_null() {
687                    Ok((from_glib_full(ret), from_glib_full(out_fd_list)))
688                } else {
689                    Err(from_glib_full(error))
690                };
691                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
692                    Box_::from_raw(user_data as *mut _);
693                let callback: P = callback.into_inner();
694                callback(result);
695            }
696        }
697        let callback = call_with_unix_fd_list_trampoline::<P>;
698        unsafe {
699            ffi::g_dbus_connection_call_with_unix_fd_list(
700                self.to_glib_none().0,
701                bus_name.to_glib_none().0,
702                object_path.to_glib_none().0,
703                interface_name.to_glib_none().0,
704                method_name.to_glib_none().0,
705                parameters.to_glib_none().0,
706                reply_type.to_glib_none().0,
707                flags.into_glib(),
708                timeout_msec,
709                fd_list.map(|p| p.as_ref()).to_glib_none().0,
710                cancellable.map(|p| p.as_ref()).to_glib_none().0,
711                Some(callback),
712                Box_::into_raw(user_data) as *mut _,
713            );
714        }
715    }
716
717    #[cfg(unix)]
718    #[cfg_attr(docsrs, doc(cfg(unix)))]
719    pub fn call_with_unix_fd_list_future(
720        &self,
721        bus_name: Option<&str>,
722        object_path: &str,
723        interface_name: &str,
724        method_name: &str,
725        parameters: Option<&glib::Variant>,
726        reply_type: Option<&glib::VariantTy>,
727        flags: DBusCallFlags,
728        timeout_msec: i32,
729        fd_list: Option<&(impl IsA<UnixFDList> + Clone + 'static)>,
730    ) -> Pin<
731        Box_<
732            dyn std::future::Future<
733                    Output = Result<(glib::Variant, Option<UnixFDList>), glib::Error>,
734                > + 'static,
735        >,
736    > {
737        let bus_name = bus_name.map(ToOwned::to_owned);
738        let object_path = String::from(object_path);
739        let interface_name = String::from(interface_name);
740        let method_name = String::from(method_name);
741        let parameters = parameters.map(ToOwned::to_owned);
742        let reply_type = reply_type.map(ToOwned::to_owned);
743        let fd_list = fd_list.map(ToOwned::to_owned);
744        Box_::pin(crate::GioFuture::new(
745            self,
746            move |obj, cancellable, send| {
747                obj.call_with_unix_fd_list(
748                    bus_name.as_ref().map(::std::borrow::Borrow::borrow),
749                    &object_path,
750                    &interface_name,
751                    &method_name,
752                    parameters.as_ref().map(::std::borrow::Borrow::borrow),
753                    reply_type.as_ref().map(::std::borrow::Borrow::borrow),
754                    flags,
755                    timeout_msec,
756                    fd_list.as_ref().map(::std::borrow::Borrow::borrow),
757                    Some(cancellable),
758                    move |res| {
759                        send.resolve(res);
760                    },
761                );
762            },
763        ))
764    }
765
766    /// Like g_dbus_connection_call_sync() but also takes and returns #GUnixFDList objects.
767    /// See g_dbus_connection_call_with_unix_fd_list() and
768    /// g_dbus_connection_call_with_unix_fd_list_finish() for more details.
769    ///
770    /// This method is only available on UNIX.
771    /// ## `bus_name`
772    /// a unique or well-known bus name or [`None`]
773    ///     if @self is not a message bus connection
774    /// ## `object_path`
775    /// path of remote object
776    /// ## `interface_name`
777    /// D-Bus interface to invoke method on
778    /// ## `method_name`
779    /// the name of the method to invoke
780    /// ## `parameters`
781    /// a #GVariant tuple with parameters for
782    ///     the method or [`None`] if not passing parameters
783    /// ## `reply_type`
784    /// the expected type of the reply, or [`None`]
785    /// ## `flags`
786    /// flags from the #GDBusCallFlags enumeration
787    /// ## `timeout_msec`
788    /// the timeout in milliseconds, -1 to use the default
789    ///     timeout or `G_MAXINT` for no timeout
790    /// ## `fd_list`
791    /// a #GUnixFDList or [`None`]
792    /// ## `cancellable`
793    /// a #GCancellable or [`None`]
794    ///
795    /// # Returns
796    ///
797    /// [`None`] if @error is set. Otherwise a non-floating
798    ///     #GVariant tuple with return values. Free with g_variant_unref().
799    ///
800    /// ## `out_fd_list`
801    /// return location for a #GUnixFDList or [`None`]
802    #[cfg(unix)]
803    #[cfg_attr(docsrs, doc(cfg(unix)))]
804    #[doc(alias = "g_dbus_connection_call_with_unix_fd_list_sync")]
805    pub fn call_with_unix_fd_list_sync(
806        &self,
807        bus_name: Option<&str>,
808        object_path: &str,
809        interface_name: &str,
810        method_name: &str,
811        parameters: Option<&glib::Variant>,
812        reply_type: Option<&glib::VariantTy>,
813        flags: DBusCallFlags,
814        timeout_msec: i32,
815        fd_list: Option<&impl IsA<UnixFDList>>,
816        cancellable: Option<&impl IsA<Cancellable>>,
817    ) -> Result<(glib::Variant, Option<UnixFDList>), glib::Error> {
818        unsafe {
819            let mut out_fd_list = std::ptr::null_mut();
820            let mut error = std::ptr::null_mut();
821            let ret = ffi::g_dbus_connection_call_with_unix_fd_list_sync(
822                self.to_glib_none().0,
823                bus_name.to_glib_none().0,
824                object_path.to_glib_none().0,
825                interface_name.to_glib_none().0,
826                method_name.to_glib_none().0,
827                parameters.to_glib_none().0,
828                reply_type.to_glib_none().0,
829                flags.into_glib(),
830                timeout_msec,
831                fd_list.map(|p| p.as_ref()).to_glib_none().0,
832                &mut out_fd_list,
833                cancellable.map(|p| p.as_ref()).to_glib_none().0,
834                &mut error,
835            );
836            if error.is_null() {
837                Ok((from_glib_full(ret), from_glib_full(out_fd_list)))
838            } else {
839                Err(from_glib_full(error))
840            }
841        }
842    }
843
844    /// Closes @self. Note that this never causes the process to
845    /// exit (this might only happen if the other end of a shared message
846    /// bus connection disconnects, see #GDBusConnection:exit-on-close).
847    ///
848    /// Once the connection is closed, operations such as sending a message
849    /// will return with the error [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. Closing a connection
850    /// will not automatically flush the connection so queued messages may
851    /// be lost. Use g_dbus_connection_flush() if you need such guarantees.
852    ///
853    /// If @self is already closed, this method fails with
854    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
855    ///
856    /// When @self has been closed, the #GDBusConnection::closed
857    /// signal is emitted in the thread-default main context
858    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
859    /// of the thread that @self was constructed in.
860    ///
861    /// This is an asynchronous method. When the operation is finished,
862    /// @callback will be invoked in the thread-default main context
863    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
864    /// of the thread you are calling this method from. You can
865    /// then call g_dbus_connection_close_finish() to get the result of the
866    /// operation. See g_dbus_connection_close_sync() for the synchronous
867    /// version.
868    /// ## `cancellable`
869    /// a #GCancellable or [`None`]
870    /// ## `callback`
871    /// a #GAsyncReadyCallback to call when the request is
872    ///     satisfied or [`None`] if you don't care about the result
873    #[doc(alias = "g_dbus_connection_close")]
874    pub fn close<P: FnOnce(Result<(), glib::Error>) + 'static>(
875        &self,
876        cancellable: Option<&impl IsA<Cancellable>>,
877        callback: P,
878    ) {
879        let main_context = glib::MainContext::ref_thread_default();
880        let is_main_context_owner = main_context.is_owner();
881        let has_acquired_main_context = (!is_main_context_owner)
882            .then(|| main_context.acquire().ok())
883            .flatten();
884        assert!(
885            is_main_context_owner || has_acquired_main_context.is_some(),
886            "Async operations only allowed if the thread is owning the MainContext"
887        );
888
889        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
890            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
891        unsafe extern "C" fn close_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
892            _source_object: *mut glib::gobject_ffi::GObject,
893            res: *mut crate::ffi::GAsyncResult,
894            user_data: glib::ffi::gpointer,
895        ) {
896            unsafe {
897                let mut error = std::ptr::null_mut();
898                ffi::g_dbus_connection_close_finish(_source_object as *mut _, res, &mut error);
899                let result = if error.is_null() {
900                    Ok(())
901                } else {
902                    Err(from_glib_full(error))
903                };
904                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
905                    Box_::from_raw(user_data as *mut _);
906                let callback: P = callback.into_inner();
907                callback(result);
908            }
909        }
910        let callback = close_trampoline::<P>;
911        unsafe {
912            ffi::g_dbus_connection_close(
913                self.to_glib_none().0,
914                cancellable.map(|p| p.as_ref()).to_glib_none().0,
915                Some(callback),
916                Box_::into_raw(user_data) as *mut _,
917            );
918        }
919    }
920
921    pub fn close_future(
922        &self,
923    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
924        Box_::pin(crate::GioFuture::new(
925            self,
926            move |obj, cancellable, send| {
927                obj.close(Some(cancellable), move |res| {
928                    send.resolve(res);
929                });
930            },
931        ))
932    }
933
934    /// Synchronously closes @self. The calling thread is blocked
935    /// until this is done. See g_dbus_connection_close() for the
936    /// asynchronous version of this method and more details about what it
937    /// does.
938    /// ## `cancellable`
939    /// a #GCancellable or [`None`]
940    ///
941    /// # Returns
942    ///
943    /// [`true`] if the operation succeeded, [`false`] if @error is set
944    #[doc(alias = "g_dbus_connection_close_sync")]
945    pub fn close_sync(
946        &self,
947        cancellable: Option<&impl IsA<Cancellable>>,
948    ) -> Result<(), glib::Error> {
949        unsafe {
950            let mut error = std::ptr::null_mut();
951            let is_ok = ffi::g_dbus_connection_close_sync(
952                self.to_glib_none().0,
953                cancellable.map(|p| p.as_ref()).to_glib_none().0,
954                &mut error,
955            );
956            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
957            if error.is_null() {
958                Ok(())
959            } else {
960                Err(from_glib_full(error))
961            }
962        }
963    }
964
965    /// Emits a signal.
966    ///
967    /// If the parameters GVariant is floating, it is consumed.
968    ///
969    /// This can only fail if @parameters is not compatible with the D-Bus protocol
970    /// ([`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument]), or if @self has been closed
971    /// ([`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]).
972    /// ## `destination_bus_name`
973    /// the unique bus name for the destination
974    ///     for the signal or [`None`] to emit to all listeners
975    /// ## `object_path`
976    /// path of remote object
977    /// ## `interface_name`
978    /// D-Bus interface to emit a signal on
979    /// ## `signal_name`
980    /// the name of the signal to emit
981    /// ## `parameters`
982    /// a #GVariant tuple with parameters for the signal
983    ///              or [`None`] if not passing parameters
984    ///
985    /// # Returns
986    ///
987    /// [`true`] unless @error is set
988    #[doc(alias = "g_dbus_connection_emit_signal")]
989    pub fn emit_signal(
990        &self,
991        destination_bus_name: Option<&str>,
992        object_path: &str,
993        interface_name: &str,
994        signal_name: &str,
995        parameters: Option<&glib::Variant>,
996    ) -> Result<(), glib::Error> {
997        unsafe {
998            let mut error = std::ptr::null_mut();
999            let is_ok = ffi::g_dbus_connection_emit_signal(
1000                self.to_glib_none().0,
1001                destination_bus_name.to_glib_none().0,
1002                object_path.to_glib_none().0,
1003                interface_name.to_glib_none().0,
1004                signal_name.to_glib_none().0,
1005                parameters.to_glib_none().0,
1006                &mut error,
1007            );
1008            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1009            if error.is_null() {
1010                Ok(())
1011            } else {
1012                Err(from_glib_full(error))
1013            }
1014        }
1015    }
1016
1017    /// Asynchronously flushes @self, that is, writes all queued
1018    /// outgoing messages to the transport and then flushes the transport
1019    /// (using g_output_stream_flush_async()). This is useful in programs
1020    /// that want to emit a D-Bus signal and then exit immediately. Without
1021    /// flushing the connection, there is no guarantee that the message has
1022    /// been sent to the networking buffers in the OS kernel.
1023    ///
1024    /// This is an asynchronous method. When the operation is finished,
1025    /// @callback will be invoked in the thread-default main context
1026    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
1027    /// of the thread you are calling this method from. You can
1028    /// then call g_dbus_connection_flush_finish() to get the result of the
1029    /// operation. See g_dbus_connection_flush_sync() for the synchronous
1030    /// version.
1031    /// ## `cancellable`
1032    /// a #GCancellable or [`None`]
1033    /// ## `callback`
1034    /// a #GAsyncReadyCallback to call when the
1035    ///     request is satisfied or [`None`] if you don't care about the result
1036    #[doc(alias = "g_dbus_connection_flush")]
1037    pub fn flush<P: FnOnce(Result<(), glib::Error>) + 'static>(
1038        &self,
1039        cancellable: Option<&impl IsA<Cancellable>>,
1040        callback: P,
1041    ) {
1042        let main_context = glib::MainContext::ref_thread_default();
1043        let is_main_context_owner = main_context.is_owner();
1044        let has_acquired_main_context = (!is_main_context_owner)
1045            .then(|| main_context.acquire().ok())
1046            .flatten();
1047        assert!(
1048            is_main_context_owner || has_acquired_main_context.is_some(),
1049            "Async operations only allowed if the thread is owning the MainContext"
1050        );
1051
1052        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1053            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1054        unsafe extern "C" fn flush_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
1055            _source_object: *mut glib::gobject_ffi::GObject,
1056            res: *mut crate::ffi::GAsyncResult,
1057            user_data: glib::ffi::gpointer,
1058        ) {
1059            unsafe {
1060                let mut error = std::ptr::null_mut();
1061                ffi::g_dbus_connection_flush_finish(_source_object as *mut _, res, &mut error);
1062                let result = if error.is_null() {
1063                    Ok(())
1064                } else {
1065                    Err(from_glib_full(error))
1066                };
1067                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1068                    Box_::from_raw(user_data as *mut _);
1069                let callback: P = callback.into_inner();
1070                callback(result);
1071            }
1072        }
1073        let callback = flush_trampoline::<P>;
1074        unsafe {
1075            ffi::g_dbus_connection_flush(
1076                self.to_glib_none().0,
1077                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1078                Some(callback),
1079                Box_::into_raw(user_data) as *mut _,
1080            );
1081        }
1082    }
1083
1084    pub fn flush_future(
1085        &self,
1086    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
1087        Box_::pin(crate::GioFuture::new(
1088            self,
1089            move |obj, cancellable, send| {
1090                obj.flush(Some(cancellable), move |res| {
1091                    send.resolve(res);
1092                });
1093            },
1094        ))
1095    }
1096
1097    /// Synchronously flushes @self. The calling thread is blocked
1098    /// until this is done. See g_dbus_connection_flush() for the
1099    /// asynchronous version of this method and more details about what it
1100    /// does.
1101    /// ## `cancellable`
1102    /// a #GCancellable or [`None`]
1103    ///
1104    /// # Returns
1105    ///
1106    /// [`true`] if the operation succeeded, [`false`] if @error is set
1107    #[doc(alias = "g_dbus_connection_flush_sync")]
1108    pub fn flush_sync(
1109        &self,
1110        cancellable: Option<&impl IsA<Cancellable>>,
1111    ) -> Result<(), glib::Error> {
1112        unsafe {
1113            let mut error = std::ptr::null_mut();
1114            let is_ok = ffi::g_dbus_connection_flush_sync(
1115                self.to_glib_none().0,
1116                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1117                &mut error,
1118            );
1119            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1120            if error.is_null() {
1121                Ok(())
1122            } else {
1123                Err(from_glib_full(error))
1124            }
1125        }
1126    }
1127
1128    /// Gets the capabilities negotiated with the remote peer
1129    ///
1130    /// # Returns
1131    ///
1132    /// zero or more flags from the #GDBusCapabilityFlags enumeration
1133    #[doc(alias = "g_dbus_connection_get_capabilities")]
1134    #[doc(alias = "get_capabilities")]
1135    pub fn capabilities(&self) -> DBusCapabilityFlags {
1136        unsafe {
1137            from_glib(ffi::g_dbus_connection_get_capabilities(
1138                self.to_glib_none().0,
1139            ))
1140        }
1141    }
1142
1143    /// Gets whether the process is terminated when @self is
1144    /// closed by the remote peer. See
1145    /// #GDBusConnection:exit-on-close for more details.
1146    ///
1147    /// # Returns
1148    ///
1149    /// whether the process is terminated when @self is
1150    ///     closed by the remote peer
1151    #[doc(alias = "g_dbus_connection_get_exit_on_close")]
1152    #[doc(alias = "get_exit_on_close")]
1153    #[doc(alias = "exit-on-close")]
1154    pub fn exits_on_close(&self) -> bool {
1155        unsafe {
1156            from_glib(ffi::g_dbus_connection_get_exit_on_close(
1157                self.to_glib_none().0,
1158            ))
1159        }
1160    }
1161
1162    /// Gets the flags used to construct this connection
1163    ///
1164    /// # Returns
1165    ///
1166    /// zero or more flags from the #GDBusConnectionFlags enumeration
1167    #[cfg(feature = "v2_60")]
1168    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1169    #[doc(alias = "g_dbus_connection_get_flags")]
1170    #[doc(alias = "get_flags")]
1171    pub fn flags(&self) -> DBusConnectionFlags {
1172        unsafe { from_glib(ffi::g_dbus_connection_get_flags(self.to_glib_none().0)) }
1173    }
1174
1175    /// The GUID of the peer performing the role of server when
1176    /// authenticating. See #GDBusConnection:guid for more details.
1177    ///
1178    /// # Returns
1179    ///
1180    /// The GUID. Do not free this string, it is owned by
1181    ///     @self.
1182    #[doc(alias = "g_dbus_connection_get_guid")]
1183    #[doc(alias = "get_guid")]
1184    pub fn guid(&self) -> glib::GString {
1185        unsafe { from_glib_none(ffi::g_dbus_connection_get_guid(self.to_glib_none().0)) }
1186    }
1187
1188    /// Retrieves the last serial number assigned to a #GDBusMessage on
1189    /// the current thread. This includes messages sent via both low-level
1190    /// API such as g_dbus_connection_send_message() as well as
1191    /// high-level API such as g_dbus_connection_emit_signal(),
1192    /// g_dbus_connection_call() or g_dbus_proxy_call().
1193    ///
1194    /// # Returns
1195    ///
1196    /// the last used serial or zero when no message has been sent
1197    ///     within the current thread
1198    #[doc(alias = "g_dbus_connection_get_last_serial")]
1199    #[doc(alias = "get_last_serial")]
1200    pub fn last_serial(&self) -> u32 {
1201        unsafe { ffi::g_dbus_connection_get_last_serial(self.to_glib_none().0) }
1202    }
1203
1204    /// Gets the credentials of the authenticated peer. This will always
1205    /// return [`None`] unless @self acted as a server
1206    /// (e.g. [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER] was passed)
1207    /// when set up and the client passed credentials as part of the
1208    /// authentication process.
1209    ///
1210    /// In a message bus setup, the message bus is always the server and
1211    /// each application is a client. So this method will always return
1212    /// [`None`] for message bus clients.
1213    ///
1214    /// # Returns
1215    ///
1216    /// a #GCredentials or [`None`] if not
1217    ///     available. Do not free this object, it is owned by @self.
1218    #[doc(alias = "g_dbus_connection_get_peer_credentials")]
1219    #[doc(alias = "get_peer_credentials")]
1220    pub fn peer_credentials(&self) -> Option<Credentials> {
1221        unsafe {
1222            from_glib_none(ffi::g_dbus_connection_get_peer_credentials(
1223                self.to_glib_none().0,
1224            ))
1225        }
1226    }
1227
1228    /// Gets the underlying stream used for IO.
1229    ///
1230    /// While the #GDBusConnection is active, it will interact with this
1231    /// stream from a worker thread, so it is not safe to interact with
1232    /// the stream directly.
1233    ///
1234    /// # Returns
1235    ///
1236    /// the stream used for IO
1237    #[doc(alias = "g_dbus_connection_get_stream")]
1238    #[doc(alias = "get_stream")]
1239    pub fn stream(&self) -> IOStream {
1240        unsafe { from_glib_none(ffi::g_dbus_connection_get_stream(self.to_glib_none().0)) }
1241    }
1242
1243    /// Gets the unique name of @self as assigned by the message
1244    /// bus. This can also be used to figure out if @self is a
1245    /// message bus connection.
1246    ///
1247    /// # Returns
1248    ///
1249    /// the unique name or [`None`] if @self is not a message
1250    ///     bus connection. Do not free this string, it is owned by
1251    ///     @self.
1252    #[doc(alias = "g_dbus_connection_get_unique_name")]
1253    #[doc(alias = "get_unique_name")]
1254    #[doc(alias = "unique-name")]
1255    pub fn unique_name(&self) -> Option<glib::GString> {
1256        unsafe {
1257            from_glib_none(ffi::g_dbus_connection_get_unique_name(
1258                self.to_glib_none().0,
1259            ))
1260        }
1261    }
1262
1263    /// Gets whether @self is closed.
1264    ///
1265    /// # Returns
1266    ///
1267    /// [`true`] if the connection is closed, [`false`] otherwise
1268    #[doc(alias = "g_dbus_connection_is_closed")]
1269    #[doc(alias = "closed")]
1270    pub fn is_closed(&self) -> bool {
1271        unsafe { from_glib(ffi::g_dbus_connection_is_closed(self.to_glib_none().0)) }
1272    }
1273
1274    /// Asynchronously sends @message to the peer represented by @self.
1275    ///
1276    /// Unless @flags contain the
1277    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag, the serial number
1278    /// will be assigned by @self and set on @message via
1279    /// g_dbus_message_set_serial(). If @out_serial is not [`None`], then the
1280    /// serial number used will be written to this location prior to
1281    /// submitting the message to the underlying transport. While it has a `volatile`
1282    /// qualifier, this is a historical artifact and the argument passed to it should
1283    /// not be `volatile`.
1284    ///
1285    /// If @self is closed then the operation will fail with
1286    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @message is not well-formed,
1287    /// the operation fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
1288    ///
1289    /// See this [server][`DBusConnection`][crate::DBusConnection]#an-example-d-bus-server]
1290    /// and [client][`DBusConnection`][crate::DBusConnection]#an-example-for-file-descriptor-passing]
1291    /// for an example of how to use this low-level API to send and receive
1292    /// UNIX file descriptors.
1293    ///
1294    /// Note that @message must be unlocked, unless @flags contain the
1295    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag.
1296    /// ## `message`
1297    /// a #GDBusMessage
1298    /// ## `flags`
1299    /// flags affecting how the message is sent
1300    ///
1301    /// # Returns
1302    ///
1303    /// [`true`] if the message was well-formed and queued for
1304    ///     transmission, [`false`] if @error is set
1305    ///
1306    /// ## `out_serial`
1307    /// return location for serial number assigned
1308    ///     to @message when sending it or [`None`]
1309    #[doc(alias = "g_dbus_connection_send_message")]
1310    pub fn send_message(
1311        &self,
1312        message: &DBusMessage,
1313        flags: DBusSendMessageFlags,
1314    ) -> Result<u32, glib::Error> {
1315        unsafe {
1316            let mut out_serial = std::mem::MaybeUninit::uninit();
1317            let mut error = std::ptr::null_mut();
1318            let is_ok = ffi::g_dbus_connection_send_message(
1319                self.to_glib_none().0,
1320                message.to_glib_none().0,
1321                flags.into_glib(),
1322                out_serial.as_mut_ptr(),
1323                &mut error,
1324            );
1325            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1326            if error.is_null() {
1327                Ok(out_serial.assume_init())
1328            } else {
1329                Err(from_glib_full(error))
1330            }
1331        }
1332    }
1333
1334    /// Asynchronously sends @message to the peer represented by @self.
1335    ///
1336    /// Unless @flags contain the
1337    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag, the serial number
1338    /// will be assigned by @self and set on @message via
1339    /// g_dbus_message_set_serial(). If @out_serial is not [`None`], then the
1340    /// serial number used will be written to this location prior to
1341    /// submitting the message to the underlying transport. While it has a `volatile`
1342    /// qualifier, this is a historical artifact and the argument passed to it should
1343    /// not be `volatile`.
1344    ///
1345    /// If @self is closed then the operation will fail with
1346    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the operation will
1347    /// fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @message is not well-formed,
1348    /// the operation fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
1349    ///
1350    /// This is an asynchronous method. When the operation is finished, @callback
1351    /// will be invoked in the thread-default main context
1352    /// (see [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()])
1353    /// of the thread you are calling this method from. You can then call
1354    /// g_dbus_connection_send_message_with_reply_finish() to get the result of the operation.
1355    /// See g_dbus_connection_send_message_with_reply_sync() for the synchronous version.
1356    ///
1357    /// Note that @message must be unlocked, unless @flags contain the
1358    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag.
1359    ///
1360    /// See this [server][`DBusConnection`][crate::DBusConnection]#an-example-d-bus-server]
1361    /// and [client][`DBusConnection`][crate::DBusConnection]#an-example-for-file-descriptor-passing]
1362    /// for an example of how to use this low-level API to send and receive
1363    /// UNIX file descriptors.
1364    /// ## `message`
1365    /// a #GDBusMessage
1366    /// ## `flags`
1367    /// flags affecting how the message is sent
1368    /// ## `timeout_msec`
1369    /// the timeout in milliseconds, -1 to use the default
1370    ///     timeout or `G_MAXINT` for no timeout
1371    /// ## `cancellable`
1372    /// a #GCancellable or [`None`]
1373    /// ## `callback`
1374    /// a #GAsyncReadyCallback to call when the request
1375    ///     is satisfied or [`None`] if you don't care about the result
1376    ///
1377    /// # Returns
1378    ///
1379    ///
1380    /// ## `out_serial`
1381    /// return location for serial number assigned
1382    ///     to @message when sending it or [`None`]
1383    #[doc(alias = "g_dbus_connection_send_message_with_reply")]
1384    pub fn send_message_with_reply<P: FnOnce(Result<DBusMessage, glib::Error>) + 'static>(
1385        &self,
1386        message: &DBusMessage,
1387        flags: DBusSendMessageFlags,
1388        timeout_msec: i32,
1389        cancellable: Option<&impl IsA<Cancellable>>,
1390        callback: P,
1391    ) -> u32 {
1392        let main_context = glib::MainContext::ref_thread_default();
1393        let is_main_context_owner = main_context.is_owner();
1394        let has_acquired_main_context = (!is_main_context_owner)
1395            .then(|| main_context.acquire().ok())
1396            .flatten();
1397        assert!(
1398            is_main_context_owner || has_acquired_main_context.is_some(),
1399            "Async operations only allowed if the thread is owning the MainContext"
1400        );
1401
1402        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1403            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1404        unsafe extern "C" fn send_message_with_reply_trampoline<
1405            P: FnOnce(Result<DBusMessage, glib::Error>) + 'static,
1406        >(
1407            _source_object: *mut glib::gobject_ffi::GObject,
1408            res: *mut crate::ffi::GAsyncResult,
1409            user_data: glib::ffi::gpointer,
1410        ) {
1411            unsafe {
1412                let mut error = std::ptr::null_mut();
1413                let ret = ffi::g_dbus_connection_send_message_with_reply_finish(
1414                    _source_object as *mut _,
1415                    res,
1416                    &mut error,
1417                );
1418                let result = if error.is_null() {
1419                    Ok(from_glib_full(ret))
1420                } else {
1421                    Err(from_glib_full(error))
1422                };
1423                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1424                    Box_::from_raw(user_data as *mut _);
1425                let callback: P = callback.into_inner();
1426                callback(result);
1427            }
1428        }
1429        let callback = send_message_with_reply_trampoline::<P>;
1430        unsafe {
1431            let mut out_serial = std::mem::MaybeUninit::uninit();
1432            ffi::g_dbus_connection_send_message_with_reply(
1433                self.to_glib_none().0,
1434                message.to_glib_none().0,
1435                flags.into_glib(),
1436                timeout_msec,
1437                out_serial.as_mut_ptr(),
1438                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1439                Some(callback),
1440                Box_::into_raw(user_data) as *mut _,
1441            );
1442            out_serial.assume_init()
1443        }
1444    }
1445
1446    pub fn send_message_with_reply_future(
1447        &self,
1448        message: &DBusMessage,
1449        flags: DBusSendMessageFlags,
1450        timeout_msec: i32,
1451    ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusMessage, glib::Error>> + 'static>>
1452    {
1453        let message = message.clone();
1454        Box_::pin(crate::GioFuture::new(
1455            self,
1456            move |obj, cancellable, send| {
1457                obj.send_message_with_reply(
1458                    &message,
1459                    flags,
1460                    timeout_msec,
1461                    Some(cancellable),
1462                    move |res| {
1463                        send.resolve(res);
1464                    },
1465                );
1466            },
1467        ))
1468    }
1469
1470    /// Synchronously sends @message to the peer represented by @self
1471    /// and blocks the calling thread until a reply is received or the
1472    /// timeout is reached. See g_dbus_connection_send_message_with_reply()
1473    /// for the asynchronous version of this method.
1474    ///
1475    /// Unless @flags contain the
1476    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag, the serial number
1477    /// will be assigned by @self and set on @message via
1478    /// g_dbus_message_set_serial(). If @out_serial is not [`None`], then the
1479    /// serial number used will be written to this location prior to
1480    /// submitting the message to the underlying transport. While it has a `volatile`
1481    /// qualifier, this is a historical artifact and the argument passed to it should
1482    /// not be `volatile`.
1483    ///
1484    /// If @self is closed then the operation will fail with
1485    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. If @cancellable is canceled, the operation will
1486    /// fail with [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled]. If @message is not well-formed,
1487    /// the operation fails with [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument].
1488    ///
1489    /// Note that @error is only set if a local in-process error
1490    /// occurred. That is to say that the returned #GDBusMessage object may
1491    /// be of type [`DBusMessageType::Error`][crate::DBusMessageType::Error]. Use
1492    /// g_dbus_message_to_gerror() to transcode this to a #GError.
1493    ///
1494    /// See this [server][`DBusConnection`][crate::DBusConnection]#an-example-d-bus-server]
1495    /// and [client][`DBusConnection`][crate::DBusConnection]#an-example-for-file-descriptor-passing]
1496    /// for an example of how to use this low-level API to send and receive
1497    /// UNIX file descriptors.
1498    ///
1499    /// Note that @message must be unlocked, unless @flags contain the
1500    /// [`DBusSendMessageFlags::PRESERVE_SERIAL`][crate::DBusSendMessageFlags::PRESERVE_SERIAL] flag.
1501    /// ## `message`
1502    /// a #GDBusMessage
1503    /// ## `flags`
1504    /// flags affecting how the message is sent.
1505    /// ## `timeout_msec`
1506    /// the timeout in milliseconds, -1 to use the default
1507    ///     timeout or `G_MAXINT` for no timeout
1508    /// ## `cancellable`
1509    /// a #GCancellable or [`None`]
1510    ///
1511    /// # Returns
1512    ///
1513    /// a locked #GDBusMessage that is the reply
1514    ///     to @message or [`None`] if @error is set
1515    ///
1516    /// ## `out_serial`
1517    /// return location for serial number
1518    ///     assigned to @message when sending it or [`None`]
1519    #[doc(alias = "g_dbus_connection_send_message_with_reply_sync")]
1520    pub fn send_message_with_reply_sync(
1521        &self,
1522        message: &DBusMessage,
1523        flags: DBusSendMessageFlags,
1524        timeout_msec: i32,
1525        cancellable: Option<&impl IsA<Cancellable>>,
1526    ) -> Result<(DBusMessage, u32), glib::Error> {
1527        unsafe {
1528            let mut out_serial = std::mem::MaybeUninit::uninit();
1529            let mut error = std::ptr::null_mut();
1530            let ret = ffi::g_dbus_connection_send_message_with_reply_sync(
1531                self.to_glib_none().0,
1532                message.to_glib_none().0,
1533                flags.into_glib(),
1534                timeout_msec,
1535                out_serial.as_mut_ptr(),
1536                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1537                &mut error,
1538            );
1539            if error.is_null() {
1540                Ok((from_glib_full(ret), out_serial.assume_init()))
1541            } else {
1542                Err(from_glib_full(error))
1543            }
1544        }
1545    }
1546
1547    /// Sets whether the process should be terminated when @self is
1548    /// closed by the remote peer. See #GDBusConnection:exit-on-close for
1549    /// more details.
1550    ///
1551    /// Note that this function should be used with care. Most modern UNIX
1552    /// desktops tie the notion of a user session with the session bus, and expect
1553    /// all of a user's applications to quit when their bus connection goes away.
1554    /// If you are setting @exit_on_close to [`false`] for the shared session
1555    /// bus connection, you should make sure that your application exits
1556    /// when the user session ends.
1557    /// ## `exit_on_close`
1558    /// whether the process should be terminated
1559    ///     when @self is closed by the remote peer
1560    #[doc(alias = "g_dbus_connection_set_exit_on_close")]
1561    #[doc(alias = "exit-on-close")]
1562    pub fn set_exit_on_close(&self, exit_on_close: bool) {
1563        unsafe {
1564            ffi::g_dbus_connection_set_exit_on_close(
1565                self.to_glib_none().0,
1566                exit_on_close.into_glib(),
1567            );
1568        }
1569    }
1570
1571    /// If @self was created with
1572    /// [`DBusConnectionFlags::DELAY_MESSAGE_PROCESSING`][crate::DBusConnectionFlags::DELAY_MESSAGE_PROCESSING], this method
1573    /// starts processing messages. Does nothing on if @self wasn't
1574    /// created with this flag or if the method has already been called.
1575    #[doc(alias = "g_dbus_connection_start_message_processing")]
1576    pub fn start_message_processing(&self) {
1577        unsafe {
1578            ffi::g_dbus_connection_start_message_processing(self.to_glib_none().0);
1579        }
1580    }
1581
1582    #[cfg(not(feature = "v2_60"))]
1583    #[cfg_attr(docsrs, doc(cfg(not(feature = "v2_60"))))]
1584    pub fn flags(&self) -> DBusConnectionFlags {
1585        ObjectExt::property(self, "flags")
1586    }
1587
1588    /// Asynchronously sets up a D-Bus connection for exchanging D-Bus messages
1589    /// with the end represented by @stream.
1590    ///
1591    /// If @stream is a #GSocketConnection, then the corresponding #GSocket
1592    /// will be put into non-blocking mode.
1593    ///
1594    /// The D-Bus connection will interact with @stream from a worker thread.
1595    /// As a result, the caller should not interact with @stream after this
1596    /// method has been called, except by calling g_object_unref() on it.
1597    ///
1598    /// If @observer is not [`None`] it may be used to control the
1599    /// authentication process.
1600    ///
1601    /// When the operation is finished, @callback will be invoked. You can
1602    /// then call g_dbus_connection_new_finish() to get the result of the
1603    /// operation.
1604    ///
1605    /// This is an asynchronous failable constructor. See
1606    /// g_dbus_connection_new_sync() for the synchronous
1607    /// version.
1608    /// ## `stream`
1609    /// a #GIOStream
1610    /// ## `guid`
1611    /// the GUID to use if authenticating as a server or [`None`]
1612    /// ## `flags`
1613    /// flags describing how to make the connection
1614    /// ## `observer`
1615    /// a #GDBusAuthObserver or [`None`]
1616    /// ## `cancellable`
1617    /// a #GCancellable or [`None`]
1618    /// ## `callback`
1619    /// a #GAsyncReadyCallback to call when the request is satisfied
1620    #[doc(alias = "g_dbus_connection_new")]
1621    pub fn new<P: FnOnce(Result<DBusConnection, glib::Error>) + 'static>(
1622        stream: &impl IsA<IOStream>,
1623        guid: Option<&str>,
1624        flags: DBusConnectionFlags,
1625        observer: Option<&DBusAuthObserver>,
1626        cancellable: Option<&impl IsA<Cancellable>>,
1627        callback: P,
1628    ) {
1629        let main_context = glib::MainContext::ref_thread_default();
1630        let is_main_context_owner = main_context.is_owner();
1631        let has_acquired_main_context = (!is_main_context_owner)
1632            .then(|| main_context.acquire().ok())
1633            .flatten();
1634        assert!(
1635            is_main_context_owner || has_acquired_main_context.is_some(),
1636            "Async operations only allowed if the thread is owning the MainContext"
1637        );
1638
1639        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1640            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1641        unsafe extern "C" fn new_trampoline<
1642            P: FnOnce(Result<DBusConnection, glib::Error>) + 'static,
1643        >(
1644            _source_object: *mut glib::gobject_ffi::GObject,
1645            res: *mut crate::ffi::GAsyncResult,
1646            user_data: glib::ffi::gpointer,
1647        ) {
1648            unsafe {
1649                let mut error = std::ptr::null_mut();
1650                let ret = ffi::g_dbus_connection_new_finish(res, &mut error);
1651                let result = if error.is_null() {
1652                    Ok(from_glib_full(ret))
1653                } else {
1654                    Err(from_glib_full(error))
1655                };
1656                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1657                    Box_::from_raw(user_data as *mut _);
1658                let callback: P = callback.into_inner();
1659                callback(result);
1660            }
1661        }
1662        let callback = new_trampoline::<P>;
1663        unsafe {
1664            ffi::g_dbus_connection_new(
1665                stream.as_ref().to_glib_none().0,
1666                guid.to_glib_none().0,
1667                flags.into_glib(),
1668                observer.to_glib_none().0,
1669                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1670                Some(callback),
1671                Box_::into_raw(user_data) as *mut _,
1672            );
1673        }
1674    }
1675
1676    pub fn new_future(
1677        stream: &(impl IsA<IOStream> + Clone + 'static),
1678        guid: Option<&str>,
1679        flags: DBusConnectionFlags,
1680        observer: Option<&DBusAuthObserver>,
1681    ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusConnection, glib::Error>> + 'static>>
1682    {
1683        let stream = stream.clone();
1684        let guid = guid.map(ToOwned::to_owned);
1685        let observer = observer.map(ToOwned::to_owned);
1686        Box_::pin(crate::GioFuture::new(
1687            &(),
1688            move |_obj, cancellable, send| {
1689                Self::new(
1690                    &stream,
1691                    guid.as_ref().map(::std::borrow::Borrow::borrow),
1692                    flags,
1693                    observer.as_ref().map(::std::borrow::Borrow::borrow),
1694                    Some(cancellable),
1695                    move |res| {
1696                        send.resolve(res);
1697                    },
1698                );
1699            },
1700        ))
1701    }
1702
1703    /// Asynchronously connects and sets up a D-Bus client connection for
1704    /// exchanging D-Bus messages with an endpoint specified by @address
1705    /// which must be in the
1706    /// [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses).
1707    ///
1708    /// This constructor can only be used to initiate client-side
1709    /// connections - use g_dbus_connection_new() if you need to act as the
1710    /// server. In particular, @flags cannot contain the
1711    /// [`DBusConnectionFlags::AUTHENTICATION_SERVER`][crate::DBusConnectionFlags::AUTHENTICATION_SERVER],
1712    /// [`DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS`][crate::DBusConnectionFlags::AUTHENTICATION_ALLOW_ANONYMOUS] or
1713    /// [`DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER`][crate::DBusConnectionFlags::AUTHENTICATION_REQUIRE_SAME_USER] flags.
1714    ///
1715    /// When the operation is finished, @callback will be invoked. You can
1716    /// then call g_dbus_connection_new_for_address_finish() to get the result of
1717    /// the operation.
1718    ///
1719    /// If @observer is not [`None`] it may be used to control the
1720    /// authentication process.
1721    ///
1722    /// This is an asynchronous failable constructor. See
1723    /// g_dbus_connection_new_for_address_sync() for the synchronous
1724    /// version.
1725    /// ## `address`
1726    /// a D-Bus address
1727    /// ## `flags`
1728    /// flags describing how to make the connection
1729    /// ## `observer`
1730    /// a #GDBusAuthObserver or [`None`]
1731    /// ## `cancellable`
1732    /// a #GCancellable or [`None`]
1733    /// ## `callback`
1734    /// a #GAsyncReadyCallback to call when the request is satisfied
1735    #[doc(alias = "g_dbus_connection_new_for_address")]
1736    #[doc(alias = "new_for_address")]
1737    pub fn for_address<P: FnOnce(Result<DBusConnection, glib::Error>) + 'static>(
1738        address: &str,
1739        flags: DBusConnectionFlags,
1740        observer: Option<&DBusAuthObserver>,
1741        cancellable: Option<&impl IsA<Cancellable>>,
1742        callback: P,
1743    ) {
1744        let main_context = glib::MainContext::ref_thread_default();
1745        let is_main_context_owner = main_context.is_owner();
1746        let has_acquired_main_context = (!is_main_context_owner)
1747            .then(|| main_context.acquire().ok())
1748            .flatten();
1749        assert!(
1750            is_main_context_owner || has_acquired_main_context.is_some(),
1751            "Async operations only allowed if the thread is owning the MainContext"
1752        );
1753
1754        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
1755            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
1756        unsafe extern "C" fn for_address_trampoline<
1757            P: FnOnce(Result<DBusConnection, glib::Error>) + 'static,
1758        >(
1759            _source_object: *mut glib::gobject_ffi::GObject,
1760            res: *mut crate::ffi::GAsyncResult,
1761            user_data: glib::ffi::gpointer,
1762        ) {
1763            unsafe {
1764                let mut error = std::ptr::null_mut();
1765                let ret = ffi::g_dbus_connection_new_for_address_finish(res, &mut error);
1766                let result = if error.is_null() {
1767                    Ok(from_glib_full(ret))
1768                } else {
1769                    Err(from_glib_full(error))
1770                };
1771                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
1772                    Box_::from_raw(user_data as *mut _);
1773                let callback: P = callback.into_inner();
1774                callback(result);
1775            }
1776        }
1777        let callback = for_address_trampoline::<P>;
1778        unsafe {
1779            ffi::g_dbus_connection_new_for_address(
1780                address.to_glib_none().0,
1781                flags.into_glib(),
1782                observer.to_glib_none().0,
1783                cancellable.map(|p| p.as_ref()).to_glib_none().0,
1784                Some(callback),
1785                Box_::into_raw(user_data) as *mut _,
1786            );
1787        }
1788    }
1789
1790    pub fn for_address_future(
1791        address: &str,
1792        flags: DBusConnectionFlags,
1793        observer: Option<&DBusAuthObserver>,
1794    ) -> Pin<Box_<dyn std::future::Future<Output = Result<DBusConnection, glib::Error>> + 'static>>
1795    {
1796        let address = String::from(address);
1797        let observer = observer.map(ToOwned::to_owned);
1798        Box_::pin(crate::GioFuture::new(
1799            &(),
1800            move |_obj, cancellable, send| {
1801                Self::for_address(
1802                    &address,
1803                    flags,
1804                    observer.as_ref().map(::std::borrow::Borrow::borrow),
1805                    Some(cancellable),
1806                    move |res| {
1807                        send.resolve(res);
1808                    },
1809                );
1810            },
1811        ))
1812    }
1813
1814    /// Emitted when the connection is closed.
1815    ///
1816    /// The cause of this event can be
1817    ///
1818    /// - If g_dbus_connection_close() is called. In this case
1819    ///   @remote_peer_vanished is set to [`false`] and @error is [`None`].
1820    ///
1821    /// - If the remote peer closes the connection. In this case
1822    ///   @remote_peer_vanished is set to [`true`] and @error is set.
1823    ///
1824    /// - If the remote peer sends invalid or malformed data. In this
1825    ///   case @remote_peer_vanished is set to [`false`] and @error is set.
1826    ///
1827    /// Upon receiving this signal, you should give up your reference to
1828    /// @connection. You are guaranteed that this signal is emitted only
1829    /// once.
1830    /// ## `remote_peer_vanished`
1831    /// [`true`] if @connection is closed because the
1832    ///     remote peer closed its end of the connection
1833    /// ## `error`
1834    /// a #GError with more details about the event or [`None`]
1835    #[doc(alias = "closed")]
1836    pub fn connect_closed<F: Fn(&Self, bool, Option<&glib::Error>) + Send + Sync + 'static>(
1837        &self,
1838        f: F,
1839    ) -> SignalHandlerId {
1840        unsafe extern "C" fn closed_trampoline<
1841            F: Fn(&DBusConnection, bool, Option<&glib::Error>) + Send + Sync + 'static,
1842        >(
1843            this: *mut ffi::GDBusConnection,
1844            remote_peer_vanished: glib::ffi::gboolean,
1845            error: *mut glib::ffi::GError,
1846            f: glib::ffi::gpointer,
1847        ) {
1848            unsafe {
1849                let f: &F = &*(f as *const F);
1850                f(
1851                    &from_glib_borrow(this),
1852                    from_glib(remote_peer_vanished),
1853                    Option::<glib::Error>::from_glib_borrow(error)
1854                        .as_ref()
1855                        .as_ref(),
1856                )
1857            }
1858        }
1859        unsafe {
1860            let f: Box_<F> = Box_::new(f);
1861            connect_raw(
1862                self.as_ptr() as *mut _,
1863                c"closed".as_ptr() as *const _,
1864                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1865                    closed_trampoline::<F> as *const (),
1866                )),
1867                Box_::into_raw(f),
1868            )
1869        }
1870    }
1871
1872    #[doc(alias = "capabilities")]
1873    pub fn connect_capabilities_notify<F: Fn(&Self) + Send + Sync + 'static>(
1874        &self,
1875        f: F,
1876    ) -> SignalHandlerId {
1877        unsafe extern "C" fn notify_capabilities_trampoline<
1878            F: Fn(&DBusConnection) + Send + Sync + 'static,
1879        >(
1880            this: *mut ffi::GDBusConnection,
1881            _param_spec: glib::ffi::gpointer,
1882            f: glib::ffi::gpointer,
1883        ) {
1884            unsafe {
1885                let f: &F = &*(f as *const F);
1886                f(&from_glib_borrow(this))
1887            }
1888        }
1889        unsafe {
1890            let f: Box_<F> = Box_::new(f);
1891            connect_raw(
1892                self.as_ptr() as *mut _,
1893                c"notify::capabilities".as_ptr() as *const _,
1894                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1895                    notify_capabilities_trampoline::<F> as *const (),
1896                )),
1897                Box_::into_raw(f),
1898            )
1899        }
1900    }
1901
1902    #[doc(alias = "closed")]
1903    pub fn connect_closed_notify<F: Fn(&Self) + Send + Sync + 'static>(
1904        &self,
1905        f: F,
1906    ) -> SignalHandlerId {
1907        unsafe extern "C" fn notify_closed_trampoline<
1908            F: Fn(&DBusConnection) + Send + Sync + 'static,
1909        >(
1910            this: *mut ffi::GDBusConnection,
1911            _param_spec: glib::ffi::gpointer,
1912            f: glib::ffi::gpointer,
1913        ) {
1914            unsafe {
1915                let f: &F = &*(f as *const F);
1916                f(&from_glib_borrow(this))
1917            }
1918        }
1919        unsafe {
1920            let f: Box_<F> = Box_::new(f);
1921            connect_raw(
1922                self.as_ptr() as *mut _,
1923                c"notify::closed".as_ptr() as *const _,
1924                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1925                    notify_closed_trampoline::<F> as *const (),
1926                )),
1927                Box_::into_raw(f),
1928            )
1929        }
1930    }
1931
1932    #[doc(alias = "exit-on-close")]
1933    pub fn connect_exit_on_close_notify<F: Fn(&Self) + Send + Sync + 'static>(
1934        &self,
1935        f: F,
1936    ) -> SignalHandlerId {
1937        unsafe extern "C" fn notify_exit_on_close_trampoline<
1938            F: Fn(&DBusConnection) + Send + Sync + 'static,
1939        >(
1940            this: *mut ffi::GDBusConnection,
1941            _param_spec: glib::ffi::gpointer,
1942            f: glib::ffi::gpointer,
1943        ) {
1944            unsafe {
1945                let f: &F = &*(f as *const F);
1946                f(&from_glib_borrow(this))
1947            }
1948        }
1949        unsafe {
1950            let f: Box_<F> = Box_::new(f);
1951            connect_raw(
1952                self.as_ptr() as *mut _,
1953                c"notify::exit-on-close".as_ptr() as *const _,
1954                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1955                    notify_exit_on_close_trampoline::<F> as *const (),
1956                )),
1957                Box_::into_raw(f),
1958            )
1959        }
1960    }
1961
1962    #[doc(alias = "unique-name")]
1963    pub fn connect_unique_name_notify<F: Fn(&Self) + Send + Sync + 'static>(
1964        &self,
1965        f: F,
1966    ) -> SignalHandlerId {
1967        unsafe extern "C" fn notify_unique_name_trampoline<
1968            F: Fn(&DBusConnection) + Send + Sync + 'static,
1969        >(
1970            this: *mut ffi::GDBusConnection,
1971            _param_spec: glib::ffi::gpointer,
1972            f: glib::ffi::gpointer,
1973        ) {
1974            unsafe {
1975                let f: &F = &*(f as *const F);
1976                f(&from_glib_borrow(this))
1977            }
1978        }
1979        unsafe {
1980            let f: Box_<F> = Box_::new(f);
1981            connect_raw(
1982                self.as_ptr() as *mut _,
1983                c"notify::unique-name".as_ptr() as *const _,
1984                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1985                    notify_unique_name_trampoline::<F> as *const (),
1986                )),
1987                Box_::into_raw(f),
1988            )
1989        }
1990    }
1991}
1992
1993unsafe impl Send for DBusConnection {}
1994unsafe impl Sync for DBusConnection {}