wl_proxy/protocols/wayland/
wl_shm_pool.rs

1//! a shared memory pool
2//!
3//! The wl_shm_pool object encapsulates a piece of memory shared
4//! between the compositor and client.  Through the wl_shm_pool
5//! object, the client can allocate shared memory wl_buffer objects.
6//! All objects created through the same pool share the same
7//! underlying mapped memory. Reusing the mapped memory avoids the
8//! setup/teardown overhead and is useful when interactively resizing
9//! a surface or for many small buffers.
10
11use crate::protocol_helpers::prelude::*;
12use super::super::all_types::*;
13
14/// A wl_shm_pool object.
15///
16/// See the documentation of [the module][self] for the interface description.
17pub struct WlShmPool {
18    core: ObjectCore,
19    handler: HandlerHolder<dyn WlShmPoolHandler>,
20}
21
22struct DefaultHandler;
23
24impl WlShmPoolHandler for DefaultHandler { }
25
26impl ConcreteObject for WlShmPool {
27    const XML_VERSION: u32 = 2;
28    const INTERFACE: ObjectInterface = ObjectInterface::WlShmPool;
29    const INTERFACE_NAME: &str = "wl_shm_pool";
30}
31
32impl WlShmPool {
33    /// Sets a new handler.
34    pub fn set_handler(&self, handler: impl WlShmPoolHandler) {
35        self.set_boxed_handler(Box::new(handler));
36    }
37
38    /// Sets a new, already boxed handler.
39    pub fn set_boxed_handler(&self, handler: Box<dyn WlShmPoolHandler>) {
40        if self.core.state.destroyed.get() {
41            return;
42        }
43        self.handler.set(Some(handler));
44    }
45}
46
47impl Debug for WlShmPool {
48    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49        f.debug_struct("WlShmPool")
50            .field("server_obj_id", &self.core.server_obj_id.get())
51            .field("client_id", &self.core.client_id.get())
52            .field("client_obj_id", &self.core.client_obj_id.get())
53            .finish()
54    }
55}
56
57impl WlShmPool {
58    /// Since when the create_buffer message is available.
59    pub const MSG__CREATE_BUFFER__SINCE: u32 = 1;
60
61    /// create a buffer from the pool
62    ///
63    /// Create a wl_buffer object from the pool.
64    ///
65    /// The buffer is created offset bytes into the pool and has
66    /// width and height as specified.  The stride argument specifies
67    /// the number of bytes from the beginning of one row to the beginning
68    /// of the next.  The format is the pixel format of the buffer and
69    /// must be one of those advertised through the wl_shm.format event.
70    ///
71    /// A buffer will keep a reference to the pool it was created from
72    /// so it is valid to destroy the pool immediately after creating
73    /// a buffer from it.
74    ///
75    /// # Arguments
76    ///
77    /// - `id`: buffer to create
78    /// - `offset`: buffer byte offset within the pool
79    /// - `width`: buffer width, in pixels
80    /// - `height`: buffer height, in pixels
81    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
82    /// - `format`: buffer pixel format
83    #[inline]
84    pub fn try_send_create_buffer(
85        &self,
86        id: &Rc<WlBuffer>,
87        offset: i32,
88        width: i32,
89        height: i32,
90        stride: i32,
91        format: WlShmFormat,
92    ) -> Result<(), ObjectError> {
93        let (
94            arg0,
95            arg1,
96            arg2,
97            arg3,
98            arg4,
99            arg5,
100        ) = (
101            id,
102            offset,
103            width,
104            height,
105            stride,
106            format,
107        );
108        let arg0_obj = arg0;
109        let arg0 = arg0_obj.core();
110        let core = self.core();
111        let Some(id) = core.server_obj_id.get() else {
112            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
113        };
114        arg0.generate_server_id(arg0_obj.clone())
115            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
116        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
117        #[cfg(feature = "logging")]
118        if self.core.state.log {
119            #[cold]
120            fn log(state: &State, id: u32, arg0: u32, arg1: i32, arg2: i32, arg3: i32, arg4: i32, arg5: WlShmFormat) {
121                let (millis, micros) = time_since_epoch();
122                let prefix = &state.log_prefix;
123                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_shm_pool#{}.create_buffer(id: wl_buffer#{}, offset: {}, width: {}, height: {}, stride: {}, format: {:?})\n", id, arg0, arg1, arg2, arg3, arg4, arg5);
124                state.log(args);
125            }
126            log(&self.core.state, id, arg0_id, arg1, arg2, arg3, arg4, arg5);
127        }
128        let Some(endpoint) = &self.core.state.server else {
129            return Ok(());
130        };
131        if !endpoint.flush_queued.replace(true) {
132            self.core.state.add_flushable_endpoint(endpoint, None);
133        }
134        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
135        let outgoing = &mut *outgoing_ref;
136        let mut fmt = outgoing.formatter();
137        fmt.words([
138            id,
139            0,
140            arg0_id,
141            arg1 as u32,
142            arg2 as u32,
143            arg3 as u32,
144            arg4 as u32,
145            arg5.0,
146        ]);
147        Ok(())
148    }
149
150    /// create a buffer from the pool
151    ///
152    /// Create a wl_buffer object from the pool.
153    ///
154    /// The buffer is created offset bytes into the pool and has
155    /// width and height as specified.  The stride argument specifies
156    /// the number of bytes from the beginning of one row to the beginning
157    /// of the next.  The format is the pixel format of the buffer and
158    /// must be one of those advertised through the wl_shm.format event.
159    ///
160    /// A buffer will keep a reference to the pool it was created from
161    /// so it is valid to destroy the pool immediately after creating
162    /// a buffer from it.
163    ///
164    /// # Arguments
165    ///
166    /// - `id`: buffer to create
167    /// - `offset`: buffer byte offset within the pool
168    /// - `width`: buffer width, in pixels
169    /// - `height`: buffer height, in pixels
170    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
171    /// - `format`: buffer pixel format
172    #[inline]
173    pub fn send_create_buffer(
174        &self,
175        id: &Rc<WlBuffer>,
176        offset: i32,
177        width: i32,
178        height: i32,
179        stride: i32,
180        format: WlShmFormat,
181    ) {
182        let res = self.try_send_create_buffer(
183            id,
184            offset,
185            width,
186            height,
187            stride,
188            format,
189        );
190        if let Err(e) = res {
191            log_send("wl_shm_pool.create_buffer", &e);
192        }
193    }
194
195    /// create a buffer from the pool
196    ///
197    /// Create a wl_buffer object from the pool.
198    ///
199    /// The buffer is created offset bytes into the pool and has
200    /// width and height as specified.  The stride argument specifies
201    /// the number of bytes from the beginning of one row to the beginning
202    /// of the next.  The format is the pixel format of the buffer and
203    /// must be one of those advertised through the wl_shm.format event.
204    ///
205    /// A buffer will keep a reference to the pool it was created from
206    /// so it is valid to destroy the pool immediately after creating
207    /// a buffer from it.
208    ///
209    /// # Arguments
210    ///
211    /// - `offset`: buffer byte offset within the pool
212    /// - `width`: buffer width, in pixels
213    /// - `height`: buffer height, in pixels
214    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
215    /// - `format`: buffer pixel format
216    #[inline]
217    pub fn new_try_send_create_buffer(
218        &self,
219        offset: i32,
220        width: i32,
221        height: i32,
222        stride: i32,
223        format: WlShmFormat,
224    ) -> Result<Rc<WlBuffer>, ObjectError> {
225        let id = self.core.create_child();
226        self.try_send_create_buffer(
227            &id,
228            offset,
229            width,
230            height,
231            stride,
232            format,
233        )?;
234        Ok(id)
235    }
236
237    /// create a buffer from the pool
238    ///
239    /// Create a wl_buffer object from the pool.
240    ///
241    /// The buffer is created offset bytes into the pool and has
242    /// width and height as specified.  The stride argument specifies
243    /// the number of bytes from the beginning of one row to the beginning
244    /// of the next.  The format is the pixel format of the buffer and
245    /// must be one of those advertised through the wl_shm.format event.
246    ///
247    /// A buffer will keep a reference to the pool it was created from
248    /// so it is valid to destroy the pool immediately after creating
249    /// a buffer from it.
250    ///
251    /// # Arguments
252    ///
253    /// - `offset`: buffer byte offset within the pool
254    /// - `width`: buffer width, in pixels
255    /// - `height`: buffer height, in pixels
256    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
257    /// - `format`: buffer pixel format
258    #[inline]
259    pub fn new_send_create_buffer(
260        &self,
261        offset: i32,
262        width: i32,
263        height: i32,
264        stride: i32,
265        format: WlShmFormat,
266    ) -> Rc<WlBuffer> {
267        let id = self.core.create_child();
268        self.send_create_buffer(
269            &id,
270            offset,
271            width,
272            height,
273            stride,
274            format,
275        );
276        id
277    }
278
279    /// Since when the destroy message is available.
280    pub const MSG__DESTROY__SINCE: u32 = 1;
281
282    /// destroy the pool
283    ///
284    /// Destroy the shared memory pool.
285    ///
286    /// The mmapped memory will be released when all
287    /// buffers that have been created from this pool
288    /// are gone.
289    #[inline]
290    pub fn try_send_destroy(
291        &self,
292    ) -> Result<(), ObjectError> {
293        let core = self.core();
294        let Some(id) = core.server_obj_id.get() else {
295            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
296        };
297        #[cfg(feature = "logging")]
298        if self.core.state.log {
299            #[cold]
300            fn log(state: &State, id: u32) {
301                let (millis, micros) = time_since_epoch();
302                let prefix = &state.log_prefix;
303                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_shm_pool#{}.destroy()\n", id);
304                state.log(args);
305            }
306            log(&self.core.state, id);
307        }
308        let Some(endpoint) = &self.core.state.server else {
309            return Ok(());
310        };
311        if !endpoint.flush_queued.replace(true) {
312            self.core.state.add_flushable_endpoint(endpoint, None);
313        }
314        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
315        let outgoing = &mut *outgoing_ref;
316        let mut fmt = outgoing.formatter();
317        fmt.words([
318            id,
319            1,
320        ]);
321        self.core.handle_server_destroy();
322        Ok(())
323    }
324
325    /// destroy the pool
326    ///
327    /// Destroy the shared memory pool.
328    ///
329    /// The mmapped memory will be released when all
330    /// buffers that have been created from this pool
331    /// are gone.
332    #[inline]
333    pub fn send_destroy(
334        &self,
335    ) {
336        let res = self.try_send_destroy(
337        );
338        if let Err(e) = res {
339            log_send("wl_shm_pool.destroy", &e);
340        }
341    }
342
343    /// Since when the resize message is available.
344    pub const MSG__RESIZE__SINCE: u32 = 1;
345
346    /// change the size of the pool mapping
347    ///
348    /// This request will cause the server to remap the backing memory
349    /// for the pool from the file descriptor passed when the pool was
350    /// created, but using the new size.  This request can only be
351    /// used to make the pool bigger.
352    ///
353    /// This request only changes the amount of bytes that are mmapped
354    /// by the server and does not touch the file corresponding to the
355    /// file descriptor passed at creation time. It is the client's
356    /// responsibility to ensure that the file is at least as big as
357    /// the new pool size.
358    ///
359    /// # Arguments
360    ///
361    /// - `size`: new size of the pool, in bytes
362    #[inline]
363    pub fn try_send_resize(
364        &self,
365        size: i32,
366    ) -> Result<(), ObjectError> {
367        let (
368            arg0,
369        ) = (
370            size,
371        );
372        let core = self.core();
373        let Some(id) = core.server_obj_id.get() else {
374            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
375        };
376        #[cfg(feature = "logging")]
377        if self.core.state.log {
378            #[cold]
379            fn log(state: &State, id: u32, arg0: i32) {
380                let (millis, micros) = time_since_epoch();
381                let prefix = &state.log_prefix;
382                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_shm_pool#{}.resize(size: {})\n", id, arg0);
383                state.log(args);
384            }
385            log(&self.core.state, id, arg0);
386        }
387        let Some(endpoint) = &self.core.state.server else {
388            return Ok(());
389        };
390        if !endpoint.flush_queued.replace(true) {
391            self.core.state.add_flushable_endpoint(endpoint, None);
392        }
393        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
394        let outgoing = &mut *outgoing_ref;
395        let mut fmt = outgoing.formatter();
396        fmt.words([
397            id,
398            2,
399            arg0 as u32,
400        ]);
401        Ok(())
402    }
403
404    /// change the size of the pool mapping
405    ///
406    /// This request will cause the server to remap the backing memory
407    /// for the pool from the file descriptor passed when the pool was
408    /// created, but using the new size.  This request can only be
409    /// used to make the pool bigger.
410    ///
411    /// This request only changes the amount of bytes that are mmapped
412    /// by the server and does not touch the file corresponding to the
413    /// file descriptor passed at creation time. It is the client's
414    /// responsibility to ensure that the file is at least as big as
415    /// the new pool size.
416    ///
417    /// # Arguments
418    ///
419    /// - `size`: new size of the pool, in bytes
420    #[inline]
421    pub fn send_resize(
422        &self,
423        size: i32,
424    ) {
425        let res = self.try_send_resize(
426            size,
427        );
428        if let Err(e) = res {
429            log_send("wl_shm_pool.resize", &e);
430        }
431    }
432}
433
434/// A message handler for [`WlShmPool`] proxies.
435pub trait WlShmPoolHandler: Any {
436    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
437    ///
438    /// The default handler forwards the event to the client, if any.
439    #[inline]
440    fn delete_id(&mut self, slf: &Rc<WlShmPool>) {
441        slf.core.delete_id();
442    }
443
444    /// create a buffer from the pool
445    ///
446    /// Create a wl_buffer object from the pool.
447    ///
448    /// The buffer is created offset bytes into the pool and has
449    /// width and height as specified.  The stride argument specifies
450    /// the number of bytes from the beginning of one row to the beginning
451    /// of the next.  The format is the pixel format of the buffer and
452    /// must be one of those advertised through the wl_shm.format event.
453    ///
454    /// A buffer will keep a reference to the pool it was created from
455    /// so it is valid to destroy the pool immediately after creating
456    /// a buffer from it.
457    ///
458    /// # Arguments
459    ///
460    /// - `id`: buffer to create
461    /// - `offset`: buffer byte offset within the pool
462    /// - `width`: buffer width, in pixels
463    /// - `height`: buffer height, in pixels
464    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
465    /// - `format`: buffer pixel format
466    #[inline]
467    fn handle_create_buffer(
468        &mut self,
469        slf: &Rc<WlShmPool>,
470        id: &Rc<WlBuffer>,
471        offset: i32,
472        width: i32,
473        height: i32,
474        stride: i32,
475        format: WlShmFormat,
476    ) {
477        if !slf.core.forward_to_server.get() {
478            return;
479        }
480        let res = slf.try_send_create_buffer(
481            id,
482            offset,
483            width,
484            height,
485            stride,
486            format,
487        );
488        if let Err(e) = res {
489            log_forward("wl_shm_pool.create_buffer", &e);
490        }
491    }
492
493    /// destroy the pool
494    ///
495    /// Destroy the shared memory pool.
496    ///
497    /// The mmapped memory will be released when all
498    /// buffers that have been created from this pool
499    /// are gone.
500    #[inline]
501    fn handle_destroy(
502        &mut self,
503        slf: &Rc<WlShmPool>,
504    ) {
505        if !slf.core.forward_to_server.get() {
506            return;
507        }
508        let res = slf.try_send_destroy(
509        );
510        if let Err(e) = res {
511            log_forward("wl_shm_pool.destroy", &e);
512        }
513    }
514
515    /// change the size of the pool mapping
516    ///
517    /// This request will cause the server to remap the backing memory
518    /// for the pool from the file descriptor passed when the pool was
519    /// created, but using the new size.  This request can only be
520    /// used to make the pool bigger.
521    ///
522    /// This request only changes the amount of bytes that are mmapped
523    /// by the server and does not touch the file corresponding to the
524    /// file descriptor passed at creation time. It is the client's
525    /// responsibility to ensure that the file is at least as big as
526    /// the new pool size.
527    ///
528    /// # Arguments
529    ///
530    /// - `size`: new size of the pool, in bytes
531    #[inline]
532    fn handle_resize(
533        &mut self,
534        slf: &Rc<WlShmPool>,
535        size: i32,
536    ) {
537        if !slf.core.forward_to_server.get() {
538            return;
539        }
540        let res = slf.try_send_resize(
541            size,
542        );
543        if let Err(e) = res {
544            log_forward("wl_shm_pool.resize", &e);
545        }
546    }
547}
548
549impl ObjectPrivate for WlShmPool {
550    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
551        Rc::<Self>::new_cyclic(|slf| Self {
552            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlShmPool, version),
553            handler: Default::default(),
554        })
555    }
556
557    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
558        let Some(mut handler) = self.handler.try_borrow_mut() else {
559            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
560        };
561        if let Some(handler) = &mut *handler {
562            handler.delete_id(&self);
563        } else {
564            self.core.delete_id();
565        }
566        Ok(())
567    }
568
569    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
570        let Some(mut handler) = self.handler.try_borrow_mut() else {
571            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
572        };
573        let handler = &mut *handler;
574        match msg[1] & 0xffff {
575            0 => {
576                let [
577                    arg0,
578                    arg1,
579                    arg2,
580                    arg3,
581                    arg4,
582                    arg5,
583                ] = msg[2..] else {
584                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 32)));
585                };
586                let arg1 = arg1 as i32;
587                let arg2 = arg2 as i32;
588                let arg3 = arg3 as i32;
589                let arg4 = arg4 as i32;
590                let arg5 = WlShmFormat(arg5);
591                #[cfg(feature = "logging")]
592                if self.core.state.log {
593                    #[cold]
594                    fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: i32, arg2: i32, arg3: i32, arg4: i32, arg5: WlShmFormat) {
595                        let (millis, micros) = time_since_epoch();
596                        let prefix = &state.log_prefix;
597                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shm_pool#{}.create_buffer(id: wl_buffer#{}, offset: {}, width: {}, height: {}, stride: {}, format: {:?})\n", client_id, id, arg0, arg1, arg2, arg3, arg4, arg5);
598                        state.log(args);
599                    }
600                    log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1, arg2, arg3, arg4, arg5);
601                }
602                let arg0_id = arg0;
603                let arg0 = WlBuffer::new(&self.core.state, self.core.version);
604                arg0.core().set_client_id(client, arg0_id, arg0.clone())
605                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
606                let arg0 = &arg0;
607                if let Some(handler) = handler {
608                    (**handler).handle_create_buffer(&self, arg0, arg1, arg2, arg3, arg4, arg5);
609                } else {
610                    DefaultHandler.handle_create_buffer(&self, arg0, arg1, arg2, arg3, arg4, arg5);
611                }
612            }
613            1 => {
614                if msg.len() != 2 {
615                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
616                }
617                #[cfg(feature = "logging")]
618                if self.core.state.log {
619                    #[cold]
620                    fn log(state: &State, client_id: u64, id: u32) {
621                        let (millis, micros) = time_since_epoch();
622                        let prefix = &state.log_prefix;
623                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shm_pool#{}.destroy()\n", client_id, id);
624                        state.log(args);
625                    }
626                    log(&self.core.state, client.endpoint.id, msg[0]);
627                }
628                self.core.handle_client_destroy();
629                if let Some(handler) = handler {
630                    (**handler).handle_destroy(&self);
631                } else {
632                    DefaultHandler.handle_destroy(&self);
633                }
634            }
635            2 => {
636                let [
637                    arg0,
638                ] = msg[2..] else {
639                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
640                };
641                let arg0 = arg0 as i32;
642                #[cfg(feature = "logging")]
643                if self.core.state.log {
644                    #[cold]
645                    fn log(state: &State, client_id: u64, id: u32, arg0: i32) {
646                        let (millis, micros) = time_since_epoch();
647                        let prefix = &state.log_prefix;
648                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shm_pool#{}.resize(size: {})\n", client_id, id, arg0);
649                        state.log(args);
650                    }
651                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
652                }
653                if let Some(handler) = handler {
654                    (**handler).handle_resize(&self, arg0);
655                } else {
656                    DefaultHandler.handle_resize(&self, arg0);
657                }
658            }
659            n => {
660                let _ = client;
661                let _ = msg;
662                let _ = fds;
663                let _ = handler;
664                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
665            }
666        }
667        Ok(())
668    }
669
670    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
671        let Some(mut handler) = self.handler.try_borrow_mut() else {
672            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
673        };
674        let handler = &mut *handler;
675        match msg[1] & 0xffff {
676            n => {
677                let _ = server;
678                let _ = msg;
679                let _ = fds;
680                let _ = handler;
681                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
682            }
683        }
684    }
685
686    fn get_request_name(&self, id: u32) -> Option<&'static str> {
687        let name = match id {
688            0 => "create_buffer",
689            1 => "destroy",
690            2 => "resize",
691            _ => return None,
692        };
693        Some(name)
694    }
695
696    fn get_event_name(&self, id: u32) -> Option<&'static str> {
697        let _ = id;
698        None
699    }
700}
701
702impl Object for WlShmPool {
703    fn core(&self) -> &ObjectCore {
704        &self.core
705    }
706
707    fn unset_handler(&self) {
708        self.handler.set(None);
709    }
710
711    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
712        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
713        if borrowed.is_none() {
714            return Err(HandlerAccessError::NoHandler);
715        }
716        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
717    }
718
719    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
720        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
721        if borrowed.is_none() {
722            return Err(HandlerAccessError::NoHandler);
723        }
724        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
725    }
726}
727