@@ -147,7 +147,7 @@ macro_rules! compat_fn_with_fallback {
147
147
use super :: * ;
148
148
use crate :: mem;
149
149
use crate :: ffi:: CStr ;
150
- use crate :: sync:: atomic:: { AtomicPtr , Ordering } ;
150
+ use crate :: sync:: atomic:: { AtomicBool , AtomicPtr , Ordering } ;
151
151
use crate :: sys:: compat:: Module ;
152
152
153
153
type F = unsafe extern "system" fn ( $( $argtype) ,* ) -> $rettype;
@@ -158,6 +158,7 @@ macro_rules! compat_fn_with_fallback {
158
158
/// If it succeeds, `PTR` is set to the address of that symbol.
159
159
/// If it fails, then `PTR` is set to `fallback`.
160
160
static PTR : AtomicPtr <c_void> = AtomicPtr :: new( load as * mut _) ;
161
+ static AVAILABLE : AtomicBool = AtomicBool :: new( false ) ;
161
162
162
163
unsafe extern "system" fn load( $( $argname: $argtype) ,* ) -> $rettype {
163
164
let func = load_from_module( Module :: new( $module) ) ;
@@ -172,9 +173,11 @@ macro_rules! compat_fn_with_fallback {
172
173
. or_else( || module. and_then( |m| m. proc_address( SYMBOL_NAME ) ) )
173
174
{
174
175
PTR . store( f. as_ptr( ) , Ordering :: Relaxed ) ;
176
+ AVAILABLE . store( true , Ordering :: Relaxed ) ;
175
177
mem:: transmute( f)
176
178
} else {
177
179
PTR . store( fallback as * mut _, Ordering :: Relaxed ) ;
180
+ AVAILABLE . store( false , Ordering :: Relaxed ) ;
178
181
fallback
179
182
}
180
183
}
@@ -185,6 +188,20 @@ macro_rules! compat_fn_with_fallback {
185
188
$fallback_body
186
189
}
187
190
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
+
188
205
#[ inline( always) ]
189
206
pub unsafe fn call( $( $argname: $argtype) ,* ) -> $rettype {
190
207
let func: F = mem:: transmute( PTR . load( Ordering :: Relaxed ) ) ;
0 commit comments