pipewire/registry/
rc.rs

1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4use std::{
5    ops::Deref,
6    ptr,
7    rc::{Rc, Weak},
8};
9
10use super::{Registry, RegistryBox};
11
12#[derive(Debug)]
13struct RegistryRcInner {
14    registry: RegistryBox<'static>,
15    // Store the core here, so that the registry is not dropped before the core,
16    // which may lead to undefined behaviour. Rusts drop order of struct fields
17    // (from top to bottom) ensures that this is always destroyed _after_ the registry.
18    _core: crate::core::CoreRc,
19}
20
21/// Reference counting smart pointer providing shared ownership of a PipeWire [registry](super).
22///
23/// For the non-owning variant, see [`RegistryWeak`].
24/// For unique ownership, see [`RegistryBox`].
25///
26/// For an explanation of these, see [Smart pointers to PipeWire objects](crate#smart-pointers-to-pipewire-objects).
27#[derive(Debug, Clone)]
28pub struct RegistryRc {
29    inner: Rc<RegistryRcInner>,
30}
31
32impl RegistryRc {
33    /// Create a `RegistryRc` by taking ownership of a raw `pw_registry`.
34    ///
35    /// # Safety
36    /// The provided pointer must point to a valid, well aligned [`pw_registry`](`pw_sys::pw_registry`).
37    ///
38    /// The raw registry must not be manually destroyed or moved, as the new [`RegistryRc`] takes
39    /// ownership of it.
40    pub unsafe fn from_raw(
41        ptr: ptr::NonNull<pw_sys::pw_registry>,
42        core: crate::core::CoreRc,
43    ) -> Self {
44        let registry = unsafe { RegistryBox::from_raw(ptr) };
45
46        Self {
47            inner: Rc::new(RegistryRcInner {
48                registry,
49                _core: core,
50            }),
51        }
52    }
53
54    pub fn downgrade(&self) -> RegistryWeak {
55        let weak = Rc::downgrade(&self.inner);
56        RegistryWeak { weak }
57    }
58}
59
60impl Deref for RegistryRc {
61    type Target = Registry;
62
63    fn deref(&self) -> &Self::Target {
64        self.inner.registry.deref()
65    }
66}
67
68impl AsRef<Registry> for RegistryRc {
69    fn as_ref(&self) -> &Registry {
70        self.deref()
71    }
72}
73
74/// Non-owning reference to a [registry](super) managed by [`RegistryRc`].
75///
76/// The registry can be accessed by calling [`upgrade`](Self::upgrade).
77pub struct RegistryWeak {
78    weak: Weak<RegistryRcInner>,
79}
80
81impl RegistryWeak {
82    pub fn upgrade(&self) -> Option<RegistryRc> {
83        self.weak.upgrade().map(|inner| RegistryRc { inner })
84    }
85}