libpulse_binding/mainloop/events/
timer.rs1use std::os::raw::c_void;
26use std::rc::Rc;
27use libc::timeval;
28use crate::mainloop::api::{MainloopApi, MainloopInnerType};
29use crate::time::{UnixTs, MonotonicTs, Timeval, MicroSeconds};
30use crate::callbacks::MultiUseCallback;
31
32pub use capi::pa_time_event as TimeEventInternal;
33
34pub struct TimeEvent<T>
36 where T: MainloopInnerType
37{
38 ptr: *mut TimeEventInternal,
40 owner: Rc<T>,
42 _saved_cb: EventCb,
44}
45
46pub struct TimeEventRef<T: 'static>
49 where T: MainloopInnerType
50{
51 ptr: *mut TimeEventInternal,
53 owner: Rc<T>,
55}
56
57pub(crate) type EventCb = MultiUseCallback<dyn FnMut(*mut TimeEventInternal),
58 extern "C" fn(a: *const MainloopApi, e: *mut TimeEventInternal, tv: *const timeval,
59 userdata: *mut c_void)>;
60
61impl<T> TimeEvent<T>
62 where T: MainloopInnerType
63{
64 #[inline]
65 pub(crate) fn from_raw(ptr: *mut TimeEventInternal, mainloop_inner: Rc<T>, callback: EventCb)
66 -> Self
67 {
68 assert_eq!(false, ptr.is_null());
69 Self { ptr: ptr, owner: mainloop_inner, _saved_cb: callback }
70 }
71
72 #[inline]
75 pub fn restart(&mut self, t: &UnixTs) {
76 let fn_ptr = (*self.owner).get_api().time_restart.unwrap();
77 fn_ptr(self.ptr, &(t.0).0);
78 }
79
80 pub fn restart_rt(&mut self, t: MonotonicTs) {
83 assert_ne!(t.0, MicroSeconds::INVALID);
84 let mut tv = Timeval::new_zero();
85 tv.set_rt(t.0, (*self.owner).supports_rtclock());
86
87 let fn_ptr = (*self.owner).get_api().time_restart.unwrap();
88 fn_ptr(self.ptr, &tv.0);
89 }
90}
91
92impl<T> TimeEventRef<T>
93 where T: MainloopInnerType
94{
95 pub(crate) fn from_raw(ptr: *mut TimeEventInternal, mainloop_inner: Rc<T>) -> Self {
96 assert_eq!(false, ptr.is_null());
97 Self { ptr: ptr, owner: mainloop_inner }
98 }
99
100 #[inline]
103 pub fn restart(&mut self, t: &UnixTs) {
104 let fn_ptr = (*self.owner).get_api().time_restart.unwrap();
105 fn_ptr(self.ptr, &(t.0).0);
106 }
107
108 pub fn restart_rt(&mut self, t: MonotonicTs) {
111 assert_ne!(t.0, MicroSeconds::INVALID);
112 let mut tv = Timeval::new_zero();
113 tv.set_rt(t.0, (*self.owner).supports_rtclock());
114
115 let fn_ptr = (*self.owner).get_api().time_restart.unwrap();
116 fn_ptr(self.ptr, &tv.0);
117 }
118}
119
120impl<T> Drop for TimeEvent<T>
121 where T: MainloopInnerType
122{
123 fn drop(&mut self) {
124 let fn_ptr = (*self.owner).get_api().time_free.unwrap();
125 fn_ptr(self.ptr);
126 }
127}
128
129pub(crate)
134extern "C"
135fn event_cb_proxy(_: *const MainloopApi, e: *mut TimeEventInternal, _: *const timeval,
136 userdata: *mut c_void)
137{
138 let _ = std::panic::catch_unwind(|| {
139 let callback = EventCb::get_callback(userdata);
140 (callback)(e);
141 });
142}