Skip to content

Commit

Permalink
Upgraded deprecated version of 'winapi' (#40)
Browse files Browse the repository at this point in the history
- Upgraded 'winapi' dependency to 0.3.9.
- `c_void` is determined by the OS used (on Win it's `winapi::c_types::c_void`,
  on other OS - `std::os::raw::c_void`).
- Removed dependency on 'kernel32', now methods from 'winapi' crate are
  used.
- Resolved some warnings.
- Incremented major crate version to 3.0.0.

Co-authored-by: Michael Spector <spektom@gmail.com>
  • Loading branch information
spektom and Michael Spector authored Jan 18, 2023
1 parent 9da7011 commit 9e91030
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 56 deletions.
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "context"
version = "2.1.0"
version = "3.0.0"
authors = ["Y. T. Chung <zonyitoo@gmail.com>", "Leonard Hecker <leonard@hecker.io>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/zonyitoo/context-rs"
Expand All @@ -25,8 +25,7 @@ exclude = [
libc = "0.2"

[target.'cfg(windows)'.dependencies]
kernel32-sys = "0.2"
winapi = "0.2"
winapi = { version = "0.3", features = ["minwindef", "winnt", "memoryapi", "sysinfoapi"] }

[build-dependencies]
cc = "~1"
Expand Down
8 changes: 5 additions & 3 deletions benches/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ extern crate test;

use test::Bencher;

use context::{Context, Transfer};
use context::stack::FixedSizeStack;
use context::{Context, Transfer};
use std::mem;

#[bench]
Expand All @@ -23,7 +23,7 @@ fn resume_reference_perf(b: &mut Bencher) {
test::black_box(t)
}

let mut t: Transfer = unsafe { mem::uninitialized() };
let mut t: Transfer = unsafe { mem::MaybeUninit::uninit().assume_init() };

b.iter(|| unsafe {
t = yielder(mem::transmute_copy::<_, Transfer>(&t));
Expand Down Expand Up @@ -62,6 +62,8 @@ fn resume_ontop(b: &mut Bencher) {
let mut t = Transfer::new(unsafe { Context::new(&stack, yielder) }, 0);

b.iter(|| unsafe {
t = mem::transmute_copy::<_, Transfer>(&t).context.resume_ontop(0, ontop_function);
t = mem::transmute_copy::<_, Transfer>(&t)
.context
.resume_ontop(0, ontop_function);
});
}
28 changes: 21 additions & 7 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
// copied, modified, or distributed except according to those terms.

use std::fmt;
use std::os::raw::c_void;

use c_void;
use stack::Stack;

// Requires cdecl calling convention on x86, which is the default for "C" blocks.
Expand All @@ -18,7 +18,6 @@ extern "C" {
/// * `sp` - A pointer to the bottom of the stack.
/// * `size` - The size of the stack.
/// * `f` - A function to be invoked on the first call to jump_fcontext(this, _).
#[inline(never)]
fn make_fcontext(sp: *mut c_void, size: usize, f: ContextFn) -> &'static c_void;

/// Yields the execution to another `Context`.
Expand All @@ -27,7 +26,6 @@ extern "C" {
/// * `to` - A pointer to the `Context` with whom we swap execution.
/// * `p` - An arbitrary argument that will be set as the `data` field
/// of the `Transfer` object passed to the other Context.
#[inline(never)]
fn jump_fcontext(to: &'static c_void, p: usize) -> Transfer;

/// Yields the execution to another `Context` and executes a function "ontop" of it's stack.
Expand All @@ -37,7 +35,6 @@ extern "C" {
/// * `p` - An arbitrary argument that will be set as the `data` field
/// of the `Transfer` object passed to the other Context.
/// * `f` - A function to be invoked on `to` before returning.
#[inline(never)]
fn ontop_fcontext(to: &'static c_void, p: usize, f: ResumeOntopFn) -> Transfer;
}

Expand Down Expand Up @@ -152,10 +149,10 @@ impl Transfer {
#[cfg(test)]
mod tests {
use std::mem;
use std::os::raw::c_void;

use stack::ProtectedFixedSizeStack;
use super::*;
use c_void;
use stack::ProtectedFixedSizeStack;

#[test]
fn type_sizes() {
Expand All @@ -168,7 +165,24 @@ mod tests {
fn stack_alignment() {
#[allow(non_camel_case_types)]
#[repr(simd)]
struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
struct u8x16(
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
u8,
);

extern "C" fn context_function(t: Transfer) -> ! {
// If we do not use an array in combination with mem::uninitialized(),
Expand Down
9 changes: 6 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
extern crate libc;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate winapi;

/// Provides the `Context` and `Transfer` types for
Expand All @@ -29,4 +27,9 @@ pub mod stack;

mod sys;

pub use context::{Context, Transfer, ContextFn, ResumeOntopFn};
pub use context::{Context, ContextFn, ResumeOntopFn, Transfer};

#[cfg(not(target_os = "windows"))]
pub use std::os::raw::c_void;
#[cfg(target_os = "windows")]
pub use winapi::ctypes::c_void;
13 changes: 9 additions & 4 deletions src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use std::error::Error;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::io;
use std::ops::Deref;
use std::os::raw::c_void;

use c_void;
use sys;

/// Error type returned by stack allocation methods.
Expand All @@ -27,21 +27,26 @@ impl Display for StackError {
fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
match *self {
StackError::ExceedsMaximumSize(size) => {
write!(fmt, "Requested more than max size of {} bytes for a stack", size)
},
write!(
fmt,
"Requested more than max size of {} bytes for a stack",
size
)
}
StackError::IoError(ref e) => e.fmt(fmt),
}
}
}

impl Error for StackError {
#[allow(deprecated, deprecated_in_future)]
fn description(&self) -> &str {
match *self {
StackError::ExceedsMaximumSize(_) => "exceeds maximum stack size",
StackError::IoError(ref e) => e.description(),
}
}
fn cause(&self) -> Option<&Error> {
fn cause(&self) -> Option<&dyn Error> {
match *self {
StackError::ExceedsMaximumSize(_) => None,
StackError::IoError(ref e) => Some(e),
Expand Down
34 changes: 24 additions & 10 deletions src/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@

use std::io;
use std::mem;
use std::os::raw::c_void;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::usize;

use libc;

use c_void;
use stack::Stack;

#[cfg(any(target_os = "openbsd", target_os = "macos", target_os = "ios", target_os = "android"))]
#[cfg(any(
target_os = "openbsd",
target_os = "macos",
target_os = "ios",
target_os = "android"
))]
const MAP_STACK: libc::c_int = 0;

#[cfg(not(any(target_os = "openbsd", target_os = "macos", target_os = "ios", target_os = "android")))]
#[cfg(not(any(
target_os = "openbsd",
target_os = "macos",
target_os = "ios",
target_os = "android"
)))]
const MAP_STACK: libc::c_int = libc::MAP_STACK;

pub unsafe fn allocate_stack(size: usize) -> io::Result<Stack> {
Expand All @@ -31,7 +41,10 @@ pub unsafe fn allocate_stack(size: usize) -> io::Result<Stack> {
if ptr == libc::MAP_FAILED {
Err(io::Error::last_os_error())
} else {
Ok(Stack::new((ptr as usize + size) as *mut c_void, ptr as *mut c_void))
Ok(Stack::new(
(ptr as usize + size) as *mut c_void,
ptr as *mut c_void,
))
}
}

Expand All @@ -58,7 +71,7 @@ pub unsafe fn deallocate_stack(ptr: *mut c_void, size: usize) {
}

pub fn page_size() -> usize {
static PAGE_SIZE: AtomicUsize = ATOMIC_USIZE_INIT;
static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);

let mut ret = PAGE_SIZE.load(Ordering::Relaxed);

Expand All @@ -80,7 +93,7 @@ pub fn min_stack_size() -> usize {
}

pub fn max_stack_size() -> usize {
static PAGE_SIZE: AtomicUsize = ATOMIC_USIZE_INIT;
static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);

let mut ret = PAGE_SIZE.load(Ordering::Relaxed);

Expand All @@ -89,13 +102,14 @@ pub fn max_stack_size() -> usize {
let limitret;

unsafe {
limit = mem::uninitialized();
limit = mem::MaybeUninit::uninit().assume_init();
limitret = libc::getrlimit(libc::RLIMIT_STACK, &mut limit);
}

if limitret == 0 {
ret = if limit.rlim_max == libc::RLIM_INFINITY ||
limit.rlim_max > (usize::MAX as libc::rlim_t) {
ret = if limit.rlim_max == libc::RLIM_INFINITY
|| limit.rlim_max > (usize::MAX as libc::rlim_t)
{
usize::MAX
} else {
limit.rlim_max as usize
Expand Down
55 changes: 29 additions & 26 deletions src/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,49 @@

use std::io;
use std::mem;
use std::os::raw::c_void;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::usize;

use kernel32;
use winapi;

use c_void;
use stack::Stack;

extern "system" {
// TODO: kernel32-sys has currently (0.2.1) a bug where lpflOldProtect
// is declared as a DWORD, but should be PDWORD instead.
pub fn VirtualProtect(lpAddress: winapi::LPVOID,
dwSize: winapi::SIZE_T,
flNewProtect: winapi::DWORD,
lpflOldProtect: winapi::PDWORD)
-> winapi::BOOL;
}

pub unsafe fn allocate_stack(size: usize) -> io::Result<Stack> {
const NULL: winapi::LPVOID = 0 as winapi::LPVOID;
const PROT: winapi::DWORD = winapi::PAGE_READWRITE;
const TYPE: winapi::DWORD = winapi::MEM_COMMIT | winapi::MEM_RESERVE;

let ptr = kernel32::VirtualAlloc(NULL, size as winapi::SIZE_T, TYPE, PROT);
const NULL: winapi::shared::minwindef::LPVOID = 0 as winapi::shared::minwindef::LPVOID;
const PROT: winapi::shared::minwindef::DWORD = winapi::um::winnt::PAGE_READWRITE;
const TYPE: winapi::shared::minwindef::DWORD =
winapi::um::winnt::MEM_COMMIT | winapi::um::winnt::MEM_RESERVE;

let ptr = winapi::um::memoryapi::VirtualAlloc(
NULL,
size as winapi::shared::basetsd::SIZE_T,
TYPE,
PROT,
);

if ptr == NULL {
Err(io::Error::last_os_error())
} else {
Ok(Stack::new((ptr as usize + size) as *mut c_void, ptr as *mut c_void))
Ok(Stack::new(
(ptr as usize + size) as *mut c_void,
ptr as *mut c_void,
))
}
}

pub unsafe fn protect_stack(stack: &Stack) -> io::Result<Stack> {
const TYPE: winapi::DWORD = winapi::PAGE_READWRITE | winapi::PAGE_GUARD;
const TYPE: winapi::shared::minwindef::DWORD =
winapi::um::winnt::PAGE_READWRITE | winapi::um::winnt::PAGE_GUARD;

let page_size = page_size();
let mut old_prot: winapi::DWORD = 0;
let mut old_prot: winapi::shared::minwindef::DWORD = 0;

debug_assert!(stack.len() % page_size == 0 && stack.len() != 0);

let ret = {
let page_size = page_size as winapi::SIZE_T;
VirtualProtect(stack.bottom(), page_size, TYPE, &mut old_prot)
let page_size = page_size as winapi::shared::basetsd::SIZE_T;
winapi::um::memoryapi::VirtualProtect(stack.bottom(), page_size, TYPE, &mut old_prot)
};

if ret == 0 {
Expand All @@ -62,18 +61,22 @@ pub unsafe fn protect_stack(stack: &Stack) -> io::Result<Stack> {
}

pub unsafe fn deallocate_stack(ptr: *mut c_void, _: usize) {
kernel32::VirtualFree(ptr as winapi::LPVOID, 0, winapi::MEM_RELEASE);
winapi::um::memoryapi::VirtualFree(
ptr as winapi::shared::minwindef::LPVOID,
0,
winapi::um::winnt::MEM_RELEASE,
);
}

pub fn page_size() -> usize {
static PAGE_SIZE: AtomicUsize = ATOMIC_USIZE_INIT;
static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);

let mut ret = PAGE_SIZE.load(Ordering::Relaxed);

if ret == 0 {
ret = unsafe {
let mut info = mem::zeroed();
kernel32::GetSystemInfo(&mut info);
winapi::um::sysinfoapi::GetSystemInfo(&mut info);
info.dwPageSize as usize
};

Expand Down

0 comments on commit 9e91030

Please sign in to comment.