Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upMake runtime creation safe #450
Conversation
Runtime parent These changes adjust our uses of the rust-mozjs APIs to accommodate the changes in servo/rust-mozjs#450. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #22342. - [x] There are tests for these changes
|
There is one hole that I've come up with so far - while the assertion in the Runtime drop implementation catches the point at which a parent runtime is dropped before all of its children are dropped, that only interrupts the thread on which the parent runtime is executing. The threads on which any child runtimes are executing have no signal that their parent runtime is now invalid. The best choice at this point would be to abort the whole program for the sake of safety, but this PR does not do that right now. |
5c26260
to
ac7f350
d10b181
to
6e9cc73
|
I fixed the racing issues by switching to a single mutex around an enum that represents the engine state. This is ready for review. |
|
r? @asajeffrey |
|
Mostly nits, the main thing is it looks like you're assuming the |
| @@ -42,9 +44,9 @@ doctest = false | |||
|
|
|||
| [features] | |||
| debugmozjs = ['mozjs_sys/debugmozjs'] | |||
| init_once = [] | |||
This comment has been minimized.
This comment has been minimized.
| impl Drop for JSEngine { | ||
| fn drop(&mut self) { | ||
| *ENGINE_STATE.lock().unwrap() = EngineState::ShutDown; | ||
| unsafe { |
This comment has been minimized.
This comment has been minimized.
| /// runtime can be dropped. | ||
| pub struct ParentRuntime { | ||
| parent: *mut JSRuntime, | ||
| count: Arc<AtomicU32>, |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
asajeffrey
Dec 21, 2018
Member
Also, looking through the code it looks like the counter is incremented when the arc is cloned, and decremented when the arc is dropped, so the counter is always the same as the refcount. This makes me suspect that there's a simplification, where ParentRuntime just contains an Arc<JSEngine> or some such.
| /// Unsafety: | ||
| /// If panicking does not abort the program, any threads with child runtimes will | ||
| /// continue executing after the thread with the parent runtime panics, but they | ||
| /// will be in an invalid and undefined state. |
This comment has been minimized.
This comment has been minimized.
asajeffrey
Dec 21, 2018
Member
Hmm, this might be an issue for Servo when we do crash reporting? Not sure what we can do though, other than not put any JS on our crash reporting page and hope for the best.
|
@asajeffrey Review comments addressed. I've added more comments around the adjusted refcounting bits to hopefully make clear why it looks weird. |
|
LGTM. Squash and r=me? |
|
@bors-servo r=asajeffrey |
|
|
Make runtime creation safe The fundamental problem exposed in servo/servo#22342 is that our concept of a parent runtime did not match reality. Using the first JSContext's runtime as the global parent for all subsequent contexts only makes sense if that JSContext outlives every other context. This is not guaranteed, leading to crashes when trying to use those contexts if the first context (and therefore its runtime) was destroyed. The new design incorporates several changes for safer, more clear context and runtime management: * in order to create a new context, either a handle to an initialized JS engine is required or a handle to an existing runtime * all runtimes track outstanding handles that have been created, and assert if a runtime is destroyed before all of its child runtimes * overall initialization and shutdown of the engine is controlled by the lifetime of a JSEngine value, so creating a Runtime value is now infallible <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-mozjs/450) <!-- Reviewable:end -->
|
@bors-servo r=asajeffrey |
|
|
Make runtime creation safe The fundamental problem exposed in servo/servo#22342 is that our concept of a parent runtime did not match reality. Using the first JSContext's runtime as the global parent for all subsequent contexts only makes sense if that JSContext outlives every other context. This is not guaranteed, leading to crashes when trying to use those contexts if the first context (and therefore its runtime) was destroyed. The new design incorporates several changes for safer, more clear context and runtime management: * in order to create a new context, either a handle to an initialized JS engine is required or a handle to an existing runtime * all runtimes track outstanding handles that have been created, and assert if a runtime is destroyed before all of its child runtimes * overall initialization and shutdown of the engine is controlled by the lifetime of a JSEngine value, so creating a Runtime value is now infallible <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-mozjs/450) <!-- Reviewable:end -->
|
|
Update rust-mozjs These changes adjust our uses of the rust-mozjs APIs to accommodate the changes in servo/rust-mozjs#450. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #22342. - [x] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22353) <!-- Reviewable:end -->
jdm commentedDec 2, 2018
•
edited by larsbergstrom
The fundamental problem exposed in servo/servo#22342 is that our concept of a parent runtime did not match reality. Using the first JSContext's runtime as the global parent for all subsequent contexts only makes sense if that JSContext outlives every other context. This is not guaranteed, leading to crashes when trying to use those contexts if the first context (and therefore its runtime) was destroyed.
The new design incorporates several changes for safer, more clear context and runtime management:
This change is