@@ -89,18 +89,18 @@ extern "system" {
89
89
static HEAP : AtomicPtr < c_void > = AtomicPtr :: new ( ptr:: null_mut ( ) ) ;
90
90
91
91
// Get a handle to the default heap of the current process, or null if the operation fails.
92
- // SAFETY: If this operation is successful, `HEAP` will be successfully initialized and contain
92
+ // If this operation is successful, `HEAP` will be successfully initialized and contain
93
93
// a non-null handle returned by `GetProcessHeap`.
94
94
#[ inline]
95
- unsafe fn init_or_get_process_heap ( ) -> c:: HANDLE {
95
+ fn init_or_get_process_heap ( ) -> c:: HANDLE {
96
96
let heap = HEAP . load ( Ordering :: Relaxed ) ;
97
97
if heap. is_null ( ) {
98
98
// `HEAP` has not yet been successfully initialized
99
99
let heap = unsafe { GetProcessHeap ( ) } ;
100
100
if !heap. is_null ( ) {
101
101
// SAFETY: No locking is needed because within the same process,
102
102
// successful calls to `GetProcessHeap` will always return the same value, even on different threads.
103
- HEAP . store ( heap, Ordering :: Relaxed ) ;
103
+ HEAP . store ( heap, Ordering :: Release ) ;
104
104
105
105
// SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
106
106
heap
@@ -114,16 +114,25 @@ unsafe fn init_or_get_process_heap() -> c::HANDLE {
114
114
}
115
115
}
116
116
117
+ // Get a non-null handle to the default heap of the current process.
118
+ // SAFETY: `HEAP` must have been successfully initialized.
119
+ #[ inline]
120
+ unsafe fn get_process_heap ( ) -> c:: HANDLE {
121
+ HEAP . load ( Ordering :: Acquire )
122
+ }
123
+
117
124
// Header containing a pointer to the start of an allocated block.
118
125
// SAFETY: Size and alignment must be <= `MIN_ALIGN`.
119
126
#[ repr( C ) ]
120
127
struct Header ( * mut u8 ) ;
121
128
122
129
// Allocate a block of optionally zeroed memory for a given `layout`.
123
- // SAFETY: Returns a pointer satisfying the guarantees of `System` about allocated pointers.
130
+ // SAFETY: Returns a pointer satisfying the guarantees of `System` about allocated pointers,
131
+ // or null if the operation fails. If this returns non-null `HEAP` will have been successfully
132
+ // initialized.
124
133
#[ inline]
125
134
unsafe fn allocate ( layout : Layout , zeroed : bool ) -> * mut u8 {
126
- let heap = unsafe { init_or_get_process_heap ( ) } ;
135
+ let heap = init_or_get_process_heap ( ) ;
127
136
if heap. is_null ( ) {
128
137
// Allocation has failed, could not get the current process heap.
129
138
return ptr:: null_mut ( ) ;
@@ -209,11 +218,11 @@ unsafe impl GlobalAlloc for System {
209
218
} ;
210
219
211
220
// SAFETY: because `ptr` has been successfully allocated with this allocator,
212
- // `HEAP` must have been successfully initialized and contain a non-null handle
213
- // returned by `GetProcessHeap`.
214
- let heap = HEAP . load ( Ordering :: Relaxed ) ;
221
+ // `HEAP` must have been successfully initialized.
222
+ let heap = unsafe { get_process_heap ( ) } ;
215
223
216
- // SAFETY: `block` is a pointer to the start of an allocated block.
224
+ // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`,
225
+ // `block` is a pointer to the start of an allocated block.
217
226
unsafe {
218
227
let err = HeapFree ( heap, 0 , block as c:: LPVOID ) ;
219
228
debug_assert ! ( err != 0 , "Failed to free heap memory: {}" , c:: GetLastError ( ) ) ;
@@ -224,11 +233,11 @@ unsafe impl GlobalAlloc for System {
224
233
unsafe fn realloc ( & self , ptr : * mut u8 , layout : Layout , new_size : usize ) -> * mut u8 {
225
234
if layout. align ( ) <= MIN_ALIGN {
226
235
// SAFETY: because `ptr` has been successfully allocated with this allocator,
227
- // `HEAP` must have been successfully initialized and contain a non-null handle
228
- // returned by `GetProcessHeap`.
229
- let heap = HEAP . load ( Ordering :: Relaxed ) ;
236
+ // `HEAP` must have been successfully initialized.
237
+ let heap = unsafe { get_process_heap ( ) } ;
230
238
231
- // SAFETY: `ptr` is a pointer to the start of an allocated block.
239
+ // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`,
240
+ // `ptr` is a pointer to the start of an allocated block.
232
241
// The returned pointer points to the start of an allocated block.
233
242
unsafe { HeapReAlloc ( heap, 0 , ptr as c:: LPVOID , new_size) as * mut u8 }
234
243
} else {
0 commit comments