Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate from winapi to windows_sys #76

Merged
merged 2 commits into from
Oct 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ cfg-if = "1.0.0"
libc = "0.2.45"
psm = { path = "psm", version = "0.1.7" }

[target.'cfg(windows)'.dependencies.winapi]
version = "0.3.6"
[target.'cfg(windows)'.dependencies.windows-sys]
version = ">=0.34.0, <0.42.0"
features = [
'memoryapi',
'winbase',
'fibersapi',
'processthreadsapi',
'minwindef',
"Win32_System_Memory",
"Win32_System_Threading",
"Win32_Foundation",
]


[build-dependencies]
cc = "1.0.2"
38 changes: 17 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
extern crate cfg_if;
extern crate libc;
#[cfg(windows)]
extern crate winapi;
extern crate windows_sys;
#[macro_use]
extern crate psm;

Expand Down Expand Up @@ -92,7 +92,7 @@ pub fn remaining_stack() -> Option<usize> {
get_stack_limit().map(|limit| current_ptr - limit)
}

psm_stack_information! (
psm_stack_information!(
yes {
fn current_stack_ptr() -> usize {
psm::stack_pointer() as usize
Expand Down Expand Up @@ -278,29 +278,27 @@ cfg_if! {
if #[cfg(windows)] {
use std::ptr;
use std::io;

use winapi::shared::basetsd::*;
use winapi::shared::minwindef::{LPVOID, BOOL};
use winapi::shared::ntdef::*;
use winapi::um::fibersapi::*;
use winapi::um::memoryapi::*;
use winapi::um::processthreadsapi::*;
use winapi::um::winbase::*;
use libc::c_void;
use windows_sys::Win32::System::Threading::{SwitchToFiber, IsThreadAFiber, ConvertThreadToFiber,
CreateFiber, DeleteFiber, ConvertFiberToThread, SetThreadStackGuarantee
};
use windows_sys::Win32::Foundation::BOOL;
use windows_sys::Win32::System::Memory::VirtualQuery;

// Make sure the libstacker.a (implemented in C) is linked.
// See https://github.com/rust-lang/rust/issues/65610
#[link(name="stacker")]
extern {
fn __stacker_get_current_fiber() -> PVOID;
fn __stacker_get_current_fiber() -> *mut c_void;
}

struct FiberInfo<F> {
callback: std::mem::MaybeUninit<F>,
panic: Option<Box<dyn std::any::Any + Send + 'static>>,
parent_fiber: LPVOID,
parent_fiber: *mut c_void,
}

unsafe extern "system" fn fiber_proc<F: FnOnce()>(data: LPVOID) {
unsafe extern "system" fn fiber_proc<F: FnOnce()>(data: *mut c_void) {
// This function is the entry point to our inner fiber, and as argument we get an
// instance of `FiberInfo`. We will set-up the "runtime" for the callback and execute
// it.
Expand All @@ -313,7 +311,6 @@ cfg_if! {
// Restore to the previous Fiber
set_stack_limit(old_stack_limit);
SwitchToFiber(data.parent_fiber);
return;
}

fn _grow(stack_size: usize, callback: &mut dyn FnMut()) {
Expand All @@ -322,7 +319,7 @@ cfg_if! {
// to it so we can use it's stack. After running `callback` within our fiber, we switch
// back to the current stack and destroy the fiber and its associated stack.
unsafe {
let was_fiber = IsThreadAFiber() == TRUE as BOOL;
let was_fiber = IsThreadAFiber() == 1 as BOOL;
let mut data = FiberInfo {
callback: std::mem::MaybeUninit::new(callback),
panic: None,
Expand All @@ -346,7 +343,7 @@ cfg_if! {
}

let fiber = CreateFiber(
stack_size as SIZE_T,
stack_size as usize,
Some(fiber_proc::<&mut dyn FnMut()>),
&mut data as *mut FiberInfo<&mut dyn FnMut()> as *mut _,
);
Expand All @@ -361,12 +358,11 @@ cfg_if! {
DeleteFiber(fiber);

// Clean-up.
if !was_fiber {
if ConvertFiberToThread() == 0 {
if !was_fiber && ConvertFiberToThread() == 0 {
// FIXME: Perhaps should not panic here?
panic!("unable to convert back to thread: {}", io::Error::last_os_error());
}
}

if let Some(p) = data.panic {
std::panic::resume_unwind(p);
}
Expand Down Expand Up @@ -400,12 +396,12 @@ cfg_if! {
// to discover the size of the stack
//
// FIXME: we could read stack base from the TIB, specifically the 3rd element of it.
type QueryT = winapi::um::winnt::MEMORY_BASIC_INFORMATION;
type QueryT = windows_sys::Win32::System::Memory::MEMORY_BASIC_INFORMATION;
let mut mi = std::mem::MaybeUninit::<QueryT>::uninit();
VirtualQuery(
psm::stack_pointer() as *const _,
mi.as_mut_ptr(),
std::mem::size_of::<QueryT>() as SIZE_T,
std::mem::size_of::<QueryT>() as usize,
);
Some(mi.assume_init().AllocationBase as usize + get_thread_stack_guarantee() + 0x1000)
}
Expand Down