1use {
4 crate::{
5 client::Client,
6 endpoint::Endpoint,
7 handler::{HandlerAccessError, HandlerMut, HandlerRef},
8 protocols::ObjectInterface,
9 state::State,
10 },
11 debug_fn::debug_fn,
12 error_reporter::Report,
13 std::{
14 any::Any,
15 cell::{Cell, RefCell},
16 collections::{VecDeque, hash_map::Entry},
17 fmt::{Debug, Display},
18 os::fd::OwnedFd,
19 rc::{Rc, Weak},
20 },
21 thiserror::Error,
22};
23
24#[cfg(test)]
25mod tests;
26
27pub(crate) trait ObjectPrivate: Any {
28 fn new(state: &Rc<State>, version: u32) -> Rc<Self>
29 where
30 Self: Sized;
31 fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)>;
32 fn handle_request(
33 self: Rc<Self>,
34 client: &Rc<Client>,
35 msg: &[u32],
36 fds: &mut VecDeque<Rc<OwnedFd>>,
37 ) -> Result<(), ObjectError>;
38 fn handle_event(
39 self: Rc<Self>,
40 server: &Endpoint,
41 msg: &[u32],
42 fds: &mut VecDeque<Rc<OwnedFd>>,
43 ) -> Result<(), ObjectError>;
44 fn get_request_name(&self, id: u32) -> Option<&'static str>;
45 fn get_event_name(&self, id: u32) -> Option<&'static str>;
46}
47
48#[expect(private_bounds)]
52pub trait Object: Debug + ObjectPrivate {
53 fn core(&self) -> &ObjectCore;
55 fn unset_handler(&self);
62 fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError>;
64 fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError>;
66}
67
68pub trait ConcreteObject: Object {
70 const XML_VERSION: u32;
72 const INTERFACE: ObjectInterface;
74 const INTERFACE_NAME: &str;
76}
77
78pub trait ObjectCoreApi {
80 fn state(&self) -> &Rc<State>;
82
83 fn client(&self) -> Option<Rc<Client>>;
85
86 fn create_child<P>(&self) -> Rc<P>
101 where
102 P: Object;
103
104 fn interface(&self) -> ObjectInterface;
106
107 fn version(&self) -> u32;
109
110 fn unique_id(&self) -> u64;
116
117 fn client_id(&self) -> Option<u32>;
119
120 fn server_id(&self) -> Option<u32>;
122
123 fn delete_id(&self);
128
129 fn try_delete_id(&self) -> Result<(), ObjectError>;
134
135 fn set_forward_to_client(&self, enabled: bool);
139
140 fn set_forward_to_server(&self, enabled: bool);
144}
145
146impl ObjectCoreApi for ObjectCore {
147 fn state(&self) -> &Rc<State> {
148 &self.state
149 }
150
151 fn client(&self) -> Option<Rc<Client>> {
152 self.client.borrow().clone()
153 }
154
155 fn create_child<P>(&self) -> Rc<P>
156 where
157 P: Object,
158 {
159 self.state.create_object::<P>(self.version)
160 }
161
162 fn interface(&self) -> ObjectInterface {
163 self.interface
164 }
165
166 fn version(&self) -> u32 {
167 self.version
168 }
169
170 fn unique_id(&self) -> u64 {
171 self.id
172 }
173
174 fn client_id(&self) -> Option<u32> {
175 self.client_obj_id.get()
176 }
177
178 fn server_id(&self) -> Option<u32> {
179 self.server_obj_id.get()
180 }
181
182 fn delete_id(&self) {
183 if let Err(e) = self.try_delete_id() {
184 log::warn!("Could not release a client id: {}", Report::new(e));
185 }
186 }
187
188 fn try_delete_id(&self) -> Result<(), ObjectError> {
189 if !self.awaiting_delete_id.replace(false) {
190 if self.client.borrow().is_some() {
191 return Err(ObjectError(ObjectErrorKind::NotAwaitingDeleteId));
192 }
193 return Ok(());
194 }
195 let Some(id) = self.client_obj_id.take() else {
196 return Ok(());
197 };
198 self.client_id.take();
199 let Some(client) = self.client.take() else {
200 return Ok(());
201 };
202 let object = client.endpoint.objects.borrow_mut().remove(&id);
203 drop(object);
204 client.display.try_send_delete_id(id)
205 }
206
207 fn set_forward_to_client(&self, enabled: bool) {
208 self.forward_to_client.set(enabled);
209 }
210
211 fn set_forward_to_server(&self, enabled: bool) {
212 self.forward_to_server.set(enabled);
213 }
214}
215
216impl<T> ObjectCoreApi for T
217where
218 T: Object + ?Sized,
219{
220 fn state(&self) -> &Rc<State> {
221 self.core().state()
222 }
223
224 fn client(&self) -> Option<Rc<Client>> {
225 self.core().client()
226 }
227
228 fn create_child<P>(&self) -> Rc<P>
229 where
230 P: Object,
231 {
232 self.core().create_child()
233 }
234
235 fn interface(&self) -> ObjectInterface {
236 self.core().interface()
237 }
238
239 fn version(&self) -> u32 {
240 self.core().version()
241 }
242
243 fn unique_id(&self) -> u64 {
244 self.core().unique_id()
245 }
246
247 fn client_id(&self) -> Option<u32> {
248 self.core().client_id()
249 }
250
251 fn server_id(&self) -> Option<u32> {
252 self.core().server_id()
253 }
254
255 fn delete_id(&self) {
256 self.core().delete_id()
257 }
258
259 fn try_delete_id(&self) -> Result<(), ObjectError> {
260 self.core().try_delete_id()
261 }
262
263 fn set_forward_to_client(&self, enabled: bool) {
264 self.core().set_forward_to_client(enabled);
265 }
266
267 fn set_forward_to_server(&self, enabled: bool) {
268 self.core().set_forward_to_server(enabled);
269 }
270}
271
272pub trait ObjectUtils: Object {
274 fn try_get_handler_ref<T>(&self) -> Result<HandlerRef<'_, T>, HandlerAccessError>
276 where
277 T: 'static,
278 {
279 let handler = self.get_handler_any_ref()?;
280 handler
281 .downcast_ref::<T>()
282 .ok_or(HandlerAccessError::InvalidType)?;
283 Ok(HandlerRef::map(handler, |h| unsafe {
285 &*(h as *const dyn Any as *const T)
286 }))
287 }
288
289 fn get_handler_ref<T>(&self) -> HandlerRef<'_, T>
293 where
294 T: 'static,
295 {
296 self.try_get_handler_ref().map_err(Report::new).unwrap()
297 }
298
299 fn try_get_handler_mut<T>(&self) -> Result<HandlerMut<'_, T>, HandlerAccessError>
301 where
302 T: 'static,
303 {
304 let mut handler = self.get_handler_any_mut()?;
305 handler
306 .downcast_mut::<T>()
307 .ok_or(HandlerAccessError::InvalidType)?;
308 Ok(HandlerMut::map(handler, |h| unsafe {
310 &mut *(h as *mut dyn Any as *mut T)
311 }))
312 }
313
314 fn get_handler_mut<T>(&self) -> HandlerMut<'_, T>
318 where
319 T: 'static,
320 {
321 self.try_get_handler_mut().map_err(Report::new).unwrap()
322 }
323}
324
325impl<T> ObjectUtils for T where T: Object + ?Sized {}
326
327pub trait ObjectRcUtils {
329 fn try_downcast<T>(&self) -> Option<Rc<T>>
331 where
332 T: ConcreteObject;
333
334 fn downcast<T>(&self) -> Rc<T>
338 where
339 T: ConcreteObject;
340}
341
342impl ObjectRcUtils for Rc<dyn Object> {
343 fn try_downcast<T>(&self) -> Option<Rc<T>>
344 where
345 T: ConcreteObject,
346 {
347 (self.clone() as Rc<dyn Any>).downcast().ok()
348 }
349
350 fn downcast<T>(&self) -> Rc<T>
351 where
352 T: ConcreteObject,
353 {
354 let Some(t) = self.try_downcast() else {
355 panic!(
356 "Tried to downcast {} to {}",
357 self.interface().name(),
358 T::INTERFACE_NAME,
359 );
360 };
361 t
362 }
363}
364
365pub struct ObjectCore {
369 pub(crate) state: Rc<State>,
370 id: u64,
371 pub(crate) interface: ObjectInterface,
372 pub(crate) version: u32,
373 pub(crate) forward_to_client: Cell<bool>,
374 pub(crate) forward_to_server: Cell<bool>,
375 pub(crate) awaiting_delete_id: Cell<bool>,
376 pub(crate) server_obj_id: Cell<Option<u32>>,
377 pub(crate) client_obj_id: Cell<Option<u32>>,
378 pub(crate) client_id: Cell<Option<u64>>,
379 pub(crate) client: RefCell<Option<Rc<Client>>>,
380}
381
382#[derive(Debug, Error)]
383pub(crate) enum IdError {
384 #[error("the state is already destroyed")]
385 StateDestroyed,
386 #[error("the client is already destroyed")]
387 ClientDestroyed,
388 #[error("object already has the server id {0}")]
389 HasServerId(u32),
390 #[error("the state does not have a server")]
391 NoServer,
392 #[error("there are no server ids available")]
393 NoServerSpace,
394 #[error("the id {0} is too small to be a server id")]
395 NotServerId(u32),
396 #[error("the server id {0} is already in use")]
397 ServerIdInUse(u32),
398 #[error("object already has the client id {0}")]
399 HasClientId(u32),
400 #[error("there are no client ids available")]
401 NoClientSpace,
402 #[error("the id {0} is too large to be a client id")]
403 NotClientId(u32),
404 #[error("the client id {0} is already in use")]
405 ClientIdInUse(u32),
406}
407
408const MIN_SERVER_ID: u32 = 0xff000000;
409
410impl ObjectCore {
411 pub(crate) fn new(
412 state: &Rc<State>,
413 slf: Weak<dyn Object>,
414 interface: ObjectInterface,
415 version: u32,
416 ) -> Self {
417 let object_id = state.next_object_id.get();
418 state.next_object_id.set(object_id + 1);
419 state.all_objects.borrow_mut().insert(object_id, slf);
420 Self {
421 state: state.clone(),
422 id: object_id,
423 interface,
424 version,
425 forward_to_client: Cell::new(state.forward_to_client.get()),
426 forward_to_server: Cell::new(state.forward_to_server.get()),
427 awaiting_delete_id: Default::default(),
428 server_obj_id: Default::default(),
429 client_obj_id: Default::default(),
430 client_id: Default::default(),
431 client: Default::default(),
432 }
433 }
434
435 fn check_server_destroyed(&self) -> Result<(), IdError> {
436 if self.state.destroyed.get() {
437 return Err(IdError::StateDestroyed);
438 }
439 Ok(())
440 }
441
442 pub(crate) fn generate_server_id(&self, slf: Rc<dyn Object>) -> Result<(), IdError> {
443 self.check_server_destroyed()?;
444 if let Some(id) = self.server_obj_id.get() {
445 return Err(IdError::HasServerId(id));
446 }
447 let Some(server) = &self.state.server else {
448 return Err(IdError::NoServer);
449 };
450 let id = server.idl.acquire();
451 if id >= MIN_SERVER_ID {
452 server.idl.release(id);
453 return Err(IdError::NoServerSpace);
454 }
455 self.server_obj_id.set(Some(id));
456 server.objects.borrow_mut().insert(id, slf);
457 Ok(())
458 }
459
460 pub(crate) fn set_server_id(&self, id: u32, slf: Rc<dyn Object>) -> Result<(), IdError> {
461 if id < MIN_SERVER_ID {
462 return Err(IdError::NotServerId(id));
463 }
464 self.set_server_id_unchecked(id, slf)
465 }
466
467 pub(crate) fn set_server_id_unchecked(
468 &self,
469 id: u32,
470 slf: Rc<dyn Object>,
471 ) -> Result<(), IdError> {
472 self.check_server_destroyed()?;
473 let Some(server) = &self.state.server else {
474 return Err(IdError::NoServer);
475 };
476 let objects = &mut *server.objects.borrow_mut();
477 let Entry::Vacant(entry) = objects.entry(id) else {
478 return Err(IdError::ServerIdInUse(id));
479 };
480 entry.insert(slf);
481 self.server_obj_id.set(Some(id));
482 Ok(())
483 }
484
485 fn check_client_destroyed(&self, client: &Client) -> Result<(), IdError> {
486 if client.destroyed.get() {
487 return Err(IdError::ClientDestroyed);
488 }
489 Ok(())
490 }
491
492 pub(crate) fn generate_client_id(
493 &self,
494 client: &Rc<Client>,
495 slf: Rc<dyn Object>,
496 ) -> Result<(), IdError> {
497 self.check_client_destroyed(client)?;
498 if let Some(id) = self.client_obj_id.get() {
499 return Err(IdError::HasClientId(id));
500 }
501 let id = client.endpoint.idl.acquire();
502 let Some(id) = MIN_SERVER_ID.checked_add(id) else {
503 client.endpoint.idl.release(id);
504 return Err(IdError::NoClientSpace);
505 };
506 client.endpoint.objects.borrow_mut().insert(id, slf);
507 self.set_client_id_(client, id);
508 Ok(())
509 }
510
511 pub(crate) fn set_client_id(
512 &self,
513 client: &Rc<Client>,
514 id: u32,
515 slf: Rc<dyn Object>,
516 ) -> Result<(), IdError> {
517 self.check_client_destroyed(client)?;
518 if id >= MIN_SERVER_ID {
519 return Err(IdError::NotClientId(id));
520 }
521 let objects = &mut *client.endpoint.objects.borrow_mut();
522 let Entry::Vacant(entry) = objects.entry(id) else {
523 return Err(IdError::ClientIdInUse(id));
524 };
525 entry.insert(slf);
526 self.set_client_id_(client, id);
527 Ok(())
528 }
529
530 fn set_client_id_(&self, client: &Rc<Client>, id: u32) {
531 self.client_obj_id.set(Some(id));
532 self.client_id.set(Some(client.endpoint.id));
533 *self.client.borrow_mut() = Some(client.clone());
534 }
535
536 pub(crate) fn handle_client_destroy(&self) {
537 let id = self.client_obj_id.get().unwrap();
538 if let Some(idl) = id.checked_sub(MIN_SERVER_ID) {
539 self.client_obj_id.take();
540 self.client_id.take();
541 let client = self.client.take().unwrap();
542 let object = client.endpoint.objects.borrow_mut().remove(&id);
543 drop(object);
544 client.endpoint.idl.release(idl);
545 } else {
546 self.awaiting_delete_id.set(true);
547 }
548 }
549
550 pub(crate) fn handle_server_destroy(&self) {
551 let id = self.server_obj_id.get().unwrap();
552 if id < MIN_SERVER_ID {
553 return;
554 }
555 self.server_obj_id.take();
556 let _object = self
557 .state
558 .server
559 .as_ref()
560 .unwrap()
561 .objects
562 .borrow_mut()
563 .remove(&id);
564 }
565}
566
567impl Drop for ObjectCore {
568 fn drop(&mut self) {
569 self.state.all_objects.borrow_mut().remove(&self.id);
570 }
571}
572
573#[derive(Debug, Error)]
575#[error(transparent)]
576pub struct ObjectError(#[from] pub(crate) ObjectErrorKind);
577
578#[derive(Debug, Error)]
579pub(crate) enum ObjectErrorKind {
580 #[error("could not generate a client id for argument {0}")]
581 GenerateClientId(&'static str, #[source] IdError),
582 #[error("could not generate a server id for argument {0}")]
583 GenerateServerId(&'static str, #[source] IdError),
584 #[error("could not assign client id {0} to argument {1}")]
585 SetClientId(u32, &'static str, #[source] IdError),
586 #[error("could not assign server id {0} to argument {1}")]
587 SetServerId(u32, &'static str, #[source] IdError),
588 #[error("client {0} has no object with id {1}")]
589 NoClientObject(u64, u32),
590 #[error("server has no object with id {0}")]
591 NoServerObject(u32),
592 #[error("argument {} has type {} but should have type {}", .0, .1.name(), .2.name())]
593 WrongObjectType(&'static str, ObjectInterface, ObjectInterface),
594 #[error("the requested version {} for interface {} is larger than the max version {}", .1, .0.name(), .0.xml_version())]
595 MaxVersion(ObjectInterface, u32),
596 #[error("the interface {0} is not supported")]
597 UnsupportedInterface(String),
598 #[error("the receiver has no server id")]
599 ReceiverNoServerId,
600 #[error("the receiver has no client")]
601 ReceiverNoClient,
602 #[error("the argument {0} is not associated with client {1}")]
603 ArgNoClientId(&'static str, u64),
604 #[error("the argument {0} has no server id")]
605 ArgNoServerId(&'static str),
606 #[error("the size of the message is {0} instead of {0}")]
607 WrongMessageSize(u32, u32),
608 #[error("unknown message id {0}")]
609 UnknownMessageId(u32),
610 #[error("the file descriptor for argument {0} is missing")]
611 MissingFd(&'static str),
612 #[error("there are trailing bytes after the message")]
613 TrailingBytes,
614 #[error("argument {0} is not present in the message")]
615 MissingArgument(&'static str),
616 #[error("argument {0} is a null string but the argument is not nullable")]
617 NullString(&'static str),
618 #[error("argument {0} is not valid UTF-8")]
619 NonUtf8(&'static str),
620 #[error("{}", display_error(.0.as_ref(), *.1, *.2))]
621 ServerError(Option<Rc<dyn Object>>, u32, u32, #[source] StringError),
622 #[error("the message handler is already borrowed")]
623 HandlerBorrowed,
624 #[error("the client is not waiting for a delete_id message")]
625 NotAwaitingDeleteId,
626}
627
628#[derive(Debug, Error)]
629#[error("{0}")]
630pub(crate) struct StringError(pub String);
631
632fn display_error<'a>(
633 object: Option<&'a Rc<dyn Object>>,
634 server_id: u32,
635 error: u32,
636) -> impl Display + use<'a> {
637 debug_fn(move |f| {
638 if let Some(object) = object {
639 let interface = object.interface().name();
640 let unique_id = object.unique_id();
641 write!(
642 f,
643 "server sent error {error} on object {interface}#{server_id} (unique id: {unique_id}",
644 )?;
645 if let Some(client) = object.client() {
646 write!(f, ", client: {}", client.endpoint.id)?;
647 }
648 if let Some(client_id) = object.client_id() {
649 write!(f, ", client id: {client_id}")?;
650 }
651 write!(f, ")")?;
652 } else {
653 write!(
654 f,
655 "server sent error {error} on a deleted object with server id {server_id}",
656 )?;
657 }
658 Ok(())
659 })
660}