feat: Add ThreadRegistrationGuard in nix-expr
(cherry picked from commit f287122e354535c2ee2f16c930038b19142f522a)
This commit is contained in:
parent
b714f46e07
commit
f177507f88
1 changed files with 34 additions and 16 deletions
|
|
@ -470,30 +470,32 @@ pub fn gc_now() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ThreadRegistrationGuard {
|
||||||
|
must_unregister: bool,
|
||||||
|
}
|
||||||
|
impl Drop for ThreadRegistrationGuard {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.must_unregister {
|
||||||
|
unsafe {
|
||||||
|
raw::GC_unregister_my_thread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run a function while making sure that the current thread is registered with the GC.
|
/// Run a function while making sure that the current thread is registered with the GC.
|
||||||
pub fn gc_registering_current_thread<F, R>(f: F) -> Result<R>
|
pub fn gc_registering_current_thread<F, R>(f: F) -> Result<R>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> R,
|
F: FnOnce() -> R,
|
||||||
{
|
{
|
||||||
init()?;
|
let guard = gc_register_my_thread()?;
|
||||||
if unsafe { raw::GC_thread_is_registered() } != 0 {
|
let r = f();
|
||||||
return Ok(f());
|
drop(guard);
|
||||||
} else {
|
Ok(r)
|
||||||
gc_register_my_thread()?;
|
|
||||||
let r = f();
|
|
||||||
unsafe {
|
|
||||||
raw::GC_unregister_my_thread();
|
|
||||||
}
|
|
||||||
return Ok(r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gc_register_my_thread() -> Result<()> {
|
fn gc_register_my_thread_do_it() -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let already_done = raw::GC_thread_is_registered();
|
|
||||||
if already_done != 0 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let mut sb: raw::GC_stack_base = raw::GC_stack_base {
|
let mut sb: raw::GC_stack_base = raw::GC_stack_base {
|
||||||
mem_base: null_mut(),
|
mem_base: null_mut(),
|
||||||
};
|
};
|
||||||
|
|
@ -506,6 +508,22 @@ pub fn gc_register_my_thread() -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gc_register_my_thread() -> Result<ThreadRegistrationGuard> {
|
||||||
|
init()?;
|
||||||
|
unsafe {
|
||||||
|
let already_done = raw::GC_thread_is_registered();
|
||||||
|
if already_done != 0 {
|
||||||
|
return Ok(ThreadRegistrationGuard {
|
||||||
|
must_unregister: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gc_register_my_thread_do_it()?;
|
||||||
|
Ok(ThreadRegistrationGuard {
|
||||||
|
must_unregister: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Clone for EvalState {
|
impl Clone for EvalState {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
EvalState {
|
EvalState {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue