Skip to main content

v8/
locker.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::isolate::Isolate;
4
5/// A handle to a shared isolate, allowing access to the isolate in a thread
6/// safe way.
7///
8/// This is a recursive lock (re-entrant) and may be nested on the same thread.
9#[derive(Debug)]
10pub struct Locker<'a> {
11  _lock: raw::Locker,
12  // Hold a mutable reference to ensure exclusive access to the isolate.
13  locked: &'a mut Isolate,
14}
15
16impl<'a> Locker<'a> {
17  /// Claims the isolate lock.
18  pub fn new(isolate: &'a mut Isolate) -> Self {
19    Self {
20      _lock: raw::Locker::new(isolate),
21      locked: isolate,
22    }
23  }
24
25  /// Returns a reference to the locked isolate.
26  pub fn isolate(&self) -> &Isolate {
27    self.locked
28  }
29
30  /// Returns a mutable reference to the locked isolate.
31  pub fn isolate_mut(&mut self) -> &mut Isolate {
32    self.locked
33  }
34
35  /// Returns if the isolate is locked by the current thread.
36  pub fn is_locked(isolate: &Isolate) -> bool {
37    raw::Locker::is_locked(isolate)
38  }
39}
40
41impl<'a> Deref for Locker<'a> {
42  type Target = Isolate;
43  fn deref(&self) -> &Self::Target {
44    self.isolate()
45  }
46}
47
48impl<'a> DerefMut for Locker<'a> {
49  fn deref_mut(&mut self) -> &mut Self::Target {
50    self.isolate_mut()
51  }
52}
53
54impl<'a> AsMut<Isolate> for Locker<'a> {
55  fn as_mut(&mut self) -> &mut Isolate {
56    self
57  }
58}
59
60mod raw {
61  use std::mem::MaybeUninit;
62
63  use crate::Isolate;
64  use crate::isolate::RealIsolate;
65
66  #[repr(C)]
67  #[derive(Debug)]
68  pub(super) struct Locker([MaybeUninit<usize>; 2]);
69
70  impl Locker {
71    pub fn new(isolate: &Isolate) -> Self {
72      unsafe {
73        let mut s = Self(MaybeUninit::uninit().assume_init());
74        v8__Locker__CONSTRUCT(&mut s, isolate.as_real_ptr());
75        // v8-locker.h disallows copying and assigning, but it does not disallow
76        // moving so this is hopefully safe.
77        s
78      }
79    }
80
81    pub fn is_locked(isolate: &Isolate) -> bool {
82      unsafe { v8__Locker__IsLocked(isolate.as_real_ptr()) }
83    }
84  }
85
86  impl Drop for Locker {
87    fn drop(&mut self) {
88      unsafe { v8__Locker__DESTRUCT(self) }
89    }
90  }
91
92  unsafe extern "C" {
93    fn v8__Locker__CONSTRUCT(locker: *mut Locker, isolate: *const RealIsolate);
94    fn v8__Locker__DESTRUCT(locker: *mut Locker);
95    fn v8__Locker__IsLocked(isolate: *const RealIsolate) -> bool;
96  }
97}