mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Don't leak the function that is called on drop
This commit is contained in:
parent
f3d597b31c
commit
e2b953063d
@ -102,21 +102,27 @@ pub mod unord;
|
||||
pub use ena::undo_log;
|
||||
pub use ena::unify;
|
||||
|
||||
pub struct OnDrop<F: Fn()>(pub F);
|
||||
/// Returns a structure that calls `f` when dropped.
|
||||
pub fn defer<F: FnOnce()>(f: F) -> OnDrop<F> {
|
||||
OnDrop(Some(f))
|
||||
}
|
||||
|
||||
impl<F: Fn()> OnDrop<F> {
|
||||
/// Forgets the function which prevents it from running.
|
||||
/// Ensure that the function owns no memory, otherwise it will be leaked.
|
||||
pub struct OnDrop<F: FnOnce()>(Option<F>);
|
||||
|
||||
impl<F: FnOnce()> OnDrop<F> {
|
||||
/// Disables on-drop call.
|
||||
#[inline]
|
||||
pub fn disable(self) {
|
||||
std::mem::forget(self);
|
||||
pub fn disable(mut self) {
|
||||
self.0.take();
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Fn()> Drop for OnDrop<F> {
|
||||
impl<F: FnOnce()> Drop for OnDrop<F> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
(self.0)();
|
||||
if let Some(f) = self.0.take() {
|
||||
f();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
defer,
|
||||
owned_slice::{slice_owned, try_slice_owned, OwnedSlice},
|
||||
OnDrop,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -66,7 +66,7 @@ fn boxed() {
|
||||
fn drop_drops() {
|
||||
let flag = Arc::new(AtomicBool::new(false));
|
||||
let flag_prime = Arc::clone(&flag);
|
||||
let d = OnDrop(move || flag_prime.store(true, atomic::Ordering::Relaxed));
|
||||
let d = defer(move || flag_prime.store(true, atomic::Ordering::Relaxed));
|
||||
|
||||
let slice = slice_owned(d, |_| &[]);
|
||||
|
||||
|
@ -3,9 +3,9 @@ use crate::util;
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::{self as ast, LitKind, MetaItemKind};
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
use rustc_data_structures::defer;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::OnDrop;
|
||||
use rustc_errors::registry::Registry;
|
||||
use rustc_errors::{ErrorGuaranteed, Handler};
|
||||
use rustc_lint::LintStore;
|
||||
@ -325,7 +325,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
||||
|
||||
rustc_span::set_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
|
||||
let r = {
|
||||
let _sess_abort_error = OnDrop(|| {
|
||||
let _sess_abort_error = defer(|| {
|
||||
compiler.sess.finish_diagnostics(registry);
|
||||
});
|
||||
|
||||
|
@ -78,7 +78,7 @@ where
|
||||
{
|
||||
TLV.with(|tlv| {
|
||||
let old = tlv.replace(erase(context));
|
||||
let _reset = rustc_data_structures::OnDrop(move || tlv.set(old));
|
||||
let _reset = rustc_data_structures::defer(move || tlv.set(old));
|
||||
f()
|
||||
})
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use {
|
||||
rustc_data_structures::fx::FxHashSet,
|
||||
rustc_data_structures::sync::Lock,
|
||||
rustc_data_structures::sync::Lrc,
|
||||
rustc_data_structures::{jobserver, OnDrop},
|
||||
rustc_data_structures::{defer, jobserver},
|
||||
rustc_span::DUMMY_SP,
|
||||
std::iter,
|
||||
std::process,
|
||||
@ -530,7 +530,7 @@ fn remove_cycle<D: DepKind>(
|
||||
/// all active queries for cycles before finally resuming all the waiters at once.
|
||||
#[cfg(parallel_compiler)]
|
||||
pub fn deadlock<D: DepKind>(query_map: QueryMap<D>, registry: &rayon_core::Registry) {
|
||||
let on_panic = OnDrop(|| {
|
||||
let on_panic = defer(|| {
|
||||
eprintln!("deadlock handler panicked, aborting process");
|
||||
process::abort();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user