Skip to content

Commit

Permalink
Auto merge of #3239 - beepster4096:windows_sys_tests, r=RalfJung
Browse files Browse the repository at this point in the history
Use `windows-sys` in windows tests

This PR adds `windows-sys` to `test_dependencies` so that we don't have to write out windows api bindings for each test.
  • Loading branch information
bors committed Dec 30, 2023
2 parents ef61546 + e5db7ca commit 667e5a4
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 80 deletions.
1 change: 1 addition & 0 deletions test_dependencies/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test_dependencies/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ rand = { version = "0.8", features = ["small_rng"] }
page_size = "0.6"
tokio = { version = "1.24", features = ["full"] }

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.52", features = [ "Win32_Foundation", "Win32_System_Threading" ] }

[workspace]
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@

// Joining a detached thread is undefined behavior.

use std::os::windows::io::{AsRawHandle, RawHandle};
use std::os::windows::io::AsRawHandle;
use std::thread;

extern "system" {
fn CloseHandle(handle: RawHandle) -> u32;
}
use windows_sys::Win32::Foundation::{CloseHandle, HANDLE};

fn main() {
let thread = thread::spawn(|| ());

unsafe {
assert_ne!(CloseHandle(thread.as_raw_handle()), 0);
assert_ne!(CloseHandle(thread.as_raw_handle() as HANDLE), 0);
}

thread.join().unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,18 @@

use std::thread;

extern "system" {
fn WaitForSingleObject(handle: isize, timeout: u32) -> u32;
}

const INFINITE: u32 = u32::MAX;
use windows_sys::Win32::Foundation::{HANDLE, WAIT_OBJECT_0};
use windows_sys::Win32::System::Threading::{WaitForSingleObject, INFINITE};

// XXX HACK: This is how miri represents the handle for thread 0.
// This value can be "legitimately" obtained by using `GetCurrentThread` with `DuplicateHandle`
// but miri does not implement `DuplicateHandle` yet.
const MAIN_THREAD: isize = (2i32 << 30) as isize;
const MAIN_THREAD: HANDLE = (2i32 << 30) as HANDLE;

fn main() {
thread::spawn(|| {
unsafe {
assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), 0); //~ ERROR: deadlock: the evaluated program deadlocked
assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); //~ ERROR: deadlock: the evaluated program deadlocked
}
})
.join()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: deadlock: the evaluated program deadlocked
--> $DIR/windows_join_main.rs:LL:CC
|
LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked
LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked
|
= note: inside closure at RUSTLIB/core/src/macros/mod.rs:LL:CC
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@

use std::thread;

extern "system" {
fn GetCurrentThread() -> usize;
fn WaitForSingleObject(handle: usize, timeout: u32) -> u32;
}

const INFINITE: u32 = u32::MAX;
use windows_sys::Win32::Foundation::WAIT_OBJECT_0;
use windows_sys::Win32::System::Threading::{GetCurrentThread, WaitForSingleObject, INFINITE};

fn main() {
thread::spawn(|| {
unsafe {
let native = GetCurrentThread();
assert_eq!(WaitForSingleObject(native, INFINITE), 0); //~ ERROR: deadlock: the evaluated program deadlocked
assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); //~ ERROR: deadlock: the evaluated program deadlocked
}
})
.join()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
error: deadlock: the evaluated program deadlocked
--> $DIR/windows_join_self.rs:LL:CC
|
LL | assert_eq!(WaitForSingleObject(native, INFINITE), 0);
LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0);
| ^ the evaluated program deadlocked
|
= note: inside closure at $DIR/windows_join_self.rs:LL:CC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,30 @@
// We are making scheduler assumptions here.
//@compile-flags: -Zmiri-preemption-rate=0

use std::ffi::c_void;
use std::ptr::null_mut;
use std::thread;

use windows_sys::Win32::System::Threading::{
AcquireSRWLockExclusive, AcquireSRWLockShared, ReleaseSRWLockExclusive, ReleaseSRWLockShared,
SleepConditionVariableSRW, WakeAllConditionVariable, CONDITION_VARIABLE,
CONDITION_VARIABLE_LOCKMODE_SHARED, INFINITE, SRWLOCK,
};

// not in windows-sys
const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: null_mut() };
const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: null_mut() };

#[derive(Copy, Clone)]
struct SendPtr<T>(*mut T);

unsafe impl<T> Send for SendPtr<T> {}

extern "system" {
fn SleepConditionVariableSRW(
condvar: *mut *mut c_void,
lock: *mut *mut c_void,
timeout: u32,
flags: u32,
) -> i32;
fn WakeAllConditionVariable(condvar: *mut *mut c_void);

fn AcquireSRWLockExclusive(lock: *mut *mut c_void);
fn AcquireSRWLockShared(lock: *mut *mut c_void);
fn ReleaseSRWLockExclusive(lock: *mut *mut c_void);
fn ReleaseSRWLockShared(lock: *mut *mut c_void);
}

const CONDITION_VARIABLE_LOCKMODE_SHARED: u32 = 1;
const INFINITE: u32 = u32::MAX;

/// threads should be able to reacquire the lock while it is locked by multiple other threads in shared mode
fn all_shared() {
println!("all_shared");

let mut lock = null_mut();
let mut condvar = null_mut();
let mut lock = SRWLOCK_INIT;
let mut condvar = CONDITION_VARIABLE_INIT;

let lock_ptr = SendPtr(&mut lock);
let condvar_ptr = SendPtr(&mut condvar);
Expand Down Expand Up @@ -105,8 +96,8 @@ fn all_shared() {
fn shared_sleep_and_exclusive_lock() {
println!("shared_sleep_and_exclusive_lock");

let mut lock = null_mut();
let mut condvar = null_mut();
let mut lock = SRWLOCK_INIT;
let mut condvar = CONDITION_VARIABLE_INIT;

let lock_ptr = SendPtr(&mut lock);
let condvar_ptr = SendPtr(&mut condvar);
Expand Down Expand Up @@ -166,8 +157,8 @@ fn shared_sleep_and_exclusive_lock() {
fn exclusive_sleep_and_shared_lock() {
println!("exclusive_sleep_and_shared_lock");

let mut lock = null_mut();
let mut condvar = null_mut();
let mut lock = SRWLOCK_INIT;
let mut condvar = CONDITION_VARIABLE_INIT;

let lock_ptr = SendPtr(&mut lock);
let condvar_ptr = SendPtr(&mut condvar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
use std::os::windows::io::IntoRawHandle;
use std::thread;

extern "system" {
fn CloseHandle(handle: usize) -> i32;
}
use windows_sys::Win32::Foundation::{CloseHandle, HANDLE};

fn main() {
let thread = thread::spawn(|| {}).into_raw_handle() as usize;
let thread = thread::spawn(|| {}).into_raw_handle() as HANDLE;

// this yield ensures that `thread` is terminated by this point
thread::yield_now();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,24 @@
// We are making scheduler assumptions here.
//@compile-flags: -Zmiri-preemption-rate=0

use std::ffi::c_void;
use std::ptr::null_mut;
use std::thread;

use windows_sys::Win32::Foundation::{FALSE, TRUE};
use windows_sys::Win32::System::Threading::{
InitOnceBeginInitialize, InitOnceComplete, INIT_ONCE, INIT_ONCE_INIT_FAILED,
};

// not in windows-sys
const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: null_mut() };

#[derive(Copy, Clone)]
struct SendPtr<T>(*mut T);

unsafe impl<T> Send for SendPtr<T> {}

extern "system" {
fn InitOnceBeginInitialize(
init: *mut *mut c_void,
flags: u32,
pending: *mut i32,
context: *mut c_void,
) -> i32;

fn InitOnceComplete(init: *mut *mut c_void, flags: u32, context: *mut c_void) -> i32;
}

const TRUE: i32 = 1;
const FALSE: i32 = 0;

const INIT_ONCE_INIT_FAILED: u32 = 4;

fn single_thread() {
let mut init_once = null_mut();
let mut init_once = INIT_ONCE_STATIC_INIT;
let mut pending = 0;

unsafe {
Expand All @@ -41,7 +32,7 @@ fn single_thread() {
assert_eq!(pending, FALSE);
}

let mut init_once = null_mut();
let mut init_once = INIT_ONCE_STATIC_INIT;

unsafe {
assert_eq!(InitOnceBeginInitialize(&mut init_once, 0, &mut pending, null_mut()), TRUE);
Expand All @@ -55,7 +46,7 @@ fn single_thread() {
}

fn block_until_complete() {
let mut init_once = null_mut();
let mut init_once = INIT_ONCE_STATIC_INIT;
let mut pending = 0;

unsafe {
Expand Down Expand Up @@ -92,7 +83,7 @@ fn block_until_complete() {
}

fn retry_on_fail() {
let mut init_once = null_mut();
let mut init_once = INIT_ONCE_STATIC_INIT;
let mut pending = 0;

unsafe {
Expand Down Expand Up @@ -134,7 +125,7 @@ fn retry_on_fail() {
}

fn no_data_race_after_complete() {
let mut init_once = null_mut();
let mut init_once = INIT_ONCE_STATIC_INIT;
let mut pending = 0;

unsafe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ use std::os::windows::io::IntoRawHandle;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;

extern "system" {
fn WaitForSingleObject(handle: usize, timeout: u32) -> u32;
}

const INFINITE: u32 = u32::MAX;
use windows_sys::Win32::Foundation::{HANDLE, WAIT_OBJECT_0};
use windows_sys::Win32::System::Threading::{WaitForSingleObject, INFINITE};

fn main() {
static FLAG: AtomicBool = AtomicBool::new(false);
Expand All @@ -20,10 +17,10 @@ fn main() {
thread::yield_now();
}
})
.into_raw_handle() as usize;
.into_raw_handle() as HANDLE;

let waiter = move || unsafe {
assert_eq!(WaitForSingleObject(blocker, INFINITE), 0);
assert_eq!(WaitForSingleObject(blocker, INFINITE), WAIT_OBJECT_0);
};

let waiter1 = thread::spawn(waiter);
Expand Down

0 comments on commit 667e5a4

Please sign in to comment.