Skip to content
This repository was archived by the owner on Nov 12, 2022. It is now read-only.

Commit b991ef3

Browse files
committed
Call JS_ShutDown when all runtimes have been dropped.
1 parent e381008 commit b991ef3

10 files changed

+33
-14
lines changed

src/rust.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ use std::default::Default;
1616
use std::ops::{Deref, DerefMut};
1717
use std::cell::{Cell, UnsafeCell};
1818
use std::marker::PhantomData;
19+
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1920
use consts::{JSCLASS_RESERVED_SLOTS_MASK, JSCLASS_GLOBAL_SLOT_COUNT};
2021
use consts::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
2122
use jsapi;
2223
use jsapi::{AutoIdVector, AutoObjectVector, CallArgs, CompartmentOptions, ContextFriendFields};
2324
use jsapi::{Evaluate2, Handle, HandleBase, HandleObject, HandleValue, HandleValueArray, Heap};
2425
use jsapi::{HeapObjectPostBarrier, HeapValuePostBarrier, InitSelfHostedCode, IsWindowSlow, JS_BeginRequest};
25-
use jsapi::{JS_DefineFunctions, JS_DefineProperties, JS_DestroyRuntime, JS_EndRequest};
26+
use jsapi::{JS_DefineFunctions, JS_DefineProperties, JS_DestroyRuntime, JS_EndRequest, JS_ShutDown};
2627
use jsapi::{JS_EnterCompartment, JS_EnumerateStandardClasses, JS_GetContext, JS_GlobalObjectTraceHook};
2728
use jsapi::{JS_Init, JS_LeaveCompartment, JS_MayResolveStandardClass, JS_NewRuntime, JS_ResolveStandardClass};
2829
use jsapi::{JS_SetGCParameter, JS_SetNativeStackQuota, JS_WrapValue, JSAutoCompartment};
@@ -98,6 +99,11 @@ impl ToResult for bool {
9899

99100
thread_local!(static CONTEXT: Cell<*mut JSContext> = Cell::new(ptr::null_mut()));
100101

102+
lazy_static! {
103+
static ref OUTSTANDING_RUNTIMES: AtomicUsize = AtomicUsize::new(0);
104+
static ref SHUT_DOWN: AtomicBool = AtomicBool::new(false);
105+
}
106+
101107
/// A wrapper for the `JSRuntime` and `JSContext` structures in SpiderMonkey.
102108
pub struct Runtime {
103109
rt: *mut JSRuntime,
@@ -115,7 +121,13 @@ impl Runtime {
115121
}
116122

117123
/// Creates a new `JSRuntime` and `JSContext`.
118-
pub fn new() -> Runtime {
124+
pub fn new() -> Result<Runtime, ()> {
125+
if SHUT_DOWN.load(Ordering::SeqCst) {
126+
return Err(());
127+
}
128+
129+
OUTSTANDING_RUNTIMES.fetch_add(1, Ordering::SeqCst);
130+
119131
unsafe {
120132
struct TopRuntime(*mut JSRuntime);
121133
unsafe impl Sync for TopRuntime {}
@@ -172,10 +184,10 @@ impl Runtime {
172184

173185
JS_BeginRequest(js_context);
174186

175-
Runtime {
187+
Ok(Runtime {
176188
rt: js_runtime,
177189
cx: js_context,
178-
}
190+
})
179191
}
180192
}
181193

@@ -231,6 +243,11 @@ impl Drop for Runtime {
231243
assert_eq!(context.get(), self.cx);
232244
context.set(ptr::null_mut());
233245
});
246+
247+
if OUTSTANDING_RUNTIMES.fetch_sub(1, Ordering::SeqCst) == 1 {
248+
SHUT_DOWN.store(true, Ordering::SeqCst);
249+
JS_ShutDown();
250+
}
234251
}
235252
}
236253
}

tests/callback.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use std::str;
2525

2626
#[test]
2727
fn callback() {
28-
let runtime = Runtime::new();
28+
let runtime = Runtime::new().unwrap();
2929
let context = runtime.cx();
3030
let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
3131
let c_option = CompartmentOptions::default();

tests/enumerate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::ptr;
2121

2222
#[test]
2323
fn enumerate() {
24-
let rt = Runtime::new();
24+
let rt = Runtime::new().unwrap();
2525
let cx = rt.cx();
2626

2727
unsafe {

tests/evaluate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::ptr;
1515

1616
#[test]
1717
fn evaluate() {
18-
let rt = Runtime::new();
18+
let rt = Runtime::new().unwrap();
1919
let cx = rt.cx();
2020

2121
unsafe {

tests/panic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::str;
2121
#[test]
2222
#[should_panic]
2323
fn panic() {
24-
let runtime = Runtime::new();
24+
let runtime = Runtime::new().unwrap();
2525
let context = runtime.cx();
2626
let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
2727
let c_option = CompartmentOptions::default();

tests/rooting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::ptr;
2828
#[test]
2929
fn rooting() {
3030
unsafe {
31-
let runtime = Runtime::new();
31+
let runtime = Runtime::new().unwrap();
3232
JS_SetGCZeal(runtime.rt(), 2, 1);
3333

3434
let cx = runtime.cx();

tests/runtime.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::ptr;
2121
#[test]
2222
fn runtime() {
2323
unsafe {
24-
let runtime = Runtime::new();
24+
let runtime = Runtime::new().unwrap();
2525

2626
let cx = runtime.cx();
2727
let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
@@ -35,6 +35,8 @@ fn runtime() {
3535
let _ac = JSAutoCompartment::new(cx, global.get());
3636
rooted!(in(cx) let _object = JS_NewObject(cx, &CLASS as *const _));
3737
}
38+
39+
assert!(Runtime::new().is_err());
3840
}
3941

4042
unsafe extern fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) {

tests/stack_limit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::ptr;
1515

1616
#[test]
1717
fn stack_limit() {
18-
let rt = Runtime::new();
18+
let rt = Runtime::new().unwrap();
1919
let cx = rt.cx();
2020

2121
unsafe {

tests/typedarray.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::ptr;
1818

1919
#[test]
2020
fn typedarray() {
21-
let rt = Runtime_::new();
21+
let rt = Runtime_::new().unwrap();
2222
let cx = rt.cx();
2323

2424
unsafe {
@@ -76,7 +76,7 @@ fn typedarray() {
7676
#[test]
7777
#[should_panic]
7878
fn typedarray_update_panic() {
79-
let rt = Runtime_::new();
79+
let rt = Runtime_::new().unwrap();
8080
let cx = rt.cx();
8181

8282
unsafe {

tests/vec_conversion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::ptr;
2121

2222
#[test]
2323
fn vec_conversion() {
24-
let rt = Runtime::new();
24+
let rt = Runtime::new().unwrap();
2525
let cx = rt.cx();
2626

2727
let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;

0 commit comments

Comments
 (0)