mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-21 15:04:33 -05:00
Add Isolate::request_interrupt (#208)
This commit is contained in:
parent
125d88ffc6
commit
03cab59c5c
3 changed files with 61 additions and 0 deletions
|
@ -129,6 +129,11 @@ void v8__Isolate__EnqueueMicrotask(v8::Isolate& isolate,
|
|||
isolate.EnqueueMicrotask(ptr_to_local(function));
|
||||
}
|
||||
|
||||
void v8__Isolate__RequestInterrupt(v8::Isolate& isolate,
|
||||
v8::InterruptCallback callback, void* data) {
|
||||
isolate.RequestInterrupt(callback, data);
|
||||
}
|
||||
|
||||
void v8__Isolate__SetPromiseRejectCallback(v8::Isolate* isolate,
|
||||
v8::PromiseRejectCallback callback) {
|
||||
isolate->SetPromiseRejectCallback(callback);
|
||||
|
|
|
@ -61,6 +61,9 @@ pub type HostImportModuleDynamicallyCallback = extern "C" fn(
|
|||
Local<String>,
|
||||
) -> *mut Promise;
|
||||
|
||||
pub type InterruptCallback =
|
||||
extern "C" fn(isolate: &mut Isolate, data: *mut c_void);
|
||||
|
||||
extern "C" {
|
||||
fn v8__Isolate__New(params: *mut CreateParams) -> *mut Isolate;
|
||||
fn v8__Isolate__Dispose(this: *mut Isolate);
|
||||
|
@ -91,6 +94,11 @@ extern "C" {
|
|||
isolate: *mut Isolate,
|
||||
callback: HostImportModuleDynamicallyCallback,
|
||||
);
|
||||
fn v8__Isolate__RequestInterrupt(
|
||||
isolate: *const Isolate,
|
||||
callback: InterruptCallback,
|
||||
data: *mut c_void,
|
||||
);
|
||||
fn v8__Isolate__ThrowException(
|
||||
isolate: &Isolate,
|
||||
exception: &Value,
|
||||
|
@ -302,6 +310,23 @@ impl Isolate {
|
|||
unsafe { v8__Isolate__EnqueueMicrotask(self, &mut *microtask) }
|
||||
}
|
||||
|
||||
/// Request V8 to interrupt long running JavaScript code and invoke
|
||||
/// the given |callback| passing the given |data| to it. After |callback|
|
||||
/// returns control will be returned to the JavaScript code.
|
||||
/// There may be a number of interrupt requests in flight.
|
||||
/// Can be called from another thread without acquiring a |Locker|.
|
||||
/// Registered |callback| must not reenter interrupted Isolate.
|
||||
// Clippy warns that this method is dereferencing a raw pointer, but it is
|
||||
// not: https://github.com/rust-lang/rust-clippy/issues/3045
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
pub fn request_interrupt(
|
||||
&self,
|
||||
callback: InterruptCallback,
|
||||
data: *mut c_void,
|
||||
) {
|
||||
unsafe { v8__Isolate__RequestInterrupt(self, callback, data) }
|
||||
}
|
||||
|
||||
/// Disposes the isolate. The isolate must not be entered by any
|
||||
/// thread to be disposable.
|
||||
pub unsafe fn dispose(&mut self) {
|
||||
|
|
|
@ -475,6 +475,37 @@ fn terminate_execution() {
|
|||
drop(g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn request_interrupt_small_scripts() {
|
||||
let g = setup();
|
||||
let mut params = v8::Isolate::create_params();
|
||||
params.set_array_buffer_allocator(v8::new_default_allocator());
|
||||
let isolate = v8::Isolate::new(params);
|
||||
let mut locker = v8::Locker::new(&isolate);
|
||||
{
|
||||
let mut hs = v8::HandleScope::new(&mut locker);
|
||||
let scope = hs.enter();
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
|
||||
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
extern "C" fn callback(
|
||||
_isolate: &mut v8::Isolate,
|
||||
data: *mut std::ffi::c_void,
|
||||
) {
|
||||
assert_eq!(data, std::ptr::null_mut());
|
||||
CALL_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
isolate.request_interrupt(callback, std::ptr::null_mut());
|
||||
eval(scope, context, "(function(x){return x;})(1);");
|
||||
assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
|
||||
|
||||
context.exit();
|
||||
}
|
||||
drop(locker);
|
||||
drop(g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_message_listener() {
|
||||
let g = setup();
|
||||
|
|
Loading…
Reference in a new issue