pipewire/thread_loop/
box_.rs1use std::{
5 ffi::{CStr, CString},
6 ops::Deref,
7 ptr,
8};
9
10use crate::Error;
11
12use super::ThreadLoop;
13
14#[derive(Debug)]
15pub struct ThreadLoopBox {
16 ptr: ptr::NonNull<pw_sys::pw_thread_loop>,
17}
18
19impl ThreadLoopBox {
20 pub unsafe fn new(
25 name: Option<&str>,
26 properties: Option<&spa::utils::dict::DictRef>,
27 ) -> Result<Self, Error> {
28 let name = name.map(|name| CString::new(name).unwrap());
29
30 ThreadLoopBox::new_cstr(name.as_deref(), properties)
31 }
32
33 pub unsafe fn new_cstr(
39 name: Option<&CStr>,
40 properties: Option<&spa::utils::dict::DictRef>,
41 ) -> Result<Self, Error> {
42 crate::init();
43
44 unsafe {
45 let props = properties.map_or(ptr::null(), |props| props.as_raw_ptr());
46 let name = name.map_or(ptr::null(), |p| p.as_ptr() as *const _);
47
48 let raw = pw_sys::pw_thread_loop_new(name, props);
49 let ptr = ptr::NonNull::new(raw).ok_or(Error::CreationFailed)?;
50
51 Ok(Self::from_raw(ptr))
52 }
53 }
54
55 pub unsafe fn from_raw(ptr: ptr::NonNull<pw_sys::pw_thread_loop>) -> Self {
62 Self { ptr }
63 }
64
65 pub fn into_raw(self) -> std::ptr::NonNull<pw_sys::pw_thread_loop> {
66 std::mem::ManuallyDrop::new(self).ptr
68 }
69}
70
71impl std::ops::Deref for ThreadLoopBox {
72 type Target = ThreadLoop;
73
74 fn deref(&self) -> &Self::Target {
75 unsafe { self.ptr.cast::<ThreadLoop>().as_ref() }
76 }
77}
78
79impl AsRef<ThreadLoop> for ThreadLoopBox {
80 fn as_ref(&self) -> &ThreadLoop {
81 self.deref()
82 }
83}
84
85impl std::ops::Drop for ThreadLoopBox {
86 fn drop(&mut self) {
87 unsafe {
88 pw_sys::pw_thread_loop_destroy(self.as_raw_ptr());
89 }
90 }
91}