Skip to content

Commit

Permalink
upgrade to libuv v1.45.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bmatcuk committed Oct 9, 2023
1 parent df60c99 commit 6a3bb7c
Show file tree
Hide file tree
Showing 17 changed files with 126 additions and 29 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libuv"
version = "2.5.0"
version = "2.6.0"
description = "A safe rust wrapper for libuv"
homepage = "https://github.com/bmatcuk/libuv-rs"
repository = "https://github.com/bmatcuk/libuv-rs"
Expand All @@ -20,7 +20,7 @@ maintenance = { status = "actively-developed" }

[dependencies]
bitflags = "~1.2.1"
libuv-sys2 = "~1.44.2"
libuv-sys2 = "~1.45.0"

[dev-dependencies]
rand = "~0.7.3"
Expand Down
3 changes: 3 additions & 0 deletions src/error.inc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub enum Error {
ENETUNREACH,
ENFILE,
ENOBUFS,
ENODATA,
ENODEV,
ENOENT,
ENOMEM,
Expand Down Expand Up @@ -139,6 +140,7 @@ impl crate::FromInner<uv::uv_errno_t> for Error {
uv::uv_errno_t_UV_ENETUNREACH => Error::ENETUNREACH,
uv::uv_errno_t_UV_ENFILE => Error::ENFILE,
uv::uv_errno_t_UV_ENOBUFS => Error::ENOBUFS,
uv::uv_errno_t_UV_ENODATA => Error::ENODATA,
uv::uv_errno_t_UV_ENODEV => Error::ENODEV,
uv::uv_errno_t_UV_ENOENT => Error::ENOENT,
uv::uv_errno_t_UV_ENOMEM => Error::ENOMEM,
Expand Down Expand Up @@ -230,6 +232,7 @@ impl Error {
Error::ENETUNREACH => uv::uv_errno_t_UV_ENETUNREACH,
Error::ENFILE => uv::uv_errno_t_UV_ENFILE,
Error::ENOBUFS => uv::uv_errno_t_UV_ENOBUFS,
Error::ENODATA => uv::uv_errno_t_UV_ENODATA,
Error::ENODEV => uv::uv_errno_t_UV_ENODEV,
Error::ENOENT => uv::uv_errno_t_UV_ENOENT,
Error::ENOMEM => uv::uv_errno_t_UV_ENOMEM,
Expand Down
3 changes: 3 additions & 0 deletions src/fs/fs_types.inc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum FsType {
LCHOWN,
LINK,
LSTAT,
LUTIME,
MKDIR,
MKDTEMP,
MKSTEMP,
Expand Down Expand Up @@ -60,6 +61,7 @@ impl crate::FromInner<uv::uv_fs_type> for FsType {
uv::uv_fs_type_UV_FS_LCHOWN => FsType::LCHOWN,
uv::uv_fs_type_UV_FS_LINK => FsType::LINK,
uv::uv_fs_type_UV_FS_LSTAT => FsType::LSTAT,
uv::uv_fs_type_UV_FS_LUTIME => FsType::LUTIME,
uv::uv_fs_type_UV_FS_MKDIR => FsType::MKDIR,
uv::uv_fs_type_UV_FS_MKDTEMP => FsType::MKDTEMP,
uv::uv_fs_type_UV_FS_MKSTEMP => FsType::MKSTEMP,
Expand Down Expand Up @@ -104,6 +106,7 @@ impl crate::IntoInner<uv::uv_fs_type> for &FsType {
FsType::LCHOWN => uv::uv_fs_type_UV_FS_LCHOWN,
FsType::LINK => uv::uv_fs_type_UV_FS_LINK,
FsType::LSTAT => uv::uv_fs_type_UV_FS_LSTAT,
FsType::LUTIME => uv::uv_fs_type_UV_FS_LUTIME,
FsType::MKDIR => uv::uv_fs_type_UV_FS_MKDIR,
FsType::MKDTEMP => uv::uv_fs_type_UV_FS_MKDTEMP,
FsType::MKSTEMP => uv::uv_fs_type_UV_FS_MKSTEMP,
Expand Down
4 changes: 2 additions & 2 deletions src/fs/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn chdir(dir: &str) -> Result<(), Box<dyn std::error::Error>> {

/// Gets the current working directory.
pub fn cwd() -> crate::Result<String> {
let mut size = 0u64;
let mut size = 0usize;
unsafe { uv_cwd(std::ptr::null_mut(), &mut size as _) };

let mut buf: Vec<std::os::raw::c_uchar> = Vec::with_capacity(size as _);
Expand All @@ -24,7 +24,7 @@ pub fn cwd() -> crate::Result<String> {

/// Gets the executable path. You must call setup_args before calling this function.
pub fn exepath() -> crate::Result<String> {
let mut allocated = 32u64;
let mut allocated = 32usize;
let mut size = allocated - 1;
let mut buf: Vec<std::os::raw::c_uchar> = vec![];
while size == allocated - 1 {
Expand Down
5 changes: 5 additions & 0 deletions src/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! All file operations are run on the threadpool. See Thread pool work scheduling for information
//! on the threadpool size.
//!
//! Starting with libuv v1.45.0, some file operations on Linux are handed off to io_uring
//! <https://en.wikipedia.org/wiki/Io_uring> when possible. Apart from a (sometimes significant)
//! increase in throughput there should be no change in observable behavior. Libuv reverts to using
//! its threadpool when the necessary kernel features are unavailable or unsuitable.
//!
//! Note: Uses utf-8 encoding on Windows

include!("./fs_copy_flags.inc.rs");
Expand Down
2 changes: 1 addition & 1 deletion src/handles/fs_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl FsEventHandle {
/// Get the path being monitored by the handle.
pub fn getpath(&self) -> crate::Result<String> {
// retrieve the size of the buffer we need to allocate
let mut size = 0u64;
let mut size = 0usize;
let result = crate::uvret(unsafe {
uv_fs_event_getpath(self.handle, std::ptr::null_mut(), &mut size as _)
});
Expand Down
2 changes: 1 addition & 1 deletion src/handles/fs_poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl FsPollHandle {
/// Get the path being monitored by the handle.
pub fn getpath(&self) -> crate::Result<String> {
// retrieve the size of the buffer we need to allocate
let mut size = 0u64;
let mut size = 0usize;
let result = crate::uvret(unsafe {
uv_fs_poll_getpath(self.handle, std::ptr::null_mut(), &mut size as _)
});
Expand Down
2 changes: 2 additions & 0 deletions src/handles/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ pub trait HandleTrait: ToHandle {
///
/// In-progress requests, like ConnectRequest or WriteRequest, are cancelled and have their
/// callbacks called asynchronously with status=UV_ECANCELED.
///
/// cb can be Nil in cases where no cleanup or deallocation is necessary.
fn close<CB: Into<CloseCB<'static>>>(&mut self, cb: CB) {
let handle = self.to_handle().inner();

Expand Down
4 changes: 3 additions & 1 deletion src/handles/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ impl PollHandle {
///
/// If an error happens while polling, status will be a libuv::Error. The user should not close
/// the socket while the handle is active. If the user does that anyway, the callback may be
/// called reporting an error status, but this is not guaranteed.
/// called reporting an error status, but this is not guaranteed. If status == EBADF polling is
/// discontinued for the file handle and no further events will be reported. The user should
/// then call close() on the handle.
///
/// Note: Calling start() on a handle that is already active is fine. Doing so will update the
/// events mask that is being watched for.
Expand Down
2 changes: 1 addition & 1 deletion src/handles/streams/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub(crate) struct StreamDataFields<'a> {
/// Callback for uv_recv_start, uv_udp_recv_start
pub(crate) extern "C" fn uv_alloc_cb(
handle: *mut uv::uv_handle_t,
suggested_size: u64,
suggested_size: usize,
buf: *mut uv::uv_buf_t,
) {
let dataptr = StreamHandle::get_data(uv_handle!(handle));
Expand Down
2 changes: 1 addition & 1 deletion src/handles/streams/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bitflags! {

/// Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. This sets
/// IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on Linux. This stops the
/// Linux kernel from supressing some ICMP error messages and enables full ICMP error
/// Linux kernel from suppressing some ICMP error messages and enables full ICMP error
/// reporting for faster failover. This flag is no-op on platforms other than Linux.
const RECVERR = uv::uv_udp_flags_UV_UDP_LINUX_RECVERR as _;
}
Expand Down
3 changes: 0 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ macro_rules! use_c_callback {
};
}

#[cfg(not(windows))]
pub(crate) type NREAD = i64;
#[cfg(windows)]
pub(crate) type NREAD = isize;

pub type Result<T> = std::result::Result<T, Error>;
Expand Down
35 changes: 33 additions & 2 deletions src/loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use uv::{
uv_backend_fd, uv_backend_timeout, uv_default_loop, uv_handle_t, uv_loop_alive, uv_loop_close,
uv_loop_configure, uv_loop_delete, uv_loop_fork, uv_loop_get_data, uv_loop_init, uv_loop_new,
uv_loop_option_UV_LOOP_BLOCK_SIGNAL, uv_loop_option_UV_METRICS_IDLE_TIME, uv_loop_set_data,
uv_loop_t, uv_metrics_idle_time, uv_now, uv_run, uv_run_mode, uv_run_mode_UV_RUN_DEFAULT,
uv_run_mode_UV_RUN_NOWAIT, uv_run_mode_UV_RUN_ONCE, uv_stop, uv_update_time, uv_walk,
uv_loop_t, uv_metrics_idle_time, uv_metrics_info, uv_metrics_t, uv_now, uv_run, uv_run_mode,
uv_run_mode_UV_RUN_DEFAULT, uv_run_mode_UV_RUN_NOWAIT, uv_run_mode_UV_RUN_ONCE, uv_stop,
uv_update_time, uv_walk,
};

/// Mode used to run the loop.
Expand Down Expand Up @@ -35,6 +36,29 @@ impl IntoInner<uv_run_mode> for RunMode {
}
}

/// The struct that contains event loop metrics. It is recommended to retrieve these metrics in a
/// PrepareCB in order to make sure there are no inconsistencies with the metrics counters.
pub struct Metrics {
/// Number of event loop iterations.
pub loop_count: u64,

/// Number of events that have been processed by the event handler.
pub events: u64,

/// Number of events that were waiting to be processed when the event provider was called.
pub events_waiting: u64,
}

impl FromInner<uv_metrics_t> for Metrics {
fn from_inner(metrics: uv_metrics_t) -> Metrics {
Metrics {
loop_count: metrics.loop_count,
events: metrics.events,
events_waiting: metrics.events_waiting,
}
}
}

/// Data that we need to track with the loop.
#[derive(Default)]
pub(crate) struct LoopData {
Expand Down Expand Up @@ -184,6 +208,13 @@ impl Loop {
unsafe { uv_metrics_idle_time(self.handle) }
}

/// The current set of event loop metrics.
pub fn metrics_info(&self) -> crate::Result<Metrics> {
let mut metrics: uv_metrics_t = unsafe { std::mem::zeroed() };
crate::uvret(unsafe { uv_metrics_info(self.handle, &mut metrics as _) })
.map(|_| metrics.into_inner())
}

/// Stop the event loop, causing run() to end as soon as possible. This will happen not sooner
/// than the next loop iteration. If this function was called before blocking for i/o, the loop
/// won’t block for i/o on this iteration.
Expand Down
74 changes: 64 additions & 10 deletions src/misc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{FromInner, IntoInner};
use std::ffi::{CStr, CString};
use uv::{
uv_cpu_info, uv_cpu_info_t, uv_free_cpu_info, uv_get_constrained_memory, uv_get_free_memory,
uv_get_process_title, uv_get_total_memory, uv_getrusage, uv_gettimeofday, uv_hrtime,
uv_library_shutdown, uv_loadavg, uv_resident_set_memory, uv_rusage_t, uv_set_process_title,
uv_setup_args, uv_sleep, uv_timeval64_t, uv_timeval_t, uv_uptime,
uv_clock_gettime, uv_cpu_info, uv_cpu_info_t, uv_cpumask_size, uv_free_cpu_info,
uv_get_available_memory, uv_get_constrained_memory, uv_get_free_memory, uv_get_process_title,
uv_get_total_memory, uv_getrusage, uv_gettimeofday, uv_hrtime, uv_library_shutdown, uv_loadavg,
uv_resident_set_memory, uv_rusage_t, uv_set_process_title, uv_setup_args, uv_sleep,
uv_timespec64_t, uv_timeval64_t, uv_timeval_t, uv_uptime,
};

pub mod os;
Expand Down Expand Up @@ -136,6 +137,28 @@ impl FromInner<&uv_cpu_info_t> for CpuInfo {
}
}

/// Clock source for clock_gettime().
#[repr(u32)]
pub enum ClockId {
Monotonic = uv::uv_clock_id_UV_CLOCK_MONOTONIC as _,
Realtime = uv::uv_clock_id_UV_CLOCK_REALTIME as _,
}

/// Y2K38-safe data type for storing times with nanosecond resolution.
pub struct TimeSpec64 {
pub sec: i64,
pub nsec: i32,
}

impl FromInner<uv_timespec64_t> for TimeSpec64 {
fn from_inner(timespec: uv_timespec64_t) -> TimeSpec64 {
TimeSpec64 {
sec: timespec.tv_sec,
nsec: timespec.tv_nsec,
}
}
}

/// Store the program arguments. Required for getting / setting the process title or the executable
/// path. Libuv may take ownership of the memory that argv points to. This function should be
/// called exactly once, at program start-up.
Expand Down Expand Up @@ -223,7 +246,7 @@ pub fn set_process_title(title: &str) -> Result<(), Box<dyn std::error::Error>>

/// Gets the resident set size (RSS) for the current process.
pub fn resident_set_memory() -> crate::Result<usize> {
let mut rss = 0u64;
let mut rss = 0usize;
crate::uvret(unsafe { uv_resident_set_memory(&mut rss as _) }).map(|_| rss as _)
}

Expand Down Expand Up @@ -257,6 +280,12 @@ pub fn cpu_info() -> crate::Result<Vec<CpuInfo>> {
Ok(result)
}

/// Returns the maximum size of the mask used for process/thread affinities, or ENOTSUP if
/// affinities are not supported on the current platform.
pub fn cpumask_size() -> i32 {
unsafe { uv_cpumask_size() }
}

/// Gets the load average. See: https://en.wikipedia.org/wiki/Load_(computing)
///
/// Note: Returns [0,0,0] on Windows (i.e., it’s not implemented).
Expand All @@ -267,26 +296,39 @@ pub fn loadavg() -> [f64; 3] {
}

/// Gets the amount of free memory available in the system, as reported by the kernel (in bytes).
/// Returns 0 when unknown.
pub fn get_free_memory() -> u64 {
unsafe { uv_get_free_memory() }
}

/// Gets the total amount of physical memory in the system (in bytes).
/// Gets the total amount of physical memory in the system (in bytes). Returns 0 when unknown.
pub fn get_total_memory() -> u64 {
unsafe { uv_get_total_memory() }
}

/// Gets the amount of memory available to the process (in bytes) based on limits imposed by the
/// OS. If there is no such constraint, or the constraint is unknown, 0 is returned. Note that it
/// is not unusual for this value to be less than or greater than uv_get_total_memory().
/// Gets the total amount of memory available to the process (in bytes) based on limits imposed by
/// the OS. If there is no such constraint, or the constraint is unknown, 0 is returned. If there
/// is a constraining mechanism, but there is no constraint set, `UINT64_MAX` is returned. Note
/// that it is not unusual for this value to be less than or greater than get_total_memory().
///
/// Note: This function currently only returns a non-zero value on Linux, based on cgroups if it is
/// present, and on z/OS based on RLIMIT_MEMLIMIT.
pub fn get_constrained_memory() -> u64 {
unsafe { uv_get_constrained_memory() }
}

/// Returns the current high-resolution real time. This is expressed in nanoseconds. It is relative
/// Gets the amount of free memory that is still available to the process (in bytes). This differs
/// from get_free_memory() in that it takes into account any limits imposed by the OS. If there is
/// no such constraint, or the constraint is unknown, the amount returned will be identical to
/// get_free_memory().
///
/// Note: This function currently only returns a value that is different from what
/// get_free_memory() reports on Linux, based on cgroups if it is present.
pub fn get_available_memory() -> u64 {
unsafe { uv_get_available_memory() }
}

/// Returns the current high-resolution timestamp. This is expressed in nanoseconds. It is relative
/// to an arbitrary time in the past. It is not related to the time of day and therefore not
/// subject to clock drift. The primary use is for measuring performance between intervals.
///
Expand All @@ -296,6 +338,18 @@ pub fn hrtime() -> u64 {
unsafe { uv_hrtime() }
}

/// Obtain the current system time from a high-resolution real-time or monotonic clock source.
///
/// The real-time clock counts from the UNIX epoch (1970-01-01) and is subject to time adjustments;
/// it can jump back in time.
///
/// The monotonic clock counts from an arbitrary point in the past and never jumps back in time.
pub fn clock_gettime(clock_id: ClockId) -> crate::Result<TimeSpec64> {
let mut timespec: uv_timespec64_t = unsafe { std::mem::zeroed() };
crate::uvret(unsafe { uv_clock_gettime(clock_id as _, &mut timespec as _) })
.map(|_| timespec.into_inner())
}

/// Cross-platform implementation of gettimeofday(2). The timezone argument to gettimeofday() is
/// not supported, as it is considered obsolete.
pub fn gettimeofday() -> crate::Result<TimeVal> {
Expand Down
2 changes: 1 addition & 1 deletion src/misc/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub fn get_passwd() -> crate::Result<User> {

/// Returns the hostname
pub fn gethostname() -> crate::Result<String> {
let mut size = UV_MAXHOSTNAMESIZE as u64;
let mut size = UV_MAXHOSTNAMESIZE as usize;
let mut buf: Vec<std::os::raw::c_uchar> = Vec::with_capacity(size as _);
crate::uvret(unsafe { uv_os_gethostname(buf.as_mut_ptr() as _, &mut size as _) }).map(|_| {
// size is the length of the string, *not* including the null
Expand Down
4 changes: 2 additions & 2 deletions src/net/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl TryFromInner<&uv_interface_address_t> for InterfaceAddress {
///
/// To get an interface identifier in a cross-platform compatible way, use if_indextoiid().
pub fn if_indextoname(ifindex: u32) -> crate::Result<String> {
let mut size = UV_IF_NAMESIZE as u64;
let mut size = UV_IF_NAMESIZE as usize;
let mut buf: Vec<std::os::raw::c_uchar> = Vec::with_capacity(size as _);
crate::uvret(unsafe { uv_if_indextoname(ifindex, buf.as_mut_ptr() as _, &mut size as _) }).map(
|_| {
Expand All @@ -68,7 +68,7 @@ pub fn if_indextoname(ifindex: u32) -> crate::Result<String> {
///
/// See uv_if_indextoname for further details.
pub fn if_indexto_iid(ifindex: u32) -> crate::Result<String> {
let mut size = UV_IF_NAMESIZE as u64;
let mut size = UV_IF_NAMESIZE as usize;
let mut buf: Vec<std::os::raw::c_uchar> = Vec::with_capacity(size as _);
crate::uvret(unsafe { uv_if_indextoiid(ifindex, buf.as_mut_ptr() as _, &mut size as _) }).map(
|_| {
Expand Down
4 changes: 2 additions & 2 deletions src/requests/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern "C" fn uv_random_cb(
req: *mut uv_random_t,
status: std::os::raw::c_int,
buf: *mut std::os::raw::c_void,
buflen: u64,
buflen: usize,
) {
let dataptr = crate::Req::get_data(uv_handle!(req));
if !dataptr.is_null() {
Expand Down Expand Up @@ -191,7 +191,7 @@ impl crate::Loop {
*mut uv_random_t,
std::os::raw::c_int,
*mut std::os::raw::c_void,
u64,
usize,
),
>,
)
Expand Down

0 comments on commit 6a3bb7c

Please sign in to comment.