pipewire/thread_loop/
mod.rs1use std::mem::MaybeUninit;
5
6use crate::loop_::Loop;
7
8mod box_;
9pub use box_::*;
10mod rc;
11pub use rc::*;
12
13#[repr(transparent)]
17pub struct ThreadLoop(pw_sys::pw_thread_loop);
18
19impl ThreadLoop {
20 pub fn as_raw(&self) -> &pw_sys::pw_thread_loop {
21 &self.0
22 }
23
24 pub fn as_raw_ptr(&self) -> *mut pw_sys::pw_thread_loop {
25 std::ptr::addr_of!(self.0).cast_mut()
26 }
27
28 pub fn loop_(&self) -> &Loop {
29 unsafe {
30 let pw_loop = pw_sys::pw_thread_loop_get_loop(self.as_raw_ptr());
31 &*(pw_loop.cast::<Loop>())
33 }
34 }
35
36 pub fn lock(&self) -> ThreadLoopLockGuard<'_> {
47 ThreadLoopLockGuard::new(self)
48 }
49
50 pub fn start(&self) {
52 unsafe {
53 pw_sys::pw_thread_loop_start(self.as_raw_ptr());
54 }
55 }
56
57 pub fn stop(&self) {
61 unsafe {
62 pw_sys::pw_thread_loop_stop(self.as_raw_ptr());
63 }
64 }
65
66 pub fn signal(&self, signal: bool) {
68 unsafe {
69 pw_sys::pw_thread_loop_signal(self.as_raw_ptr(), signal);
70 }
71 }
72
73 pub fn wait(&self) {
77 unsafe {
78 pw_sys::pw_thread_loop_wait(self.as_raw_ptr());
79 }
80 }
81
82 pub fn timed_wait(&self, wait_max_sec: std::time::Duration) {
85 unsafe {
86 let wait_max_sec: i32 = wait_max_sec
87 .as_secs()
88 .try_into()
89 .expect("Provided timeout does not fit in a i32");
90 pw_sys::pw_thread_loop_timed_wait(self.as_raw_ptr(), wait_max_sec);
91 }
92 }
93
94 pub fn get_time(&self, timeout: i64) -> nix::sys::time::TimeSpec {
96 unsafe {
97 let mut abstime: MaybeUninit<pw_sys::timespec> = std::mem::MaybeUninit::uninit();
98 pw_sys::pw_thread_loop_get_time(self.as_raw_ptr(), abstime.as_mut_ptr(), timeout);
99 let abstime = abstime.assume_init();
100 nix::sys::time::TimeSpec::new(abstime.tv_sec, abstime.tv_nsec)
101 }
102 }
103
104 pub fn timed_wait_full(&self, abstime: nix::sys::time::TimeSpec) {
108 unsafe {
109 let mut abstime = pw_sys::timespec {
110 tv_sec: abstime.tv_sec(),
111 tv_nsec: abstime.tv_nsec(),
112 };
113 pw_sys::pw_thread_loop_timed_wait_full(
114 self.as_raw_ptr(),
115 &mut abstime as *mut pw_sys::timespec,
116 );
117 }
118 }
119
120 pub fn accept(&self) {
122 unsafe {
123 pw_sys::pw_thread_loop_accept(self.as_raw_ptr());
124 }
125 }
126
127 pub fn in_thread(&self) {
129 unsafe {
130 pw_sys::pw_thread_loop_in_thread(self.as_raw_ptr());
131 }
132 }
133}
134
135pub struct ThreadLoopLockGuard<'a> {
136 thread_loop: &'a ThreadLoop,
137}
138
139impl<'a> ThreadLoopLockGuard<'a> {
140 fn new(thread_loop: &'a ThreadLoop) -> Self {
141 unsafe {
142 pw_sys::pw_thread_loop_lock(thread_loop.as_raw_ptr());
143 }
144 ThreadLoopLockGuard { thread_loop }
145 }
146
147 pub fn unlock(self) {
151 drop(self);
152 }
153}
154
155impl<'a> Drop for ThreadLoopLockGuard<'a> {
156 fn drop(&mut self) {
157 unsafe {
158 pw_sys::pw_thread_loop_unlock(self.thread_loop.as_raw_ptr());
159 }
160 }
161}