Skip to content

Commit

Permalink
Starting full async/await rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
svartalf committed Feb 15, 2020
1 parent 607c461 commit d0f339d
Show file tree
Hide file tree
Showing 37 changed files with 596 additions and 675 deletions.
39 changes: 19 additions & 20 deletions heim-disk/src/sys/unix/usage.rs
Expand Up @@ -56,24 +56,23 @@ impl fmt::Debug for Usage {
}
}

pub fn usage<T: AsRef<Path>>(path: T) -> impl Future<Output = Result<Usage>> {
future::lazy(move |_| {
let path = path
.as_ref()
.to_str()
.ok_or_else(|| io::Error::from(io::ErrorKind::InvalidInput))
.and_then(|string| {
CString::new(string).map_err(|_| io::Error::from(io::ErrorKind::InvalidInput))
})?;

let mut vfs = mem::MaybeUninit::<libc::statvfs>::uninit();
let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };

if result == 0 {
let vfs = unsafe { vfs.assume_init() };
Ok(Usage(vfs))
} else {
Err(Error::last_os_error())
}
})
// TODO: It is an internal function, we could monomorphize it and accept `path: &Path`
pub async fn usage<T: AsRef<Path>>(path: T) -> Result<Usage> {
let path = path
.as_ref()
.to_str()
.ok_or_else(|| io::Error::from(io::ErrorKind::InvalidInput))
.and_then(|string| {
CString::new(string).map_err(|_| io::Error::from(io::ErrorKind::InvalidInput))
})?;

let mut vfs = mem::MaybeUninit::<libc::statvfs>::uninit();
let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };

if result == 0 {
let vfs = unsafe { vfs.assume_init() };
Ok(Usage(vfs))
} else {
Err(Error::last_os_error())
}
}
40 changes: 19 additions & 21 deletions heim-disk/src/sys/windows/usage.rs
Expand Up @@ -47,27 +47,25 @@ impl fmt::Debug for Usage {
}
}

pub fn usage<T: AsRef<Path>>(path: T) -> impl Future<Output = Result<Usage>> {
future::lazy(move |_| {
let path = match widestring::U16CString::from_os_str(path.as_ref()) {
Ok(path) => path,
Err(_) => return Err(io::Error::from(io::ErrorKind::InvalidInput).into()),
};
pub async fn usage<T: AsRef<Path>>(path: T) -> Result<Usage> {
let path = match widestring::U16CString::from_os_str(path.as_ref()) {
Ok(path) => path,
Err(_) => return Err(io::Error::from(io::ErrorKind::InvalidInput).into()),
};

let mut usage = Usage::default();
let result = unsafe {
fileapi::GetDiskFreeSpaceExW(
path.as_ptr(),
&mut usage.available,
&mut usage.total,
&mut usage.free,
)
};
let mut usage = Usage::default();
let result = unsafe {
fileapi::GetDiskFreeSpaceExW(
path.as_ptr(),
&mut usage.available,
&mut usage.total,
&mut usage.free,
)
};

if result != 0 {
Ok(usage)
} else {
Err(Error::last_os_error())
}
})
if result != 0 {
Ok(usage)
} else {
Err(Error::last_os_error())
}
}
4 changes: 2 additions & 2 deletions heim-disk/src/usage.rs
Expand Up @@ -53,9 +53,9 @@ impl fmt::Debug for Usage {
/// Returns disk [Usage] statistics about the partition which contains the given `path`.
///
/// [Usage]: ./struct.Usage.html
pub fn usage<T>(path: T) -> impl Future<Output = Result<Usage>>
pub async fn usage<T>(path: T) -> Result<Usage>
where
T: AsRef<Path>,
{
sys::usage(path).map(|res| res.map(Into::into))
sys::usage(path).await.map(Into::into)
}
80 changes: 40 additions & 40 deletions heim-host/src/sys/windows/platform.rs
Expand Up @@ -113,67 +113,67 @@ impl fmt::Debug for Platform {
}
}

unsafe fn get_native_system_info() -> impl Future<Output = Result<SystemInfo>> {
fn get_native_system_info() -> SystemInfo {
let mut info = mem::MaybeUninit::<sysinfoapi::SYSTEM_INFO>::uninit();
sysinfoapi::GetNativeSystemInfo(info.as_mut_ptr());
let info = info.assume_init();

future::ok(info.into())
unsafe {
sysinfoapi::GetNativeSystemInfo(info.as_mut_ptr());
info.assume_init().into()
}
}

unsafe fn rtl_get_version() -> impl Future<Output = Result<winnt::OSVERSIONINFOEXW>> {
// Based on the `platform-info` crate source:
// https://github.com/uutils/platform-info/blob/8fa071f764d55bd8e41a96cf42009da9ae20a650/src/windows.rs
let module = match get_ntdll() {
Ok(module) => module,
Err(e) => return future::err(e),
};

let funcname = CStr::from_bytes_with_nul_unchecked(b"RtlGetVersion\0");
let func = libloaderapi::GetProcAddress(module, funcname.as_ptr());
if !func.is_null() {
let func: extern "stdcall" fn(*mut winnt::RTL_OSVERSIONINFOEXW) -> ntdef::NTSTATUS =
mem::transmute(func as *const ());

let mut osinfo = mem::MaybeUninit::<winnt::RTL_OSVERSIONINFOEXW>::uninit();
(*osinfo.as_mut_ptr()).dwOSVersionInfoSize =
mem::size_of::<winnt::RTL_OSVERSIONINFOEXW>() as minwindef::DWORD;
if func(osinfo.as_mut_ptr()) == ntstatus::STATUS_SUCCESS {
future::ok(osinfo.assume_init())
fn rtl_get_version() -> Result<winnt::OSVERSIONINFOEXW> {
unsafe {
// Based on the `platform-info` crate source:
// https://github.com/uutils/platform-info/blob/8fa071f764d55bd8e41a96cf42009da9ae20a650/src/windows.rs
// TODO: Use `ntapi` crate instead
let module = get_ntdll()?;

let funcname = CStr::from_bytes_with_nul_unchecked(b"RtlGetVersion\0");
let func = libloaderapi::GetProcAddress(module, funcname.as_ptr());
if !func.is_null() {
let func: extern "stdcall" fn(*mut winnt::RTL_OSVERSIONINFOEXW) -> ntdef::NTSTATUS =
mem::transmute(func as *const ());

let mut osinfo = mem::MaybeUninit::<winnt::RTL_OSVERSIONINFOEXW>::uninit();
(*osinfo.as_mut_ptr()).dwOSVersionInfoSize =
mem::size_of::<winnt::RTL_OSVERSIONINFOEXW>() as minwindef::DWORD;
if func(osinfo.as_mut_ptr()) == ntstatus::STATUS_SUCCESS {
Ok(osinfo.assume_init())
} else {
// https://docs.microsoft.com/en-us/windows/desktop/devnotes/rtlgetversion#return-value
unreachable!("RtlGetVersion should just work");
}
} else {
// https://docs.microsoft.com/en-us/windows/desktop/devnotes/rtlgetversion#return-value
unreachable!("RtlGetVersion should just work");
Err(io::Error::last_os_error().into())
}
} else {
future::err(io::Error::last_os_error().into())
}
}

unsafe fn get_computer_name() -> impl Future<Output = Result<String>> {
fn get_computer_name() -> Result<String> {
let mut buffer: Vec<winnt::WCHAR> = Vec::with_capacity((MAX_COMPUTERNAME_LENGTH + 1) as usize);
let mut size: minwindef::DWORD = MAX_COMPUTERNAME_LENGTH + 1;

let result = winbase::GetComputerNameW(buffer.as_mut_ptr(), &mut size);
let result = unsafe { winbase::GetComputerNameW(buffer.as_mut_ptr(), &mut size) };
if result == 0 {
future::err(Error::last_os_error())
Err(Error::last_os_error())
} else {
buffer.set_len(size as usize + 1);
unsafe {
buffer.set_len(size as usize + 1);
}
let str = OsString::from_wide(&buffer[..(size as usize)])
.to_string_lossy()
.to_string();
future::ok(str)
Ok(str)
}
}

pub fn platform() -> impl Future<Output = Result<Platform>> {
let sysinfo = unsafe { get_native_system_info() };
let version = unsafe { rtl_get_version() };
let hostname = unsafe { get_computer_name() };
pub async fn platform() -> Result<Platform> {
let version = rtl_get_version()?;

future::try_join3(sysinfo, version, hostname).map_ok(|(sysinfo, version, hostname)| Platform {
sysinfo,
Ok(Platform {
sysinfo: get_native_system_info(),
version,
hostname,
hostname: get_computer_name()?,
build: format!("{}", version.dwBuildNumber),
})
}
4 changes: 2 additions & 2 deletions heim-memory/src/memory.rs
Expand Up @@ -47,6 +47,6 @@ impl fmt::Debug for Memory {
/// Returns future which will resolve into [Memory] struct.
///
/// [Memory]: ./struct.Memory.html
pub fn memory() -> impl future::Future<Output = Result<Memory>> {
sys::memory().map(|res| res.map(Into::into))
pub async fn memory() -> Result<Memory> {
sys::memory().await.map(Into::into)
}
4 changes: 2 additions & 2 deletions heim-memory/src/swap.rs
Expand Up @@ -45,6 +45,6 @@ impl fmt::Debug for Swap {
/// Returns future which will resolve into [Swap] struct.
///
/// [Swap]: ./struct.Swap.html
pub fn swap() -> impl Future<Output = Result<Swap>> {
sys::swap().map(|res| res.map(Into::into))
pub async fn swap() -> Result<Swap> {
sys::swap().await.map(Into::into)
}
4 changes: 2 additions & 2 deletions heim-memory/src/sys/linux/memory.rs
Expand Up @@ -101,6 +101,6 @@ impl FromStr for Memory {
}
}

pub fn memory() -> impl Future<Output = Result<Memory>> {
fs::read_into("/proc/meminfo")
pub async fn memory() -> Result<Memory> {
fs::read_into("/proc/meminfo").await
}
20 changes: 10 additions & 10 deletions heim-memory/src/sys/linux/swap.rs
Expand Up @@ -134,16 +134,16 @@ impl Swap {
}
}

fn vm_stat() -> impl Future<Output = Result<VmStat>> {
fs::read_into(PROC_VMSTAT)
async fn vm_stat() -> Result<VmStat> {
fs::read_into(PROC_VMSTAT).await
}

pub fn swap() -> impl Future<Output = Result<Swap>> {
let meminfo = fs::read_to_string(PROC_MEMINFO);
// TODO: Replace with `try_join`
future::join(meminfo, vm_stat()).then(|result| match result {
(Ok(string), Ok(vm_stat)) => future::ready(Swap::parse_str(&string, vm_stat)),
(Err(e), _) => future::err(e.into()),
(_, Err(e)) => future::err(e),
})
pub async fn swap() -> Result<Swap> {
let (meminfo, vm_stat) = future::try_join(
fs::read_to_string(PROC_MEMINFO).map_err(Into::into),
vm_stat(),
)
.await?;

Swap::parse_str(&meminfo, vm_stat)
}
3 changes: 3 additions & 0 deletions heim-memory/src/sys/macos/bindings.rs
Expand Up @@ -51,6 +51,7 @@ pub struct vm_statistics64 {
pub total_uncompressed_pages_in_compressor: u64,
}

// TODO: Function should not be marked as `unsafe` itself
#[allow(trivial_casts)]
pub unsafe fn host_vm_info() -> Result<vm_statistics64> {
let port = macos::mach_host_self();
Expand Down Expand Up @@ -81,6 +82,7 @@ pub unsafe fn host_vm_info() -> Result<vm_statistics64> {
}
}

// TODO: Function should not be marked as `unsafe` itself
#[allow(trivial_casts)]
pub unsafe fn hw_memsize() -> Result<u64> {
let mut name: [i32; 2] = [CTL_HW, HW_MEMSIZE];
Expand All @@ -103,6 +105,7 @@ pub unsafe fn hw_memsize() -> Result<u64> {
}
}

// TODO: Function should not be marked as `unsafe` itself
pub unsafe fn vm_swapusage() -> Result<libc::xsw_usage> {
let mut name: [i32; 2] = [CTL_VM, VM_SWAPUSAGE];
let mut value = mem::MaybeUninit::<libc::xsw_usage>::uninit();
Expand Down
57 changes: 27 additions & 30 deletions heim-memory/src/sys/macos/memory.rs
Expand Up @@ -44,37 +44,34 @@ impl Memory {
}
}

pub fn memory() -> impl Future<Output = Result<Memory>> {
future::lazy(|_| {
let total = unsafe { bindings::hw_memsize()? };
let vm_stats = unsafe { bindings::host_vm_info()? };
let page_size = *PAGE_SIZE;
pub async fn memory() -> Result<Memory> {
let total = unsafe { bindings::hw_memsize()? };
let vm_stats = unsafe { bindings::host_vm_info()? };
let page_size = *PAGE_SIZE;

let total = Information::new::<information::byte>(total);
let available = Information::new::<information::byte>(
u64::from(vm_stats.active_count + vm_stats.free_count) * page_size,
);
let free = Information::new::<information::byte>(
u64::from(vm_stats.free_count - vm_stats.speculative_count) * page_size,
);
let used = Information::new::<information::byte>(
u64::from(vm_stats.active_count + vm_stats.wire_count) * page_size,
);
let active =
Information::new::<information::byte>(u64::from(vm_stats.active_count) * page_size);
let inactive =
Information::new::<information::byte>(u64::from(vm_stats.inactive_count) * page_size);
let wire =
Information::new::<information::byte>(u64::from(vm_stats.wire_count) * page_size);
let total = Information::new::<information::byte>(total);
let available = Information::new::<information::byte>(
u64::from(vm_stats.active_count + vm_stats.free_count) * page_size,
);
let free = Information::new::<information::byte>(
u64::from(vm_stats.free_count - vm_stats.speculative_count) * page_size,
);
let used = Information::new::<information::byte>(
u64::from(vm_stats.active_count + vm_stats.wire_count) * page_size,
);
let active =
Information::new::<information::byte>(u64::from(vm_stats.active_count) * page_size);
let inactive =
Information::new::<information::byte>(u64::from(vm_stats.inactive_count) * page_size);
let wire = Information::new::<information::byte>(u64::from(vm_stats.wire_count) * page_size);

Ok(Memory {
total,
available,
free,
used,
active,
inactive,
wire,
})
Ok(Memory {
total,
available,
free,
used,
active,
inactive,
wire,
})
}
36 changes: 17 additions & 19 deletions heim-memory/src/sys/macos/swap.rs
Expand Up @@ -35,24 +35,22 @@ impl Swap {
}

#[allow(clippy::identity_conversion)]
pub fn swap() -> impl Future<Output = Result<Swap>> {
future::lazy(|_| {
let xsw_usage = unsafe { bindings::vm_swapusage()? };
let vm_stats = unsafe { bindings::host_vm_info()? };
let page_size = *PAGE_SIZE;

let total = Information::new::<information::byte>(u64::from(xsw_usage.xsu_total));
let used = Information::new::<information::byte>(u64::from(xsw_usage.xsu_used));
let free = Information::new::<information::byte>(u64::from(xsw_usage.xsu_avail));
let sin = Information::new::<information::byte>(u64::from(vm_stats.pageins) * page_size);
let sout = Information::new::<information::byte>(u64::from(vm_stats.pageouts) * page_size);

Ok(Swap {
total,
free,
used,
sin,
sout,
})
pub async fn swap() -> Result<Swap> {
let xsw_usage = unsafe { bindings::vm_swapusage()? };
let vm_stats = unsafe { bindings::host_vm_info()? };
let page_size = *PAGE_SIZE;

let total = Information::new::<information::byte>(u64::from(xsw_usage.xsu_total));
let used = Information::new::<information::byte>(u64::from(xsw_usage.xsu_used));
let free = Information::new::<information::byte>(u64::from(xsw_usage.xsu_avail));
let sin = Information::new::<information::byte>(u64::from(vm_stats.pageins) * page_size);
let sout = Information::new::<information::byte>(u64::from(vm_stats.pageouts) * page_size);

Ok(Swap {
total,
free,
used,
sin,
sout,
})
}

0 comments on commit d0f339d

Please sign in to comment.