pipewire/core/
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 spa::spa_interface_call_method;
11
12use crate::{registry::RegistryRc, Error};
13
14use super::{Core, CoreBox};
15
16#[derive(Debug)]
17struct CoreRcInner {
18    core: CoreBox<'static>,
19    // Store the context here, so that the context is not dropped before the core,
20    // which may lead to undefined behaviour. Rusts drop order of struct fields
21    // (from top to bottom) ensures that this is always destroyed _after_ the core.
22    _context: crate::context::ContextRc,
23}
24
25/// Reference counting smart pointer providing shared ownership of a PipeWire [core](super).
26///
27/// For the non-owning variant, see [`CoreWeak`].
28/// For unique ownership, see [`CoreBox`].
29///
30/// For an explanation of these, see [Smart pointers to PipeWire objects](crate#smart-pointers-to-pipewire-objects).
31#[derive(Debug, Clone)]
32pub struct CoreRc {
33    inner: Rc<CoreRcInner>,
34}
35
36impl CoreRc {
37    pub fn from_raw(
38        ptr: ptr::NonNull<pw_sys::pw_core>,
39        context: crate::context::ContextRc,
40    ) -> Self {
41        let core = unsafe { CoreBox::from_raw(ptr) };
42
43        Self {
44            inner: Rc::new(CoreRcInner {
45                core,
46                _context: context,
47            }),
48        }
49    }
50
51    pub fn downgrade(&self) -> CoreWeak {
52        let weak = Rc::downgrade(&self.inner);
53        CoreWeak { weak }
54    }
55
56    pub fn get_registry_rc(&self) -> Result<RegistryRc, Error> {
57        unsafe {
58            let registry = spa_interface_call_method!(
59                self.as_raw_ptr(),
60                pw_sys::pw_core_methods,
61                get_registry,
62                pw_sys::PW_VERSION_REGISTRY,
63                0
64            );
65            let registry = ptr::NonNull::new(registry).ok_or(Error::CreationFailed)?;
66            Ok(RegistryRc::from_raw(registry, self.clone()))
67        }
68    }
69}
70
71impl Deref for CoreRc {
72    type Target = Core;
73
74    fn deref(&self) -> &Self::Target {
75        self.inner.core.deref()
76    }
77}
78
79impl AsRef<Core> for CoreRc {
80    fn as_ref(&self) -> &Core {
81        self.deref()
82    }
83}
84
85/// Non-owning reference to a [core](super) managed by [`CoreRc`].
86///
87/// The core can be accessed by calling [`upgrade`](Self::upgrade).
88pub struct CoreWeak {
89    weak: Weak<CoreRcInner>,
90}
91
92impl CoreWeak {
93    pub fn upgrade(&self) -> Option<CoreRc> {
94        self.weak.upgrade().map(|inner| CoreRc { inner })
95    }
96}