Skip to content

Commit c86e098

Browse files
committed
Introduce get_process_heap and fix atomic ordering.
1 parent 4cce9e3 commit c86e098

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

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

+22-13
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,18 @@ extern "system" {
8989
static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
9090

9191
// 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
9393
// a non-null handle returned by `GetProcessHeap`.
9494
#[inline]
95-
unsafe fn init_or_get_process_heap() -> c::HANDLE {
95+
fn init_or_get_process_heap() -> c::HANDLE {
9696
let heap = HEAP.load(Ordering::Relaxed);
9797
if heap.is_null() {
9898
// `HEAP` has not yet been successfully initialized
9999
let heap = unsafe { GetProcessHeap() };
100100
if !heap.is_null() {
101101
// SAFETY: No locking is needed because within the same process,
102102
// 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);
104104

105105
// SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
106106
heap
@@ -114,16 +114,25 @@ unsafe fn init_or_get_process_heap() -> c::HANDLE {
114114
}
115115
}
116116

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+
117124
// Header containing a pointer to the start of an allocated block.
118125
// SAFETY: Size and alignment must be <= `MIN_ALIGN`.
119126
#[repr(C)]
120127
struct Header(*mut u8);
121128

122129
// 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.
124133
#[inline]
125134
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();
127136
if heap.is_null() {
128137
// Allocation has failed, could not get the current process heap.
129138
return ptr::null_mut();
@@ -209,11 +218,11 @@ unsafe impl GlobalAlloc for System {
209218
};
210219

211220
// 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() };
215223

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.
217226
unsafe {
218227
let err = HeapFree(heap, 0, block as c::LPVOID);
219228
debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError());
@@ -224,11 +233,11 @@ unsafe impl GlobalAlloc for System {
224233
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
225234
if layout.align() <= MIN_ALIGN {
226235
// 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() };
230238

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.
232241
// The returned pointer points to the start of an allocated block.
233242
unsafe { HeapReAlloc(heap, 0, ptr as c::LPVOID, new_size) as *mut u8 }
234243
} else {

0 commit comments

Comments
 (0)