Skip to content

Commit e4afeed

Browse files
committed
imp(wrapper): add wrapper functions for libc
1 parent 8cde1ee commit e4afeed

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/timer/epoll.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// https://www.apache.org/licenses/LICENSE-2.0>. This file may not be copied, modified, or distributed
55
// except according to those terms.
66

7+
use crate::utils::{epoll_create1, epoll_ctl, epoll_wait, read, timerfd_create, timerfd_settime};
78
use crate::Result;
89

910
use std::sync::{mpsc::Sender, Arc, Mutex};
@@ -57,8 +58,7 @@ impl Timer {
5758
let clockid: libc::clockid_t = libc::CLOCK_REALTIME;
5859
let clock_flags: libc::c_int = libc::TFD_NONBLOCK;
5960

60-
// TODO: handler error (-1)
61-
let tfd = unsafe { libc::timerfd_create(clockid, clock_flags) };
61+
let tfd = timerfd_create(clockid, clock_flags).unwrap();
6262

6363
let now = std::time::SystemTime::now()
6464
.duration_since(std::time::UNIX_EPOCH)?
@@ -92,15 +92,13 @@ impl Timer {
9292

9393
let set_flags = libc::TFD_TIMER_ABSTIME;
9494

95-
// TODO: handler error (-1)
96-
let sfd = unsafe { libc::timerfd_settime(tfd, set_flags, &mut new_value, &mut old_value) };
95+
timerfd_settime(tfd, set_flags, &mut new_value, &mut old_value).unwrap();
9796

9897
Ok(tfd)
9998
}
10099

101100
fn create_epollfd(timer_fd: libc::c_int) -> Result<libc::c_int> {
102-
// TODO: handler error (-1)
103-
let epoll_fd = unsafe { libc::epoll_create1(0) };
101+
let epoll_fd = epoll_create1(0).unwrap();
104102

105103
let mut event = libc::epoll_event {
106104
events: libc::EPOLLIN as u32,
@@ -109,22 +107,20 @@ impl Timer {
109107

110108
let epoll_flags = libc::EPOLL_CTL_ADD;
111109

112-
// TODO: handler error (-1)
113-
let ctl_fd = unsafe { libc::epoll_ctl(epoll_fd, epoll_flags, timer_fd, &mut event) };
110+
epoll_ctl(epoll_fd, epoll_flags, timer_fd, &mut event).unwrap();
114111

115112
Ok(epoll_fd)
116113
}
117114

118115
fn epoll_wait(timer_fd: libc::c_int, epoll_fd: libc::c_int) -> Result<()> {
119116
let mut events = Vec::with_capacity(1);
120117

121-
// TODO: handler error (-1)
122-
let wait = unsafe { libc::epoll_wait(epoll_fd, events.as_mut_ptr(), 1, -1) };
118+
epoll_wait(epoll_fd, events.as_mut_ptr(), 1, -1).unwrap();
119+
123120
let mut buffer: u64 = 0;
124121
let bufptr: *mut _ = &mut buffer;
125122

126-
// TODO: handler error (-1)
127-
let read = unsafe { libc::read(timer_fd, bufptr as *mut libc::c_void, 8) };
123+
read(timer_fd, bufptr as *mut libc::c_void, 8).unwrap();
128124

129125
Ok(())
130126
}

src/utils.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// except according to those terms.
66

77
use crate::error::Result;
8+
use crate::PyroscopeError;
89

910
use std::collections::HashMap;
1011

@@ -54,3 +55,61 @@ mod tests {
5455
)
5556
}
5657
}
58+
59+
/// Wrapper for libc functions.
60+
///
61+
/// Error wrapper for some libc functions used by the library. This only does
62+
/// Error (-1 return) wrapping. Alternatively, the nix crate could be used
63+
/// instead of expanding this wrappers (if more functions and types are used
64+
/// from libc)
65+
66+
/// Error Wrapper for libc return. Only check for errors.
67+
fn check_err<T: Ord + Default>(num: T) -> Result<T> {
68+
if num < T::default() {
69+
return Err(PyroscopeError::from(std::io::Error::last_os_error()));
70+
}
71+
Ok(num)
72+
}
73+
74+
/// libc::timerfd wrapper
75+
pub fn timerfd_create(clockid: libc::clockid_t, clock_flags: libc::c_int) -> Result<i32> {
76+
check_err(unsafe { libc::timerfd_create(clockid, clock_flags) }).map(|timer_fd| timer_fd as i32)
77+
}
78+
79+
/// libc::timerfd_settime wrapper
80+
pub fn timerfd_settime(
81+
timer_fd: i32, set_flags: libc::c_int, new_value: &mut libc::itimerspec,
82+
old_value: &mut libc::itimerspec,
83+
) -> Result<()> {
84+
check_err(unsafe { libc::timerfd_settime(timer_fd, set_flags, new_value, old_value) })?;
85+
Ok(())
86+
}
87+
88+
/// libc::epoll_create1 wrapper
89+
pub fn epoll_create1(epoll_flags: libc::c_int) -> Result<i32> {
90+
check_err(unsafe { libc::epoll_create1(epoll_flags) }).map(|epoll_fd| epoll_fd as i32)
91+
}
92+
93+
/// libc::epoll_ctl wrapper
94+
pub fn epoll_ctl(epoll_fd: i32, epoll_flags: libc::c_int, timer_fd: i32, event: &mut libc::epoll_event) -> Result<()> {
95+
check_err(unsafe {
96+
libc::epoll_ctl(epoll_fd, epoll_flags, timer_fd, event)
97+
})?;
98+
Ok(())
99+
}
100+
101+
/// libc::epoll_wait wrapper
102+
pub fn epoll_wait(epoll_fd: i32, events: *mut libc::epoll_event, maxevents: libc::c_int, timeout: libc::c_int) -> Result<()> {
103+
check_err(unsafe {
104+
libc::epoll_wait(epoll_fd, events, maxevents, timeout)
105+
})?;
106+
Ok(())
107+
}
108+
109+
/// libc::read wrapper
110+
pub fn read(timer_fd: i32, bufptr: *mut libc::c_void, count: libc::size_t) -> Result<()> {
111+
check_err(unsafe {
112+
libc::read(timer_fd, bufptr, count)
113+
})?;
114+
Ok(())
115+
}

0 commit comments

Comments
 (0)