Skip to main content

gio/auto/
socket_listener.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::{
6    AsyncResult, Cancellable, Socket, SocketAddress, SocketConnection, SocketListenerEvent,
7    SocketProtocol, SocketType, ffi,
8};
9use glib::{
10    object::ObjectType as _,
11    prelude::*,
12    signal::{SignalHandlerId, connect_raw},
13    translate::*,
14};
15use std::{boxed::Box as Box_, pin::Pin};
16
17glib::wrapper! {
18    /// A `GSocketListener` is an object that keeps track of a set
19    /// of server sockets and helps you accept sockets from any of the
20    /// socket, either sync or async.
21    ///
22    /// Add addresses and ports to listen on using
23    /// [`SocketListenerExt::add_address()`][crate::prelude::SocketListenerExt::add_address()] and
24    /// [`SocketListenerExt::add_inet_port()`][crate::prelude::SocketListenerExt::add_inet_port()]. These will be listened on until
25    /// [`SocketListenerExt::close()`][crate::prelude::SocketListenerExt::close()] is called. Dropping your final reference to
26    /// the `GSocketListener` will not cause [`SocketListenerExt::close()`][crate::prelude::SocketListenerExt::close()] to be
27    /// called implicitly, as some references to the `GSocketListener` may be held
28    /// internally.
29    ///
30    /// If you want to implement a network server, also look at
31    /// [`SocketService`][crate::SocketService] and [`ThreadedSocketService`][crate::ThreadedSocketService] which are
32    /// subclasses of `GSocketListener` that make this even easier.
33    ///
34    /// ## Properties
35    ///
36    ///
37    /// #### `listen-backlog`
38    ///  The number of outstanding connections in the listen queue.
39    ///
40    /// Readable | Writeable | Construct
41    ///
42    /// ## Signals
43    ///
44    ///
45    /// #### `event`
46    ///  Emitted when @listener's activity on @socket changes state.
47    /// Note that when @listener is used to listen on both IPv4 and
48    /// IPv6, a separate set of signals will be emitted for each, and
49    /// the order they happen in is undefined.
50    ///
51    ///
52    ///
53    /// # Implements
54    ///
55    /// [`SocketListenerExt`][trait@crate::prelude::SocketListenerExt], [`trait@glib::ObjectExt`], [`SocketListenerExtManual`][trait@crate::prelude::SocketListenerExtManual]
56    #[doc(alias = "GSocketListener")]
57    pub struct SocketListener(Object<ffi::GSocketListener, ffi::GSocketListenerClass>);
58
59    match fn {
60        type_ => || ffi::g_socket_listener_get_type(),
61    }
62}
63
64impl SocketListener {
65    pub const NONE: Option<&'static SocketListener> = None;
66
67    /// Creates a new #GSocketListener with no sockets to listen for.
68    /// New listeners can be added with e.g. g_socket_listener_add_address()
69    /// or g_socket_listener_add_inet_port().
70    ///
71    /// # Returns
72    ///
73    /// a new #GSocketListener.
74    #[doc(alias = "g_socket_listener_new")]
75    pub fn new() -> SocketListener {
76        unsafe { from_glib_full(ffi::g_socket_listener_new()) }
77    }
78}
79
80impl Default for SocketListener {
81    fn default() -> Self {
82        Self::new()
83    }
84}
85
86/// Trait containing all [`struct@SocketListener`] methods.
87///
88/// # Implementors
89///
90/// [`SocketListener`][struct@crate::SocketListener], [`SocketService`][struct@crate::SocketService]
91pub trait SocketListenerExt: IsA<SocketListener> + 'static {
92    /// Blocks waiting for a client to connect to any of the sockets added
93    /// to the listener. Returns a #GSocketConnection for the socket that was
94    /// accepted.
95    ///
96    /// If @source_object is not [`None`] it will be filled out with the source
97    /// object specified when the corresponding socket or address was added
98    /// to the listener.
99    ///
100    /// If @cancellable is not [`None`], then the operation can be cancelled by
101    /// triggering the cancellable object from another thread. If the operation
102    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
103    /// ## `cancellable`
104    /// optional #GCancellable object, [`None`] to ignore.
105    ///
106    /// # Returns
107    ///
108    /// a #GSocketConnection on success, [`None`] on error.
109    ///
110    /// ## `source_object`
111    /// location where #GObject pointer will be stored, or [`None`]
112    #[doc(alias = "g_socket_listener_accept")]
113    fn accept(
114        &self,
115        cancellable: Option<&impl IsA<Cancellable>>,
116    ) -> Result<(SocketConnection, Option<glib::Object>), glib::Error> {
117        unsafe {
118            let mut source_object = std::ptr::null_mut();
119            let mut error = std::ptr::null_mut();
120            let ret = ffi::g_socket_listener_accept(
121                self.as_ref().to_glib_none().0,
122                &mut source_object,
123                cancellable.map(|p| p.as_ref()).to_glib_none().0,
124                &mut error,
125            );
126            if error.is_null() {
127                Ok((from_glib_full(ret), from_glib_none(source_object)))
128            } else {
129                Err(from_glib_full(error))
130            }
131        }
132    }
133
134    /// This is the asynchronous version of g_socket_listener_accept().
135    ///
136    /// When the operation is finished @callback will be
137    /// called. You can then call g_socket_listener_accept_finish()
138    /// to get the result of the operation.
139    /// ## `cancellable`
140    /// a #GCancellable, or [`None`]
141    /// ## `callback`
142    /// a #GAsyncReadyCallback
143    #[doc(alias = "g_socket_listener_accept_async")]
144    fn accept_async<
145        P: FnOnce(Result<(SocketConnection, Option<glib::Object>), glib::Error>) + 'static,
146    >(
147        &self,
148        cancellable: Option<&impl IsA<Cancellable>>,
149        callback: P,
150    ) {
151        let main_context = glib::MainContext::ref_thread_default();
152        let is_main_context_owner = main_context.is_owner();
153        let has_acquired_main_context = (!is_main_context_owner)
154            .then(|| main_context.acquire().ok())
155            .flatten();
156        assert!(
157            is_main_context_owner || has_acquired_main_context.is_some(),
158            "Async operations only allowed if the thread is owning the MainContext"
159        );
160
161        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
162            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
163        unsafe extern "C" fn accept_async_trampoline<
164            P: FnOnce(Result<(SocketConnection, Option<glib::Object>), glib::Error>) + 'static,
165        >(
166            _source_object: *mut glib::gobject_ffi::GObject,
167            res: *mut crate::ffi::GAsyncResult,
168            user_data: glib::ffi::gpointer,
169        ) {
170            unsafe {
171                let mut error = std::ptr::null_mut();
172                let mut source_object = std::ptr::null_mut();
173                let ret = ffi::g_socket_listener_accept_finish(
174                    _source_object as *mut _,
175                    res,
176                    &mut source_object,
177                    &mut error,
178                );
179                let result = if error.is_null() {
180                    Ok((from_glib_full(ret), from_glib_none(source_object)))
181                } else {
182                    Err(from_glib_full(error))
183                };
184                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
185                    Box_::from_raw(user_data as *mut _);
186                let callback: P = callback.into_inner();
187                callback(result);
188            }
189        }
190        let callback = accept_async_trampoline::<P>;
191        unsafe {
192            ffi::g_socket_listener_accept_async(
193                self.as_ref().to_glib_none().0,
194                cancellable.map(|p| p.as_ref()).to_glib_none().0,
195                Some(callback),
196                Box_::into_raw(user_data) as *mut _,
197            );
198        }
199    }
200
201    fn accept_future(
202        &self,
203    ) -> Pin<
204        Box_<
205            dyn std::future::Future<
206                    Output = Result<(SocketConnection, Option<glib::Object>), glib::Error>,
207                > + 'static,
208        >,
209    > {
210        Box_::pin(crate::GioFuture::new(
211            self,
212            move |obj, cancellable, send| {
213                obj.accept_async(Some(cancellable), move |res| {
214                    send.resolve(res);
215                });
216            },
217        ))
218    }
219
220    /// Blocks waiting for a client to connect to any of the sockets added
221    /// to the listener. Returns the #GSocket that was accepted.
222    ///
223    /// If you want to accept the high-level #GSocketConnection, not a #GSocket,
224    /// which is often the case, then you should use g_socket_listener_accept()
225    /// instead.
226    ///
227    /// If @source_object is not [`None`] it will be filled out with the source
228    /// object specified when the corresponding socket or address was added
229    /// to the listener.
230    ///
231    /// If @cancellable is not [`None`], then the operation can be cancelled by
232    /// triggering the cancellable object from another thread. If the operation
233    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
234    /// ## `cancellable`
235    /// optional #GCancellable object, [`None`] to ignore.
236    ///
237    /// # Returns
238    ///
239    /// a #GSocket on success, [`None`] on error.
240    ///
241    /// ## `source_object`
242    /// location where #GObject pointer will be stored, or [`None`].
243    #[doc(alias = "g_socket_listener_accept_socket")]
244    fn accept_socket(
245        &self,
246        cancellable: Option<&impl IsA<Cancellable>>,
247    ) -> Result<(Socket, Option<glib::Object>), glib::Error> {
248        unsafe {
249            let mut source_object = std::ptr::null_mut();
250            let mut error = std::ptr::null_mut();
251            let ret = ffi::g_socket_listener_accept_socket(
252                self.as_ref().to_glib_none().0,
253                &mut source_object,
254                cancellable.map(|p| p.as_ref()).to_glib_none().0,
255                &mut error,
256            );
257            if error.is_null() {
258                Ok((from_glib_full(ret), from_glib_none(source_object)))
259            } else {
260                Err(from_glib_full(error))
261            }
262        }
263    }
264
265    /// This is the asynchronous version of g_socket_listener_accept_socket().
266    ///
267    /// When the operation is finished @callback will be
268    /// called. You can then call g_socket_listener_accept_socket_finish()
269    /// to get the result of the operation.
270    /// ## `cancellable`
271    /// a #GCancellable, or [`None`]
272    /// ## `callback`
273    /// a #GAsyncReadyCallback
274    #[doc(alias = "g_socket_listener_accept_socket_async")]
275    fn accept_socket_async<
276        P: FnOnce(Result<(Socket, Option<glib::Object>), glib::Error>) + 'static,
277    >(
278        &self,
279        cancellable: Option<&impl IsA<Cancellable>>,
280        callback: P,
281    ) {
282        let main_context = glib::MainContext::ref_thread_default();
283        let is_main_context_owner = main_context.is_owner();
284        let has_acquired_main_context = (!is_main_context_owner)
285            .then(|| main_context.acquire().ok())
286            .flatten();
287        assert!(
288            is_main_context_owner || has_acquired_main_context.is_some(),
289            "Async operations only allowed if the thread is owning the MainContext"
290        );
291
292        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
293            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
294        unsafe extern "C" fn accept_socket_async_trampoline<
295            P: FnOnce(Result<(Socket, Option<glib::Object>), glib::Error>) + 'static,
296        >(
297            _source_object: *mut glib::gobject_ffi::GObject,
298            res: *mut crate::ffi::GAsyncResult,
299            user_data: glib::ffi::gpointer,
300        ) {
301            unsafe {
302                let mut error = std::ptr::null_mut();
303                let mut source_object = std::ptr::null_mut();
304                let ret = ffi::g_socket_listener_accept_socket_finish(
305                    _source_object as *mut _,
306                    res,
307                    &mut source_object,
308                    &mut error,
309                );
310                let result = if error.is_null() {
311                    Ok((from_glib_full(ret), from_glib_none(source_object)))
312                } else {
313                    Err(from_glib_full(error))
314                };
315                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
316                    Box_::from_raw(user_data as *mut _);
317                let callback: P = callback.into_inner();
318                callback(result);
319            }
320        }
321        let callback = accept_socket_async_trampoline::<P>;
322        unsafe {
323            ffi::g_socket_listener_accept_socket_async(
324                self.as_ref().to_glib_none().0,
325                cancellable.map(|p| p.as_ref()).to_glib_none().0,
326                Some(callback),
327                Box_::into_raw(user_data) as *mut _,
328            );
329        }
330    }
331
332    fn accept_socket_future(
333        &self,
334    ) -> Pin<
335        Box_<
336            dyn std::future::Future<Output = Result<(Socket, Option<glib::Object>), glib::Error>>
337                + 'static,
338        >,
339    > {
340        Box_::pin(crate::GioFuture::new(
341            self,
342            move |obj, cancellable, send| {
343                obj.accept_socket_async(Some(cancellable), move |res| {
344                    send.resolve(res);
345                });
346            },
347        ))
348    }
349
350    /// Creates a socket of type @type_ and protocol @protocol, binds
351    /// it to @address and adds it to the set of sockets we're accepting
352    /// sockets from.
353    ///
354    /// Note that adding an IPv6 address, depending on the platform,
355    /// may or may not result in a listener that also accepts IPv4
356    /// connections.  For more deterministic behavior, see
357    /// g_socket_listener_add_inet_port().
358    ///
359    /// @source_object will be passed out in the various calls
360    /// to accept to identify this particular source, which is
361    /// useful if you're listening on multiple addresses and do
362    /// different things depending on what address is connected to.
363    ///
364    /// If successful and @effective_address is non-[`None`] then it will
365    /// be set to the address that the binding actually occurred at.  This
366    /// is helpful for determining the port number that was used for when
367    /// requesting a binding to port 0 (ie: "any port").  This address, if
368    /// requested, belongs to the caller and must be freed.
369    ///
370    /// Call g_socket_listener_close() to stop listening on @address; this will not
371    /// be done automatically when you drop your final reference to @self, as
372    /// references may be held internally.
373    /// ## `address`
374    /// a #GSocketAddress
375    /// ## `type_`
376    /// a #GSocketType
377    /// ## `protocol`
378    /// a #GSocketProtocol
379    /// ## `source_object`
380    /// Optional #GObject identifying this source
381    ///
382    /// # Returns
383    ///
384    /// [`true`] on success, [`false`] on error.
385    ///
386    /// ## `effective_address`
387    /// location to store the address that was bound to, or [`None`].
388    #[doc(alias = "g_socket_listener_add_address")]
389    fn add_address(
390        &self,
391        address: &impl IsA<SocketAddress>,
392        type_: SocketType,
393        protocol: SocketProtocol,
394        source_object: Option<&impl IsA<glib::Object>>,
395    ) -> Result<SocketAddress, glib::Error> {
396        unsafe {
397            let mut effective_address = std::ptr::null_mut();
398            let mut error = std::ptr::null_mut();
399            let is_ok = ffi::g_socket_listener_add_address(
400                self.as_ref().to_glib_none().0,
401                address.as_ref().to_glib_none().0,
402                type_.into_glib(),
403                protocol.into_glib(),
404                source_object.map(|p| p.as_ref()).to_glib_none().0,
405                &mut effective_address,
406                &mut error,
407            );
408            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
409            if error.is_null() {
410                Ok(from_glib_full(effective_address))
411            } else {
412                Err(from_glib_full(error))
413            }
414        }
415    }
416
417    /// Listens for TCP connections on any available port number for both
418    /// IPv6 and IPv4 (if each is available).
419    ///
420    /// This is useful if you need to have a socket for incoming connections
421    /// but don't care about the specific port number.
422    ///
423    /// If possible, the [`SocketListener`][crate::SocketListener] will listen on both IPv4 and
424    /// IPv6 (listening on the same port on both). If listening on one of the socket
425    /// families fails, the [`SocketListener`][crate::SocketListener] will only listen on the other.
426    /// If listening on both fails, an error will be returned.
427    ///
428    /// If you need to distinguish whether listening on IPv4 or IPv6 or both was
429    /// successful, connect to [`event`][struct@crate::SocketListener#event].
430    ///
431    /// @source_object will be passed out in the various calls
432    /// to accept to identify this particular source, which is
433    /// useful if you're listening on multiple addresses and do
434    /// different things depending on what address is connected to.
435    /// ## `source_object`
436    /// Optional #GObject identifying this source
437    ///
438    /// # Returns
439    ///
440    /// the port number, or 0 in case of failure.
441    #[doc(alias = "g_socket_listener_add_any_inet_port")]
442    fn add_any_inet_port(
443        &self,
444        source_object: Option<&impl IsA<glib::Object>>,
445    ) -> Result<u16, glib::Error> {
446        unsafe {
447            let mut error = std::ptr::null_mut();
448            let ret = ffi::g_socket_listener_add_any_inet_port(
449                self.as_ref().to_glib_none().0,
450                source_object.map(|p| p.as_ref()).to_glib_none().0,
451                &mut error,
452            );
453            if error.is_null() {
454                Ok(ret)
455            } else {
456                Err(from_glib_full(error))
457            }
458        }
459    }
460
461    /// Helper function for g_socket_listener_add_address() that
462    /// creates a TCP/IP socket listening on IPv4 and IPv6 (if
463    /// supported) on the specified port on all interfaces.
464    ///
465    /// If possible, the [`SocketListener`][crate::SocketListener] will listen on both IPv4 and
466    /// IPv6 (listening on the same port on both). If listening on one of the socket
467    /// families fails, the [`SocketListener`][crate::SocketListener] will only listen on the other.
468    /// If listening on both fails, an error will be returned.
469    ///
470    /// If you need to distinguish whether listening on IPv4 or IPv6 or both was
471    /// successful, connect to [`event`][struct@crate::SocketListener#event].
472    ///
473    /// @source_object will be passed out in the various calls
474    /// to accept to identify this particular source, which is
475    /// useful if you're listening on multiple addresses and do
476    /// different things depending on what address is connected to.
477    ///
478    /// Call g_socket_listener_close() to stop listening on @port; this will not
479    /// be done automatically when you drop your final reference to @self, as
480    /// references may be held internally.
481    /// ## `port`
482    /// an IP port number (non-zero)
483    /// ## `source_object`
484    /// Optional #GObject identifying this source
485    ///
486    /// # Returns
487    ///
488    /// [`true`] on success, [`false`] on error.
489    #[doc(alias = "g_socket_listener_add_inet_port")]
490    fn add_inet_port(
491        &self,
492        port: u16,
493        source_object: Option<&impl IsA<glib::Object>>,
494    ) -> Result<(), glib::Error> {
495        unsafe {
496            let mut error = std::ptr::null_mut();
497            let is_ok = ffi::g_socket_listener_add_inet_port(
498                self.as_ref().to_glib_none().0,
499                port,
500                source_object.map(|p| p.as_ref()).to_glib_none().0,
501                &mut error,
502            );
503            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
504            if error.is_null() {
505                Ok(())
506            } else {
507                Err(from_glib_full(error))
508            }
509        }
510    }
511
512    /// Adds @socket to the set of sockets that we try to accept
513    /// new clients from. The socket must be bound to a local
514    /// address and listened to.
515    ///
516    /// For parallel calls to [`SocketListener`][crate::SocketListener] methods to work, the socket
517    /// must be in non-blocking mode. (See [`blocking`][struct@crate::Socket#blocking].)
518    ///
519    /// @source_object will be passed out in the various calls
520    /// to accept to identify this particular source, which is
521    /// useful if you're listening on multiple addresses and do
522    /// different things depending on what address is connected to.
523    ///
524    /// The @socket will not be automatically closed when the @self is finalized
525    /// unless the listener held the final reference to the socket. Before GLib 2.42,
526    /// the @socket was automatically closed on finalization of the @self, even
527    /// if references to it were held elsewhere.
528    /// ## `socket`
529    /// a listening #GSocket
530    /// ## `source_object`
531    /// Optional #GObject identifying this source
532    ///
533    /// # Returns
534    ///
535    /// [`true`] on success, [`false`] on error.
536    #[doc(alias = "g_socket_listener_add_socket")]
537    fn add_socket(
538        &self,
539        socket: &impl IsA<Socket>,
540        source_object: Option<&impl IsA<glib::Object>>,
541    ) -> Result<(), glib::Error> {
542        unsafe {
543            let mut error = std::ptr::null_mut();
544            let is_ok = ffi::g_socket_listener_add_socket(
545                self.as_ref().to_glib_none().0,
546                socket.as_ref().to_glib_none().0,
547                source_object.map(|p| p.as_ref()).to_glib_none().0,
548                &mut error,
549            );
550            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
551            if error.is_null() {
552                Ok(())
553            } else {
554                Err(from_glib_full(error))
555            }
556        }
557    }
558
559    /// Closes all the sockets in the listener.
560    #[doc(alias = "g_socket_listener_close")]
561    fn close(&self) {
562        unsafe {
563            ffi::g_socket_listener_close(self.as_ref().to_glib_none().0);
564        }
565    }
566
567    /// Sets the listen backlog on the sockets in the listener. This must be called
568    /// before adding any sockets, addresses or ports to the #GSocketListener (for
569    /// example, by calling g_socket_listener_add_inet_port()) to be effective.
570    ///
571    /// See g_socket_set_listen_backlog() for details
572    /// ## `listen_backlog`
573    /// an integer
574    #[doc(alias = "g_socket_listener_set_backlog")]
575    fn set_backlog(&self, listen_backlog: i32) {
576        unsafe {
577            ffi::g_socket_listener_set_backlog(self.as_ref().to_glib_none().0, listen_backlog);
578        }
579    }
580
581    /// The number of outstanding connections in the listen queue.
582    #[doc(alias = "listen-backlog")]
583    fn listen_backlog(&self) -> i32 {
584        ObjectExt::property(self.as_ref(), "listen-backlog")
585    }
586
587    /// The number of outstanding connections in the listen queue.
588    #[doc(alias = "listen-backlog")]
589    fn set_listen_backlog(&self, listen_backlog: i32) {
590        ObjectExt::set_property(self.as_ref(), "listen-backlog", listen_backlog)
591    }
592
593    /// Emitted when @listener's activity on @socket changes state.
594    /// Note that when @listener is used to listen on both IPv4 and
595    /// IPv6, a separate set of signals will be emitted for each, and
596    /// the order they happen in is undefined.
597    /// ## `event`
598    /// the event that is occurring
599    /// ## `socket`
600    /// the #GSocket the event is occurring on
601    #[doc(alias = "event")]
602    fn connect_event<F: Fn(&Self, SocketListenerEvent, &Socket) + 'static>(
603        &self,
604        f: F,
605    ) -> SignalHandlerId {
606        unsafe extern "C" fn event_trampoline<
607            P: IsA<SocketListener>,
608            F: Fn(&P, SocketListenerEvent, &Socket) + 'static,
609        >(
610            this: *mut ffi::GSocketListener,
611            event: ffi::GSocketListenerEvent,
612            socket: *mut ffi::GSocket,
613            f: glib::ffi::gpointer,
614        ) {
615            unsafe {
616                let f: &F = &*(f as *const F);
617                f(
618                    SocketListener::from_glib_borrow(this).unsafe_cast_ref(),
619                    from_glib(event),
620                    &from_glib_borrow(socket),
621                )
622            }
623        }
624        unsafe {
625            let f: Box_<F> = Box_::new(f);
626            connect_raw(
627                self.as_ptr() as *mut _,
628                c"event".as_ptr(),
629                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
630                    event_trampoline::<Self, F> as *const (),
631                )),
632                Box_::into_raw(f),
633            )
634        }
635    }
636
637    #[doc(alias = "listen-backlog")]
638    fn connect_listen_backlog_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
639        unsafe extern "C" fn notify_listen_backlog_trampoline<
640            P: IsA<SocketListener>,
641            F: Fn(&P) + 'static,
642        >(
643            this: *mut ffi::GSocketListener,
644            _param_spec: glib::ffi::gpointer,
645            f: glib::ffi::gpointer,
646        ) {
647            unsafe {
648                let f: &F = &*(f as *const F);
649                f(SocketListener::from_glib_borrow(this).unsafe_cast_ref())
650            }
651        }
652        unsafe {
653            let f: Box_<F> = Box_::new(f);
654            connect_raw(
655                self.as_ptr() as *mut _,
656                c"notify::listen-backlog".as_ptr(),
657                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
658                    notify_listen_backlog_trampoline::<Self, F> as *const (),
659                )),
660                Box_::into_raw(f),
661            )
662        }
663    }
664}
665
666impl<O: IsA<SocketListener>> SocketListenerExt for O {}