pipewire/thread_loop/
rc.rs1use std::{
5 ffi::CStr,
6 ops::Deref,
7 ptr,
8 rc::{Rc, Weak},
9};
10
11use crate::{
12 error::Error,
13 loop_::{IsLoopRc, Loop},
14};
15
16use super::{ThreadLoop, ThreadLoopBox};
17
18#[derive(Debug)]
19struct ThreadLoopRcInner {
20 thread_loop: ThreadLoopBox,
21}
22
23#[derive(Debug, Clone)]
24pub struct ThreadLoopRc {
25 inner: Rc<ThreadLoopRcInner>,
26}
27
28impl ThreadLoopRc {
29 pub unsafe fn new(
34 name: Option<&str>,
35 properties: Option<&spa::utils::dict::DictRef>,
36 ) -> Result<Self, Error> {
37 let thread_loop = ThreadLoopBox::new(name, properties)?;
38
39 Ok(Self::from_box(thread_loop))
40 }
41
42 pub unsafe fn new_cstr(
48 name: Option<&CStr>,
49 properties: Option<&spa::utils::dict::DictRef>,
50 ) -> Result<Self, Error> {
51 let thread_loop = ThreadLoopBox::new_cstr(name, properties)?;
52
53 Ok(Self::from_box(thread_loop))
54 }
55
56 pub unsafe fn from_box(thread_loop: ThreadLoopBox) -> Self {
61 Self {
62 inner: Rc::new(ThreadLoopRcInner { thread_loop }),
63 }
64 }
65
66 pub unsafe fn from_raw(ptr: ptr::NonNull<pw_sys::pw_thread_loop>) -> Self {
73 let thread_loop = ThreadLoopBox::from_raw(ptr);
74
75 Self {
76 inner: Rc::new(ThreadLoopRcInner { thread_loop }),
77 }
78 }
79
80 pub fn downgrade(&self) -> ThreadLoopWeak {
81 let weak = Rc::downgrade(&self.inner);
82 ThreadLoopWeak { weak }
83 }
84}
85
86unsafe impl IsLoopRc for ThreadLoopRc {}
89
90impl std::ops::Deref for ThreadLoopRc {
91 type Target = ThreadLoop;
92
93 fn deref(&self) -> &Self::Target {
94 self.inner.thread_loop.deref()
95 }
96}
97
98impl std::convert::AsRef<ThreadLoop> for ThreadLoopRc {
99 fn as_ref(&self) -> &ThreadLoop {
100 self.deref()
101 }
102}
103
104impl std::convert::AsRef<Loop> for ThreadLoopRc {
105 fn as_ref(&self) -> &Loop {
106 self.loop_()
107 }
108}
109
110pub struct ThreadLoopWeak {
111 weak: Weak<ThreadLoopRcInner>,
112}
113
114impl ThreadLoopWeak {
115 pub fn upgrade(&self) -> Option<ThreadLoopRc> {
116 self.weak.upgrade().map(|inner| ThreadLoopRc { inner })
117 }
118}