@@ -36,7 +36,8 @@ extern crate uefi;
36
36
37
37
use core:: ffi:: c_void;
38
38
use core:: fmt:: Write ;
39
- use core:: ptr:: NonNull ;
39
+ use core:: ptr:: { self , NonNull } ;
40
+ use core:: sync:: atomic:: { AtomicPtr , Ordering } ;
40
41
41
42
use cfg_if:: cfg_if;
42
43
@@ -50,15 +51,22 @@ use uefi::{Event, Result};
50
51
/// This table is only fully safe to use until UEFI boot services have been exited.
51
52
/// After that, some fields and methods are unsafe to use, see the documentation of
52
53
/// UEFI's ExitBootServices entry point for more details.
53
- static mut SYSTEM_TABLE : Option < SystemTable < Boot > > = None ;
54
+ static SYSTEM_TABLE : AtomicPtr < c_void > = AtomicPtr :: new ( ptr :: null_mut ( ) ) ;
54
55
55
56
/// Global logger object
56
57
#[ cfg( feature = "logger" ) ]
57
58
static mut LOGGER : Option < uefi:: logger:: Logger > = None ;
58
59
59
60
#[ must_use]
60
61
fn system_table_opt ( ) -> Option < SystemTable < Boot > > {
61
- unsafe { SYSTEM_TABLE . as_ref ( ) . map ( |table| table. unsafe_clone ( ) ) }
62
+ let ptr = SYSTEM_TABLE . load ( Ordering :: Acquire ) ;
63
+ // Safety: the `SYSTEM_TABLE` pointer either be null or a valid system
64
+ // table.
65
+ //
66
+ // Null is the initial value, as well as the value set when exiting boot
67
+ // services. Otherwise, the value is set by the call to `init`, which
68
+ // requires a valid system table reference as input.
69
+ unsafe { SystemTable :: from_ptr ( ptr) }
62
70
}
63
71
64
72
/// Obtains a pointer to the system table.
@@ -84,10 +92,10 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result<Option<Event>> {
84
92
return Status :: SUCCESS . to_result_with_val ( || None ) ;
85
93
}
86
94
87
- unsafe {
88
- // Setup the system table singleton
89
- SYSTEM_TABLE = Some ( st. unsafe_clone ( ) ) ;
95
+ // Setup the system table singleton
96
+ SYSTEM_TABLE . store ( st. as_ptr ( ) . cast_mut ( ) , Ordering :: Release ) ;
90
97
98
+ unsafe {
91
99
// Setup logging and memory allocation
92
100
93
101
#[ cfg( feature = "logger" ) ]
@@ -180,7 +188,7 @@ unsafe extern "efiapi" fn exit_boot_services(_e: Event, _ctx: Option<NonNull<c_v
180
188
// check that the callback does get called.
181
189
//
182
190
// info!("Shutting down the UEFI utility library");
183
- SYSTEM_TABLE = None ;
191
+ SYSTEM_TABLE . store ( ptr :: null_mut ( ) , Ordering :: Release ) ;
184
192
185
193
#[ cfg( feature = "logger" ) ]
186
194
if let Some ( ref mut logger) = LOGGER {
0 commit comments