Skip to main content

v8/
unlocker.rs

1use crate::isolate::Isolate;
2
3/// Temporarily releases the isolate lock so other threads may enter.
4///
5/// This is not recursive; do not stack multiple Unlockers.
6#[derive(Debug)]
7pub struct Unlocker<'a> {
8  _unlocker: raw::Unlocker,
9  // Hold a mutable reference to ensure exclusive access to the isolate.
10  _unlocked: &'a mut Isolate,
11}
12
13impl<'a> Unlocker<'a> {
14  /// Releases the isolate lock for the lifetime of this unlocker.
15  ///
16  /// Callers should exit the isolate before constructing an Unlocker and
17  /// re-enter after it is dropped, matching V8's C++ API usage.
18  pub fn new(isolate: &'a mut Isolate) -> Self {
19    Self {
20      _unlocker: raw::Unlocker::new(isolate),
21      _unlocked: isolate,
22    }
23  }
24}
25
26mod raw {
27  use std::mem::MaybeUninit;
28
29  use crate::Isolate;
30  use crate::isolate::RealIsolate;
31
32  #[repr(C)]
33  #[derive(Debug)]
34  pub(super) struct Unlocker([MaybeUninit<usize>; 1]);
35
36  impl Unlocker {
37    pub fn new(isolate: &Isolate) -> Self {
38      unsafe {
39        let mut s = Self(MaybeUninit::uninit().assume_init());
40        v8__Unlocker__CONSTRUCT(&mut s, isolate.as_real_ptr());
41        s
42      }
43    }
44  }
45
46  impl Drop for Unlocker {
47    fn drop(&mut self) {
48      unsafe { v8__Unlocker__DESTRUCT(self) }
49    }
50  }
51
52  unsafe extern "C" {
53    fn v8__Unlocker__CONSTRUCT(
54      unlocker: *mut Unlocker,
55      isolate: *const RealIsolate,
56    );
57    fn v8__Unlocker__DESTRUCT(unlocker: *mut Unlocker);
58  }
59}