1use std::{
4 fmt,
5 os::unix::{
6 io::{AsRawFd, BorrowedFd, OwnedFd, RawFd},
7 net::UnixStream,
8 },
9 sync::{Arc, Condvar, Mutex, MutexGuard, Weak},
10};
11
12use crate::{
13 core_interfaces::WL_DISPLAY_INTERFACE,
14 debug,
15 protocol::{
16 check_for_signature, same_interface, same_interface_or_anonymous, AllowNull, Argument,
17 ArgumentType, Interface, Message, ObjectInfo, ProtocolError, ANONYMOUS_INTERFACE,
18 INLINE_ARGS,
19 },
20};
21use smallvec::SmallVec;
22
23use super::{
24 client::*,
25 map::{Object, ObjectMap, SERVER_ID_LIMIT},
26 socket::{BufferedSocket, Socket},
27 wire::MessageParseError,
28};
29
30#[derive(Debug, Clone)]
31struct Data {
32 client_destroyed: bool,
33 server_destroyed: bool,
34 user_data: Arc<dyn ObjectData>,
35 serial: u32,
36}
37
38#[derive(Clone)]
40pub struct InnerObjectId {
41 serial: u32,
42 id: u32,
43 interface: &'static Interface,
44}
45
46impl std::cmp::PartialEq for InnerObjectId {
47 fn eq(&self, other: &Self) -> bool {
48 self.id == other.id
49 && self.serial == other.serial
50 && same_interface(self.interface, other.interface)
51 }
52}
53
54impl std::cmp::Eq for InnerObjectId {}
55
56impl std::hash::Hash for InnerObjectId {
57 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
58 self.serial.hash(state);
59 self.id.hash(state);
60 }
61}
62
63impl fmt::Display for InnerObjectId {
64 #[cfg_attr(unstable_coverage, coverage(off))]
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 write!(f, "{}@{}", self.interface.name, self.id)
67 }
68}
69
70impl fmt::Debug for InnerObjectId {
71 #[cfg_attr(unstable_coverage, coverage(off))]
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "ObjectId({}, {})", self, self.serial)
74 }
75}
76
77impl InnerObjectId {
78 pub fn is_null(&self) -> bool {
79 self.id == 0
80 }
81
82 pub fn interface(&self) -> &'static Interface {
83 self.interface
84 }
85
86 pub fn protocol_id(&self) -> u32 {
87 self.id
88 }
89}
90
91#[derive(Debug)]
92struct ProtocolState {
93 socket: BufferedSocket,
94 map: ObjectMap<Data>,
95 last_error: Option<WaylandError>,
96 last_serial: u32,
97 debug: bool,
98}
99
100#[derive(Debug)]
101struct ReadingState {
102 prepared_reads: usize,
103 read_condvar: Arc<Condvar>,
104 read_serial: usize,
105}
106
107#[derive(Debug)]
108pub struct ConnectionState {
109 protocol: Mutex<ProtocolState>,
110 read: Mutex<ReadingState>,
111}
112
113impl ConnectionState {
114 fn lock_protocol(&self) -> MutexGuard<'_, ProtocolState> {
115 self.protocol.lock().unwrap()
116 }
117
118 fn lock_read(&self) -> MutexGuard<'_, ReadingState> {
119 self.read.lock().unwrap()
120 }
121}
122
123#[derive(Clone, Debug)]
124pub struct InnerBackend {
125 state: Arc<ConnectionState>,
126}
127
128#[derive(Clone, Debug)]
129pub struct WeakInnerBackend {
130 state: Weak<ConnectionState>,
131}
132
133impl WeakInnerBackend {
134 pub fn upgrade(&self) -> Option<InnerBackend> {
135 Weak::upgrade(&self.state).map(|state| InnerBackend { state })
136 }
137}
138
139impl PartialEq for InnerBackend {
140 fn eq(&self, rhs: &Self) -> bool {
141 Arc::ptr_eq(&self.state, &rhs.state)
142 }
143}
144
145impl Eq for InnerBackend {}
146
147impl InnerBackend {
148 pub fn downgrade(&self) -> WeakInnerBackend {
149 WeakInnerBackend { state: Arc::downgrade(&self.state) }
150 }
151
152 pub fn connect(stream: UnixStream) -> Result<Self, NoWaylandLib> {
153 let socket = BufferedSocket::new(Socket::from(stream), None);
154 let mut map = ObjectMap::new();
155 map.insert_at(
156 1,
157 Object {
158 interface: &WL_DISPLAY_INTERFACE,
159 version: 1,
160 data: Data {
161 client_destroyed: false,
162 server_destroyed: false,
163 user_data: Arc::new(DumbObjectData),
164 serial: 0,
165 },
166 },
167 )
168 .unwrap();
169
170 let debug = debug::has_debug_client_env();
171
172 Ok(Self {
173 state: Arc::new(ConnectionState {
174 protocol: Mutex::new(ProtocolState {
175 socket,
176 map,
177 last_error: None,
178 last_serial: 0,
179 debug,
180 }),
181 read: Mutex::new(ReadingState {
182 prepared_reads: 0,
183 read_condvar: Arc::new(Condvar::new()),
184 read_serial: 0,
185 }),
186 }),
187 })
188 }
189
190 pub fn flush(&self) -> Result<(), WaylandError> {
192 let mut guard = self.state.lock_protocol();
193 guard.no_last_error()?;
194 if let Err(e) = guard.socket.flush() {
195 return Err(guard.store_if_not_wouldblock_and_return_error(e));
196 }
197 Ok(())
198 }
199
200 pub fn poll_fd(&self) -> BorrowedFd<'_> {
201 let raw_fd = self.state.lock_protocol().socket.as_raw_fd();
202 unsafe { BorrowedFd::borrow_raw(raw_fd) }
205 }
206}
207
208#[derive(Debug)]
209pub struct InnerReadEventsGuard {
210 state: Arc<ConnectionState>,
211 done: bool,
212}
213
214impl InnerReadEventsGuard {
215 pub fn try_new(backend: InnerBackend) -> Option<Self> {
220 backend.state.lock_read().prepared_reads += 1;
221 Some(Self { state: backend.state, done: false })
222 }
223
224 pub fn connection_fd(&self) -> BorrowedFd<'_> {
226 let raw_fd = self.state.lock_protocol().socket.as_raw_fd();
227 unsafe { BorrowedFd::borrow_raw(raw_fd) }
230 }
231
232 pub fn read(mut self) -> Result<usize, WaylandError> {
242 let mut guard = self.state.lock_read();
243 guard.prepared_reads -= 1;
244 self.done = true;
245 if guard.prepared_reads == 0 {
246 let ret = dispatch_events(self.state.clone());
248 guard.read_serial = guard.read_serial.wrapping_add(1);
250 guard.read_condvar.notify_all();
251 ret
253 } else {
254 let serial = guard.read_serial;
256 let condvar = guard.read_condvar.clone();
257 let _guard =
258 condvar.wait_while(guard, |backend| serial == backend.read_serial).unwrap();
259 self.state.lock_protocol().no_last_error()?;
260 Ok(0)
261 }
262 }
263}
264
265impl Drop for InnerReadEventsGuard {
266 fn drop(&mut self) {
267 if !self.done {
268 let mut guard = self.state.lock_read();
269 guard.prepared_reads -= 1;
270 if guard.prepared_reads == 0 {
271 guard.read_serial = guard.read_serial.wrapping_add(1);
273 guard.read_condvar.notify_all();
274 }
275 }
276 }
277}
278
279impl InnerBackend {
280 pub fn display_id(&self) -> ObjectId {
281 ObjectId { id: InnerObjectId { serial: 0, id: 1, interface: &WL_DISPLAY_INTERFACE } }
282 }
283
284 pub fn last_error(&self) -> Option<WaylandError> {
285 self.state.lock_protocol().last_error.clone()
286 }
287
288 pub fn info(&self, id: ObjectId) -> Result<ObjectInfo, InvalidId> {
289 let object = self.state.lock_protocol().get_object(id.id.clone())?;
290 if object.data.client_destroyed {
291 Err(InvalidId)
292 } else {
293 Ok(ObjectInfo { id: id.id.id, interface: object.interface, version: object.version })
294 }
295 }
296
297 pub fn null_id() -> ObjectId {
298 ObjectId { id: InnerObjectId { serial: 0, id: 0, interface: &ANONYMOUS_INTERFACE } }
299 }
300
301 pub fn destroy_object(&self, id: &ObjectId) -> Result<(), InvalidId> {
302 let mut guard = self.state.lock_protocol();
303 let object = guard.get_object(id.id.clone())?;
304 guard
305 .map
306 .with(id.id.id, |obj| {
307 if obj.data.client_destroyed {
308 return Err(InvalidId);
309 }
310 obj.data.client_destroyed = true;
311 Ok(())
312 })
313 .unwrap()?;
314 object.data.user_data.destroyed(id.clone());
315 Ok(())
316 }
317
318 pub fn send_request(
319 &self,
320 Message { sender_id: ObjectId { id }, opcode, args }: Message<ObjectId, RawFd>,
321 data: Option<Arc<dyn ObjectData>>,
322 child_spec: Option<(&'static Interface, u32)>,
323 ) -> Result<ObjectId, InvalidId> {
324 let mut guard = self.state.lock_protocol();
325 let object = guard.get_object(id.clone())?;
326
327 let message_desc = match object.interface.requests.get(opcode as usize) {
328 Some(msg) => msg,
329 None => {
330 panic!("Unknown opcode {} for object {}@{}.", opcode, object.interface.name, id.id);
331 }
332 };
333
334 if object.data.client_destroyed {
335 if guard.debug {
336 debug::print_send_message(id.interface.name, id.id, message_desc.name, &args, true);
337 }
338 return Err(InvalidId);
339 }
340
341 if !check_for_signature(message_desc.signature, &args) {
342 panic!(
343 "Unexpected signature for request {}@{}.{}: expected {:?}, got {:?}.",
344 object.interface.name, id.id, message_desc.name, message_desc.signature, args
345 );
346 }
347
348 let child_spec = if message_desc
350 .signature
351 .iter()
352 .any(|arg| matches!(arg, ArgumentType::NewId))
353 {
354 if let Some((iface, version)) = child_spec {
355 if let Some(child_interface) = message_desc.child_interface {
356 if !same_interface(child_interface, iface) {
357 panic!(
358 "Error when sending request {}@{}.{}: expected interface {} but got {}",
359 object.interface.name,
360 id.id,
361 message_desc.name,
362 child_interface.name,
363 iface.name
364 );
365 }
366 if version != object.version {
367 panic!(
368 "Error when sending request {}@{}.{}: expected version {} but got {}",
369 object.interface.name,
370 id.id,
371 message_desc.name,
372 object.version,
373 version
374 );
375 }
376 }
377 Some((iface, version))
378 } else if let Some(child_interface) = message_desc.child_interface {
379 Some((child_interface, object.version))
380 } else {
381 panic!(
382 "Error when sending request {}@{}.{}: target interface must be specified for a generic constructor.",
383 object.interface.name,
384 id.id,
385 message_desc.name
386 );
387 }
388 } else {
389 None
390 };
391
392 let child = if let Some((child_interface, child_version)) = child_spec {
393 let child_serial = guard.next_serial();
394
395 let child = Object {
396 interface: child_interface,
397 version: child_version,
398 data: Data {
399 client_destroyed: false,
400 server_destroyed: false,
401 user_data: Arc::new(DumbObjectData),
402 serial: child_serial,
403 },
404 };
405
406 let child_id = guard.map.client_insert_new(child);
407
408 guard
409 .map
410 .with(child_id, |obj| {
411 obj.data.user_data = data.expect(
412 "Sending a request creating an object without providing an object data.",
413 );
414 })
415 .unwrap();
416 Some((child_id, child_serial, child_interface))
417 } else {
418 None
419 };
420
421 let args = args.into_iter().map(|arg| {
423 if let Argument::NewId(ObjectId { id: p }) = arg {
424 if p.id != 0 {
425 panic!("The newid provided when sending request {}@{}.{} is not a placeholder.", object.interface.name, id.id, message_desc.name);
426 }
427 if let Some((child_id, child_serial, child_interface)) = child {
428 Argument::NewId(ObjectId { id: InnerObjectId { id: child_id, serial: child_serial, interface: child_interface}})
429 } else {
430 unreachable!();
431 }
432 } else {
433 arg
434 }
435 }).collect::<SmallVec<[_; INLINE_ARGS]>>();
436
437 if guard.debug {
438 debug::print_send_message(
439 object.interface.name,
440 id.id,
441 message_desc.name,
442 &args,
443 false,
444 );
445 }
446 #[cfg(feature = "log")]
447 crate::log_debug!("Sending {}.{} ({})", id, message_desc.name, debug::DisplaySlice(&args));
448
449 let mut msg_args = SmallVec::with_capacity(args.len());
452 let mut arg_interfaces = message_desc.arg_interfaces.iter();
453 for (i, arg) in args.into_iter().enumerate() {
454 msg_args.push(match arg {
455 Argument::Array(a) => Argument::Array(a),
456 Argument::Int(i) => Argument::Int(i),
457 Argument::Uint(u) => Argument::Uint(u),
458 Argument::Str(s) => Argument::Str(s),
459 Argument::Fixed(f) => Argument::Fixed(f),
460 Argument::NewId(nid) => Argument::NewId(nid.id.id),
461 Argument::Fd(f) => Argument::Fd(f),
462 Argument::Object(o) => {
463 let next_interface = arg_interfaces.next().unwrap();
464 if o.id.id != 0 {
465 let arg_object = guard.get_object(o.id.clone())?;
466 if arg_object.data.client_destroyed {
467 return Err(InvalidId);
468 }
469 if !same_interface_or_anonymous(next_interface, arg_object.interface) {
470 panic!("Request {}@{}.{} expects an argument of interface {} but {} was provided instead.", object.interface.name, id.id, message_desc.name, next_interface.name, arg_object.interface.name);
471 }
472 } else if !matches!(message_desc.signature[i], ArgumentType::Object(AllowNull::Yes)) {
473 panic!("Request {}@{}.{} expects an non-null object argument.", object.interface.name, id.id, message_desc.name);
474 }
475 Argument::Object(o.id.id)
476 }
477 });
478 }
479
480 let msg = Message { sender_id: id.id, opcode, args: msg_args };
481
482 if let Err(err) = guard.socket.write_message(&msg) {
483 guard.last_error = Some(WaylandError::Io(err));
484 }
485
486 if message_desc.is_destructor {
488 guard
489 .map
490 .with(id.id, |obj| {
491 obj.data.client_destroyed = true;
492 })
493 .unwrap();
494 object.data.user_data.destroyed(ObjectId { id });
495 }
496 if let Some((child_id, child_serial, child_interface)) = child {
497 Ok(ObjectId {
498 id: InnerObjectId {
499 id: child_id,
500 serial: child_serial,
501 interface: child_interface,
502 },
503 })
504 } else {
505 Ok(Self::null_id())
506 }
507 }
508
509 pub fn get_data(&self, id: ObjectId) -> Result<Arc<dyn ObjectData>, InvalidId> {
510 let object = self.state.lock_protocol().get_object(id.id)?;
511 Ok(object.data.user_data)
512 }
513
514 pub fn set_data(&self, id: ObjectId, data: Arc<dyn ObjectData>) -> Result<(), InvalidId> {
515 self.state
516 .lock_protocol()
517 .map
518 .with(id.id.id, move |objdata| {
519 if objdata.data.serial != id.id.serial {
520 Err(InvalidId)
521 } else {
522 objdata.data.user_data = data;
523 Ok(())
524 }
525 })
526 .unwrap_or(Err(InvalidId))
527 }
528
529 pub fn dispatch_inner_queue(&self) -> Result<usize, WaylandError> {
531 Ok(0)
532 }
533
534 #[allow(dead_code)]
535 pub fn set_max_buffer_size(&self, max_buffer_size: Option<usize>) {
536 let mut guard = self.state.lock_protocol();
537 guard.socket.set_max_buffer_size(max_buffer_size);
538 }
539}
540
541impl ProtocolState {
542 fn next_serial(&mut self) -> u32 {
543 self.last_serial = self.last_serial.wrapping_add(1);
544 self.last_serial
545 }
546
547 #[inline]
548 fn no_last_error(&self) -> Result<(), WaylandError> {
549 if let Some(ref err) = self.last_error {
550 Err(err.clone())
551 } else {
552 Ok(())
553 }
554 }
555
556 #[inline]
557 fn store_and_return_error(&mut self, err: impl Into<WaylandError>) -> WaylandError {
558 let err = err.into();
559 crate::log_error!("{err}");
560 self.last_error = Some(err.clone());
561 err
562 }
563
564 #[inline]
565 fn store_if_not_wouldblock_and_return_error(&mut self, e: std::io::Error) -> WaylandError {
566 if e.kind() != std::io::ErrorKind::WouldBlock {
567 self.store_and_return_error(e)
568 } else {
569 e.into()
570 }
571 }
572
573 fn get_object(&self, id: InnerObjectId) -> Result<Object<Data>, InvalidId> {
574 let object = self.map.find(id.id).ok_or(InvalidId)?;
575 if object.data.serial != id.serial {
576 return Err(InvalidId);
577 }
578 Ok(object)
579 }
580
581 fn handle_display_event(&mut self, message: Message<u32, OwnedFd>) -> Result<(), WaylandError> {
582 if self.debug {
583 debug::print_dispatched_message(
584 "wl_display",
585 message.sender_id,
586 if message.opcode == 0 { "error" } else { "delete_id" },
587 &message.args,
588 );
589 }
590 match message.opcode {
591 0 => {
592 if let [Argument::Object(obj), Argument::Uint(code), Argument::Str(Some(ref message))] =
594 message.args[..]
595 {
596 let object = self.map.find(obj);
597 let err = WaylandError::Protocol(ProtocolError {
598 code,
599 object_id: obj,
600 object_interface: object
601 .map(|obj| obj.interface.name)
602 .unwrap_or("<unknown>")
603 .into(),
604 message: message.to_string_lossy().into(),
605 });
606 return Err(self.store_and_return_error(err));
607 } else {
608 unreachable!()
609 }
610 }
611 1 => {
612 if let [Argument::Uint(id)] = message.args[..] {
614 let client_destroyed = self
615 .map
616 .with(id, |obj| {
617 obj.data.server_destroyed = true;
618 obj.data.client_destroyed
619 })
620 .unwrap_or(false);
621 if client_destroyed {
622 self.map.remove(id);
623 }
624 } else {
625 unreachable!()
626 }
627 }
628 _ => unreachable!(),
629 }
630 Ok(())
631 }
632}
633
634fn dispatch_events(state: Arc<ConnectionState>) -> Result<usize, WaylandError> {
635 let backend = Backend { backend: InnerBackend { state } };
636 let mut guard = backend.backend.state.lock_protocol();
637 guard.no_last_error()?;
638 let mut dispatched = 0;
639 loop {
640 let ProtocolState { ref mut socket, ref map, .. } = *guard;
642 let message = match socket.read_one_message(|id, opcode| {
643 map.find(id)
644 .and_then(|o| o.interface.events.get(opcode as usize))
645 .map(|desc| desc.signature)
646 }) {
647 Ok(msg) => msg,
648 Err(MessageParseError::MissingData) | Err(MessageParseError::MissingFD) => {
649 if let Err(e) = guard.socket.fill_incoming_buffers() {
651 if e.kind() != std::io::ErrorKind::WouldBlock {
652 return Err(guard.store_and_return_error(e));
653 } else if dispatched == 0 {
654 return Err(e.into());
655 } else {
656 break;
657 }
658 }
659 continue;
660 }
661 Err(MessageParseError::Malformed) => {
662 let err = WaylandError::Protocol(ProtocolError {
664 code: 0,
665 object_id: 0,
666 object_interface: "".into(),
667 message: "Malformed Wayland message.".into(),
668 });
669 return Err(guard.store_and_return_error(err));
670 }
671 };
672
673 let receiver = guard.map.find(message.sender_id).unwrap();
676 let message_desc = receiver.interface.events.get(message.opcode as usize).unwrap();
677
678 if message.sender_id == 1 {
680 guard.handle_display_event(message)?;
681 continue;
682 }
683
684 let mut created_id = None;
685
686 let mut args = SmallVec::with_capacity(message.args.len());
688 let mut arg_interfaces = message_desc.arg_interfaces.iter();
689 for arg in message.args.into_iter() {
690 args.push(match arg {
691 Argument::Array(a) => Argument::Array(a),
692 Argument::Int(i) => Argument::Int(i),
693 Argument::Uint(u) => Argument::Uint(u),
694 Argument::Str(s) => Argument::Str(s),
695 Argument::Fixed(f) => Argument::Fixed(f),
696 Argument::Fd(f) => Argument::Fd(f),
697 Argument::Object(o) => {
698 if o != 0 {
699 let obj = match guard.map.find(o) {
701 Some(o) => o,
702 None => {
703 let err = WaylandError::Protocol(ProtocolError {
704 code: 0,
705 object_id: 0,
706 object_interface: "".into(),
707 message: format!("Unknown object {o}."),
708 });
709 return Err(guard.store_and_return_error(err));
710 }
711 };
712 if let Some(next_interface) = arg_interfaces.next() {
713 if !same_interface_or_anonymous(next_interface, obj.interface) {
714 let err = WaylandError::Protocol(ProtocolError {
715 code: 0,
716 object_id: 0,
717 object_interface: "".into(),
718 message: format!(
719 "Protocol error: server sent object {} for interface {}, but it has interface {}.",
720 o, next_interface.name, obj.interface.name
721 ),
722 });
723 return Err(guard.store_and_return_error(err));
724 }
725 }
726 Argument::Object(ObjectId { id: InnerObjectId { id: o, serial: obj.data.serial, interface: obj.interface }})
727 } else {
728 Argument::Object(ObjectId { id: InnerObjectId { id: 0, serial: 0, interface: &ANONYMOUS_INTERFACE }})
729 }
730 }
731 Argument::NewId(new_id) => {
732 let child_interface = match message_desc.child_interface {
734 Some(iface) => iface,
735 None => panic!("Received event {}@{}.{} which creates an object without specifying its interface, this is unsupported.", receiver.interface.name, message.sender_id, message_desc.name),
736 };
737
738 let child_udata = Arc::new(UninitObjectData);
739
740 if new_id >= SERVER_ID_LIMIT
742 && guard.map.with(new_id, |obj| obj.data.client_destroyed).unwrap_or(false)
743 {
744 guard.map.remove(new_id);
745 }
746
747 let child_obj = Object {
748 interface: child_interface,
749 version: receiver.version,
750 data: Data {
751 client_destroyed: receiver.data.client_destroyed,
752 server_destroyed: false,
753 user_data: child_udata,
754 serial: guard.next_serial(),
755 }
756 };
757
758 let child_id = InnerObjectId { id: new_id, serial: child_obj.data.serial, interface: child_obj.interface };
759 created_id = Some(child_id.clone());
760
761 if let Err(()) = guard.map.insert_at(new_id, child_obj) {
762 let err = WaylandError::Protocol(ProtocolError {
764 code: 0,
765 object_id: 0,
766 object_interface: "".into(),
767 message: format!(
768 "Protocol error: server tried to create \
769 an object \"{}\" with invalid id {}.",
770 child_interface.name, new_id
771 ),
772 });
773 return Err(guard.store_and_return_error(err));
774 }
775
776 Argument::NewId(ObjectId { id: child_id })
777 }
778 });
779 }
780
781 if guard.debug {
782 debug::print_dispatched_message(
783 receiver.interface.name,
784 message.sender_id,
785 message_desc.name,
786 &args,
787 );
788 }
789
790 if receiver.data.client_destroyed {
792 continue;
793 }
794
795 let id = InnerObjectId {
797 id: message.sender_id,
798 serial: receiver.data.serial,
799 interface: receiver.interface,
800 };
801
802 std::mem::drop(guard);
804 #[cfg(feature = "log")]
805 crate::log_debug!(
806 "Dispatching {}.{} ({})",
807 id,
808 receiver.version,
809 debug::DisplaySlice(&args)
810 );
811 let ret = receiver
812 .data
813 .user_data
814 .clone()
815 .event(&backend, Message { sender_id: ObjectId { id }, opcode: message.opcode, args });
816 guard = backend.backend.state.lock_protocol();
818
819 if message_desc.is_destructor {
821 guard
822 .map
823 .with(message.sender_id, |obj| {
824 obj.data.server_destroyed = true;
825 obj.data.client_destroyed = true;
826 })
827 .unwrap();
828 receiver.data.user_data.destroyed(ObjectId {
829 id: InnerObjectId {
830 id: message.sender_id,
831 serial: receiver.data.serial,
832 interface: receiver.interface,
833 },
834 });
835 }
836
837 match (created_id, ret) {
838 (Some(child_id), Some(child_data)) => {
839 guard.map.with(child_id.id, |obj| obj.data.user_data = child_data).unwrap();
840 }
841 (None, None) => {}
842 (Some(child_id), None) => {
843 panic!("Callback creating object {child_id} did not provide any object data.");
844 }
845 (None, Some(_)) => {
846 panic!("An object data was returned from a callback not creating any object");
847 }
848 }
849
850 dispatched += 1;
851 }
852 Ok(dispatched)
853}