mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 01:25:53 -04:00
Mutex for Isolate.Terminate
Improvement to https://github.com/lightpanda-io/browser/pull/2246 In that PR, the check for `v8__Isolate__IsExecutionTerminating` guarded runMicrotasks from running when the execution was terminated, but what if termination happens immediately after? This adds a mutex to ensure that the isolate cannot be terminated while microtasks are being processed.
This commit is contained in:
@@ -91,6 +91,11 @@ private_symbols: PrivateSymbols,
|
||||
|
||||
microtask_queues_are_running: bool,
|
||||
|
||||
// Serializes V8 calls that race with TerminateExecution (which can fire from
|
||||
// the sighandler thread). Without this, a terminate landing between the
|
||||
// IsExecutionTerminating check and PerformCheckpoint trips a V8 debug assert.
|
||||
terminate_mutex: std.Thread.Mutex = .{},
|
||||
|
||||
pub const InitOpts = struct {
|
||||
with_inspector: bool = false,
|
||||
};
|
||||
@@ -360,6 +365,9 @@ pub fn destroyContext(self: *Env, context: *Context) void {
|
||||
|
||||
pub fn runMicrotasks(self: *Env) void {
|
||||
if (self.microtask_queues_are_running == false) {
|
||||
self.terminate_mutex.lock();
|
||||
defer self.terminate_mutex.unlock();
|
||||
|
||||
const v8_isolate = self.isolate.handle;
|
||||
|
||||
if (v8.v8__Isolate__IsExecutionTerminating(v8_isolate)) {
|
||||
@@ -489,14 +497,18 @@ pub fn dumpMemoryStats(self: *Env) void {
|
||||
, .{ stats.total_heap_size, stats.total_heap_size_executable, stats.total_physical_size, stats.total_available_size, stats.used_heap_size, stats.heap_size_limit, stats.malloced_memory, stats.external_memory, stats.peak_malloced_memory, stats.number_of_native_contexts, stats.number_of_detached_contexts, stats.total_global_handles_size, stats.used_global_handles_size, stats.does_zap_garbage });
|
||||
}
|
||||
|
||||
pub fn terminate(self: *const Env) void {
|
||||
pub fn terminate(self: *Env) void {
|
||||
self.terminate_mutex.lock();
|
||||
defer self.terminate_mutex.unlock();
|
||||
v8.v8__Isolate__TerminateExecution(self.isolate.handle);
|
||||
}
|
||||
|
||||
/// Clears a pending termination so V8 calls (e.g. those made during cleanup)
|
||||
/// don't keep tripping over the terminating-state asserts. Safe to call
|
||||
/// unconditionally; a no-op if termination wasn't pending.
|
||||
pub fn cancelTerminate(self: *const Env) void {
|
||||
pub fn cancelTerminate(self: *Env) void {
|
||||
self.terminate_mutex.lock();
|
||||
defer self.terminate_mutex.unlock();
|
||||
v8.v8__Isolate__CancelTerminateExecution(self.isolate.handle);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user