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 {}