alsh_libuv/handles/
signal.rs1use crate::{FromInner, HandleTrait, Inner, IntoInner};
2use std::convert::TryFrom;
3use uv::{uv_signal_init, uv_signal_start, uv_signal_start_oneshot, uv_signal_stop, uv_signal_t};
4
5callbacks! {
6 pub SignalCB(handle: SignalHandle, signum: i32);
7}
8
9#[derive(Default)]
11pub(crate) struct SignalDataFields<'a> {
12 signal_cb: SignalCB<'a>,
13}
14
15extern "C" fn uv_signal_cb(handle: *mut uv_signal_t, signum: std::os::raw::c_int) {
17 let dataptr = crate::Handle::get_data(uv_handle!(handle));
18 if !dataptr.is_null() {
19 unsafe {
20 if let super::SignalData(d) = &mut (*dataptr).addl {
21 d.signal_cb.call(handle.into_inner(), signum as _);
22 }
23 }
24 }
25}
26
27#[derive(Clone, Copy)]
55pub struct SignalHandle {
56 handle: *mut uv_signal_t,
57}
58
59impl SignalHandle {
60 pub fn new(r#loop: &crate::Loop) -> crate::Result<SignalHandle> {
62 let layout = std::alloc::Layout::new::<uv_signal_t>();
63 let handle = unsafe { std::alloc::alloc(layout) as *mut uv_signal_t };
64 if handle.is_null() {
65 return Err(crate::Error::ENOMEM);
66 }
67
68 let ret = unsafe { uv_signal_init(r#loop.into_inner(), handle) };
69 if ret < 0 {
70 unsafe { std::alloc::dealloc(handle as _, layout) };
71 return Err(crate::Error::from_inner(ret as uv::uv_errno_t));
72 }
73
74 crate::Handle::initialize_data(uv_handle!(handle), super::SignalData(Default::default()));
75
76 Ok(SignalHandle { handle })
77 }
78
79 pub fn start<CB: Into<SignalCB<'static>>>(&mut self, cb: CB, signum: i32) -> crate::Result<()> {
81 let cb = cb.into();
83 let uv_cb = use_c_callback!(uv_signal_cb, cb);
84
85 let dataptr = crate::Handle::get_data(uv_handle!(self.handle));
87 if !dataptr.is_null() {
88 if let super::SignalData(d) = unsafe { &mut (*dataptr).addl } {
89 d.signal_cb = cb;
90 }
91 }
92
93 crate::uvret(unsafe { uv_signal_start(self.handle, uv_cb, signum as _) })
94 }
95
96 pub fn start_oneshot<CB: Into<SignalCB<'static>>>(
99 &mut self,
100 cb: CB,
101 signum: i32,
102 ) -> crate::Result<()> {
103 let cb = cb.into();
105 let uv_cb = use_c_callback!(uv_signal_cb, cb);
106
107 let dataptr = crate::Handle::get_data(uv_handle!(self.handle));
109 if !dataptr.is_null() {
110 if let super::SignalData(d) = unsafe { &mut (*dataptr).addl } {
111 d.signal_cb = cb;
112 }
113 }
114
115 crate::uvret(unsafe { uv_signal_start_oneshot(self.handle, uv_cb, signum as _) })
116 }
117
118 pub fn stop(&mut self) -> crate::Result<()> {
120 crate::uvret(unsafe { uv_signal_stop(self.handle) })
121 }
122
123 pub fn signum(&self) -> i32 {
125 unsafe { (*self.handle).signum }
126 }
127}
128
129impl FromInner<*mut uv_signal_t> for SignalHandle {
130 fn from_inner(handle: *mut uv_signal_t) -> SignalHandle {
131 SignalHandle { handle }
132 }
133}
134
135impl Inner<*mut uv::uv_handle_t> for SignalHandle {
136 fn inner(&self) -> *mut uv::uv_handle_t {
137 uv_handle!(self.handle)
138 }
139}
140
141impl From<SignalHandle> for crate::Handle {
142 fn from(signal: SignalHandle) -> crate::Handle {
143 crate::Handle::from_inner(Inner::<*mut uv::uv_handle_t>::inner(&signal))
144 }
145}
146
147impl crate::ToHandle for SignalHandle {
148 fn to_handle(&self) -> crate::Handle {
149 crate::Handle::from_inner(Inner::<*mut uv::uv_handle_t>::inner(self))
150 }
151}
152
153impl TryFrom<crate::Handle> for SignalHandle {
154 type Error = crate::ConversionError;
155
156 fn try_from(handle: crate::Handle) -> Result<Self, Self::Error> {
157 let t = handle.get_type();
158 if t != crate::HandleType::SIGNAL {
159 Err(crate::ConversionError::new(t, crate::HandleType::SIGNAL))
160 } else {
161 Ok((handle.inner() as *mut uv_signal_t).into_inner())
162 }
163 }
164}
165
166impl HandleTrait for SignalHandle {}
167
168impl crate::Loop {
169 pub fn signal(&self) -> crate::Result<SignalHandle> {
171 SignalHandle::new(self)
172 }
173}