summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Hommey <mh@glandium.org>2018-05-16 09:16:37 +0900
committerMike Hommey <mh@glandium.org>2018-05-30 10:57:38 +0900
commita4d899b4a1248f885563e241fa56fe9f69616dc2 (patch)
tree4c7f5275e05d8b11bf386aa060f7dc413a0745c8
parentPass a `Layout` to `oom` (diff)
downloadgrust-a4d899b4a1248f885563e241fa56fe9f69616dc2.tar.gz
grust-a4d899b4a1248f885563e241fa56fe9f69616dc2.tar.bz2
grust-a4d899b4a1248f885563e241fa56fe9f69616dc2.tar.xz
Add hooks allowing to override the `oom` behavior
-rw-r--r--src/libstd/alloc.rs48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index 0c95ceff2e..4f9dffc7c9 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -17,11 +17,55 @@
17#[doc(inline)] pub use alloc_system::System; 17#[doc(inline)] pub use alloc_system::System;
18#[doc(inline)] pub use core::alloc::*; 18#[doc(inline)] pub use core::alloc::*;
19 19
20use core::sync::atomic::{AtomicPtr, Ordering};
21use core::{mem, ptr};
22
23static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
24
25/// Registers a custom OOM hook, replacing any that was previously registered.
26///
27/// The OOM hook is invoked when an infallible memory allocation fails.
28/// The default hook prints a message to standard error and aborts the
29/// execution, but this behavior can be customized with the [`set_oom_hook`]
30/// and [`take_oom_hook`] functions.
31///
32/// The hook is provided with a `Layout` struct which contains information
33/// about the allocation that failed.
34///
35/// The OOM hook is a global resource.
36pub fn set_oom_hook(hook: fn(Layout) -> !) {
37 HOOK.store(hook as *mut (), Ordering::SeqCst);
38}
39
40/// Unregisters the current OOM hook, returning it.
41///
42/// *See also the function [`set_oom_hook`].*
43///
44/// If no custom hook is registered, the default hook will be returned.
45pub fn take_oom_hook() -> fn(Layout) -> ! {
46 let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
47 if hook.is_null() {
48 default_oom_hook
49 } else {
50 unsafe { mem::transmute(hook) }
51 }
52}
53
54fn default_oom_hook(layout: Layout) -> ! {
55 rtabort!("memory allocation of {} bytes failed", layout.size())
56}
57
20#[cfg(not(test))] 58#[cfg(not(test))]
21#[doc(hidden)] 59#[doc(hidden)]
22#[lang = "oom"] 60#[lang = "oom"]
23pub extern fn rust_oom(_: Layout) -> ! { 61pub extern fn rust_oom(layout: Layout) -> ! {
24 rtabort!("memory allocation failed"); 62 let hook = HOOK.load(Ordering::SeqCst);
63 let hook: fn(Layout) -> ! = if hook.is_null() {
64 default_oom_hook
65 } else {
66 unsafe { mem::transmute(hook) }
67 };
68 hook(layout)
25} 69}
26 70
27#[cfg(not(test))] 71#[cfg(not(test))]