Skip to content

Commit 697f800

Browse files
seritoolsmbilker
authored andcommitted
Add fallback implementations for Mutex, CondVar and RwLock
- Add fallback implementations for `MovableMutex` `MovableMutex`es have two fallback implementations: - Critical sections (NT4+ because of try_lock/`TryEnterCriticalSection`) - CreateMutex handles-based mutex (all Win32) - Add `MovableRWLock` fallback implementation, falling back to a `MovableMutex` if `SRWLock`s are not available - Add `StaticRWLock`/`StaticMutex` shared fallback implementation. These only need the critical section fallback implementation since static mutexes don't need/expose `try_lock`. They do, however, need to be initialized, so the implementation is based on the old XP-compatible `Mutex` impl from before it was removed. Old impl seen here: https://github.com/rust-lang/rust/blob/c35007dbbe4846c641b5edad9fddf3f72a5a035a/library/std/src/sys/windows/mutex.rs Since the impls for MovableMutex and StaticMutex are now different, the `sys_common/mutex.rs` definition of `StaticMutex` and `StaticMutexGuard` had to be changed. (Same for `MovableRWLock` and `StaticRWLock`) - Add fallback implementation for `ReentrantMutex` based on `CreateMutex` mutexes, as those are reentrant as well. - Implement `CondVar` fallback based on `CreateEventA`/`PulseEvent`. This should be used with extreme caution as it may cause deadlocks. See which may cause deadlocks. See [Old New Thing](https://devblogs.microsoft.com/oldnewthing/20050105-00/?p=36803) and the [MSDN docs](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-pulseevent) for more information.
1 parent 634cc43 commit 697f800

File tree

10 files changed

+694
-90
lines changed

10 files changed

+694
-90
lines changed

library/std/src/sys/windows/c.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,56 @@ compat_fn_with_fallback! {
351351
pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
352352
GetTempPathW(bufferlength, buffer)
353353
}
354+
355+
// >= NT 4
356+
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-tryentercriticalsection
357+
pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOL {
358+
rtabort!("unavailable")
359+
}
360+
361+
// >= Vista / Server 2008
362+
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-acquiresrwlockexclusive
363+
pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
364+
rtabort!("unavailable")
365+
}
366+
pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK) -> () {
367+
rtabort!("unavailable")
368+
}
369+
pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
370+
rtabort!("unavailable")
371+
}
372+
pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK) -> () {
373+
rtabort!("unavailable")
374+
}
375+
376+
// >= Win7 / Server 2008 R2
377+
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-tryacquiresrwlockexclusive
378+
pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN {
379+
rtabort!("unavailable")
380+
}
381+
pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN {
382+
rtabort!("unavailable")
383+
}
384+
385+
// >= Vista / Server 2008
386+
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepconditionvariablesrw
387+
pub fn SleepConditionVariableSRW(
388+
ConditionVariable: PCONDITION_VARIABLE,
389+
SRWLock: PSRWLOCK,
390+
dwMilliseconds: DWORD,
391+
Flags: ULONG
392+
) -> BOOL {
393+
rtabort!("unavailable")
394+
}
395+
396+
// >= Vista / Server 2008
397+
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakeconditionvariable
398+
pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE) -> () {
399+
rtabort!("unavailable")
400+
}
401+
pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE) -> () {
402+
rtabort!("unavailable")
403+
}
354404
}
355405

356406
compat_fn_optional! {
@@ -396,4 +446,21 @@ compat_fn_with_fallback! {
396446
#[link(name = "kernel32")]
397447
extern "system" {
398448
pub fn LoadLibraryA(lpFileName: LPCSTR) -> HMODULE;
449+
450+
pub fn CreateMutexA(
451+
lpMutexAttributes: LPSECURITY_ATTRIBUTES,
452+
bInitialOwner: BOOL,
453+
lpName: LPCSTR,
454+
) -> HANDLE;
455+
456+
pub fn ReleaseMutex(hMutex: HANDLE) -> BOOL;
457+
458+
pub fn CreateEventA(
459+
lpEventAttributes: LPSECURITY_ATTRIBUTES,
460+
bManualReset: BOOL,
461+
bInitialState: BOOL,
462+
lpName: LPCSTR,
463+
) -> HANDLE;
464+
465+
pub fn PulseEvent(hEvent: HANDLE) -> BOOL;
399466
}

library/std/src/sys/windows/c/windows_sys.lst

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,8 +2490,6 @@ Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS
24902490
Windows.Win32.System.SystemServices.IO_REPARSE_TAG_MOUNT_POINT
24912491
Windows.Win32.System.SystemServices.IO_REPARSE_TAG_SYMLINK
24922492
Windows.Win32.System.Threading.ABOVE_NORMAL_PRIORITY_CLASS
2493-
Windows.Win32.System.Threading.AcquireSRWLockExclusive
2494-
Windows.Win32.System.Threading.AcquireSRWLockShared
24952493
Windows.Win32.System.Threading.BELOW_NORMAL_PRIORITY_CLASS
24962494
Windows.Win32.System.Threading.CREATE_BREAKAWAY_FROM_JOB
24972495
Windows.Win32.System.Threading.CREATE_DEFAULT_ERROR_MODE
@@ -2531,21 +2529,20 @@ Windows.Win32.System.Threading.InitOnceComplete
25312529
Windows.Win32.System.Threading.LPTHREAD_START_ROUTINE
25322530
Windows.Win32.System.Threading.NORMAL_PRIORITY_CLASS
25332531
Windows.Win32.System.Threading.OpenProcessToken
2532+
Windows.Win32.System.Threading.PCONDITION_VARIABLE
25342533
Windows.Win32.System.Threading.PROCESS_CREATION_FLAGS
25352534
Windows.Win32.System.Threading.PROCESS_INFORMATION
25362535
Windows.Win32.System.Threading.PROCESS_MODE_BACKGROUND_BEGIN
25372536
Windows.Win32.System.Threading.PROCESS_MODE_BACKGROUND_END
25382537
Windows.Win32.System.Threading.PROFILE_KERNEL
25392538
Windows.Win32.System.Threading.PROFILE_SERVER
25402539
Windows.Win32.System.Threading.PROFILE_USER
2540+
Windows.Win32.System.Threading.PSRWLOCK
25412541
Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS
2542-
Windows.Win32.System.Threading.ReleaseSRWLockExclusive
2543-
Windows.Win32.System.Threading.ReleaseSRWLockShared
25442542
Windows.Win32.System.Threading.RTL_CONDITION_VARIABLE
25452543
Windows.Win32.System.Threading.RTL_RUN_ONCE
25462544
Windows.Win32.System.Threading.RTL_SRWLOCK
25472545
Windows.Win32.System.Threading.Sleep
2548-
Windows.Win32.System.Threading.SleepConditionVariableSRW
25492546
Windows.Win32.System.Threading.SleepEx
25502547
Windows.Win32.System.Threading.STACK_SIZE_PARAM_IS_A_RESERVATION
25512548
Windows.Win32.System.Threading.STARTF_FORCEOFFFEEDBACK
@@ -2574,12 +2571,8 @@ Windows.Win32.System.Threading.TlsAlloc
25742571
Windows.Win32.System.Threading.TlsFree
25752572
Windows.Win32.System.Threading.TlsGetValue
25762573
Windows.Win32.System.Threading.TlsSetValue
2577-
Windows.Win32.System.Threading.TryAcquireSRWLockExclusive
2578-
Windows.Win32.System.Threading.TryAcquireSRWLockShared
25792574
Windows.Win32.System.Threading.WaitForMultipleObjects
25802575
Windows.Win32.System.Threading.WaitForSingleObject
2581-
Windows.Win32.System.Threading.WakeAllConditionVariable
2582-
Windows.Win32.System.Threading.WakeConditionVariable
25832576
Windows.Win32.System.WindowsProgramming.IO_STATUS_BLOCK
25842577
Windows.Win32.System.WindowsProgramming.OBJECT_ATTRIBUTES
25852578
Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE

library/std/src/sys/windows/c/windows_sys.rs

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@ extern "system" {
3131
) -> NTSTATUS;
3232
}
3333
#[link(name = "kernel32")]
34-
extern "system" {
35-
pub fn AcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
36-
}
37-
#[link(name = "kernel32")]
38-
extern "system" {
39-
pub fn AcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
40-
}
41-
#[link(name = "kernel32")]
4234
extern "system" {
4335
pub fn CancelIo(hfile: HANDLE) -> BOOL;
4436
}
@@ -428,14 +420,6 @@ extern "system" {
428420
) -> BOOL;
429421
}
430422
#[link(name = "kernel32")]
431-
extern "system" {
432-
pub fn ReleaseSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
433-
}
434-
#[link(name = "kernel32")]
435-
extern "system" {
436-
pub fn ReleaseSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
437-
}
438-
#[link(name = "kernel32")]
439423
extern "system" {
440424
pub fn RemoveDirectoryW(lppathname: PCWSTR) -> BOOL;
441425
}
@@ -494,15 +478,6 @@ extern "system" {
494478
pub fn Sleep(dwmilliseconds: u32) -> ();
495479
}
496480
#[link(name = "kernel32")]
497-
extern "system" {
498-
pub fn SleepConditionVariableSRW(
499-
conditionvariable: *mut RTL_CONDITION_VARIABLE,
500-
srwlock: *mut RTL_SRWLOCK,
501-
dwmilliseconds: u32,
502-
flags: u32,
503-
) -> BOOL;
504-
}
505-
#[link(name = "kernel32")]
506481
extern "system" {
507482
pub fn SleepEx(dwmilliseconds: u32, balertable: BOOL) -> u32;
508483
}
@@ -531,14 +506,6 @@ extern "system" {
531506
pub fn TlsSetValue(dwtlsindex: u32, lptlsvalue: *const ::core::ffi::c_void) -> BOOL;
532507
}
533508
#[link(name = "kernel32")]
534-
extern "system" {
535-
pub fn TryAcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
536-
}
537-
#[link(name = "kernel32")]
538-
extern "system" {
539-
pub fn TryAcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
540-
}
541-
#[link(name = "kernel32")]
542509
extern "system" {
543510
pub fn WaitForMultipleObjects(
544511
ncount: u32,
@@ -552,14 +519,6 @@ extern "system" {
552519
pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR;
553520
}
554521
#[link(name = "kernel32")]
555-
extern "system" {
556-
pub fn WakeAllConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
557-
}
558-
#[link(name = "kernel32")]
559-
extern "system" {
560-
pub fn WakeConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
561-
}
562-
#[link(name = "kernel32")]
563522
extern "system" {
564523
pub fn WideCharToMultiByte(
565524
codepage: u32,
@@ -3736,6 +3695,7 @@ pub const PROFILE_KERNEL: PROCESS_CREATION_FLAGS = 536870912u32;
37363695
pub const PROFILE_SERVER: PROCESS_CREATION_FLAGS = 1073741824u32;
37373696
pub const PROFILE_USER: PROCESS_CREATION_FLAGS = 268435456u32;
37383697
pub const PROGRESS_CONTINUE: u32 = 0u32;
3698+
pub type PSRWLOCK = *mut RTL_SRWLOCK;
37393699
pub type PSTR = *mut u8;
37403700
pub type PVECTORED_EXCEPTION_HANDLER = ::core::option::Option<
37413701
unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32,

0 commit comments

Comments
 (0)