Skip to content

Commit 4cee186

Browse files
committed
fixup! Optimize compat_fn!, add compat_fn_lazy!, add unicows support
1 parent 4f6764a commit 4cee186

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ macro_rules! compat_fn_with_fallback {
147147
use super::*;
148148
use crate::mem;
149149
use crate::ffi::CStr;
150-
use crate::sync::atomic::{AtomicPtr, Ordering};
150+
use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
151151
use crate::sys::compat::Module;
152152

153153
type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
@@ -158,6 +158,7 @@ macro_rules! compat_fn_with_fallback {
158158
/// If it succeeds, `PTR` is set to the address of that symbol.
159159
/// If it fails, then `PTR` is set to `fallback`.
160160
static PTR: AtomicPtr<c_void> = AtomicPtr::new(load as *mut _);
161+
static AVAILABLE: AtomicBool = AtomicBool::new(false);
161162

162163
unsafe extern "system" fn load($($argname: $argtype),*) -> $rettype {
163164
let func = load_from_module(Module::new($module));
@@ -172,9 +173,11 @@ macro_rules! compat_fn_with_fallback {
172173
.or_else(|| module.and_then(|m| m.proc_address(SYMBOL_NAME)))
173174
{
174175
PTR.store(f.as_ptr(), Ordering::Relaxed);
176+
AVAILABLE.store(true, Ordering::Relaxed);
175177
mem::transmute(f)
176178
} else {
177179
PTR.store(fallback as *mut _, Ordering::Relaxed);
180+
AVAILABLE.store(false, Ordering::Relaxed);
178181
fallback
179182
}
180183
}
@@ -185,6 +188,20 @@ macro_rules! compat_fn_with_fallback {
185188
$fallback_body
186189
}
187190

191+
pub unsafe fn available() -> bool {
192+
// Quickly return if already available
193+
if AVAILABLE.load(Ordering::Relaxed) {
194+
return true;
195+
}
196+
197+
// Try to avoid fetching the load status every time
198+
if PTR.load(Ordering::Relaxed) == load as *mut _ {
199+
let _ = load_from_module(Module::new($module));
200+
}
201+
202+
AVAILABLE.load(Ordering::Relaxed)
203+
}
204+
188205
#[inline(always)]
189206
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
190207
let func: F = mem::transmute(PTR.load(Ordering::Relaxed));

0 commit comments

Comments
 (0)