diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/inspector.rs | 37 | ||||
-rw-r--r-- | core/runtime.rs | 18 |
2 files changed, 49 insertions, 6 deletions
diff --git a/core/inspector.rs b/core/inspector.rs index e3db65afe..8a9136091 100644 --- a/core/inspector.rs +++ b/core/inspector.rs @@ -35,6 +35,7 @@ use std::ptr::NonNull; use std::rc::Rc; use std::sync::Arc; use std::thread; +use v8::HandleScope; pub enum InspectorMsgKind { Notification, @@ -213,10 +214,28 @@ impl JsRuntimeInspector { self__ } + pub fn context_destroyed( + &mut self, + scope: &mut HandleScope, + context: v8::Global<v8::Context>, + ) { + let context = v8::Local::new(scope, context); + self + .v8_inspector + .borrow_mut() + .as_mut() + .unwrap() + .context_destroyed(context); + } + pub fn has_active_sessions(&self) -> bool { self.sessions.borrow().has_active_sessions() } + pub fn has_blocking_sessions(&self) -> bool { + self.sessions.borrow().has_blocking_sessions() + } + fn poll_sessions( &self, mut invoker_cx: Option<&mut Context>, @@ -262,8 +281,11 @@ impl JsRuntimeInspector { // Accept new connections. let poll_result = sessions.session_rx.poll_next_unpin(cx); if let Poll::Ready(Some(session_proxy)) = poll_result { - let session = - InspectorSession::new(sessions.v8_inspector.clone(), session_proxy); + let session = InspectorSession::new( + sessions.v8_inspector.clone(), + session_proxy, + false, + ); let prev = sessions.handshake.replace(session); assert!(prev.is_none()); } @@ -378,7 +400,7 @@ impl JsRuntimeInspector { // InspectorSessions for a local session is added directly to the "established" // sessions, so it doesn't need to go through the session sender. let inspector_session = - InspectorSession::new(self.v8_inspector.clone(), proxy); + InspectorSession::new(self.v8_inspector.clone(), proxy, true); self .sessions .borrow_mut() @@ -432,6 +454,10 @@ impl SessionContainer { !self.established.is_empty() || self.handshake.is_some() } + fn has_blocking_sessions(&self) -> bool { + self.established.iter().any(|s| s.blocking) + } + /// A temporary placeholder that should be used before actual /// instance of V8Inspector is created. It's used in favor /// of `Default` implementation to signal that it's not meant @@ -528,6 +554,9 @@ struct InspectorSession { v8_channel: v8::inspector::ChannelBase, v8_session: v8::UniqueRef<v8::inspector::V8InspectorSession>, proxy: InspectorSessionProxy, + // Describes if session should keep event loop alive, eg. a local REPL + // session should keep event loop alive, but a Websocket session shouldn't. + blocking: bool, } impl InspectorSession { @@ -536,6 +565,7 @@ impl InspectorSession { pub fn new( v8_inspector_rc: Rc<RefCell<v8::UniquePtr<v8::inspector::V8Inspector>>>, session_proxy: InspectorSessionProxy, + blocking: bool, ) -> Box<Self> { new_box_with(move |self_ptr| { let v8_channel = v8::inspector::ChannelBase::new::<Self>(); @@ -556,6 +586,7 @@ impl InspectorSession { v8_channel, v8_session, proxy: session_proxy, + blocking, } }) } diff --git a/core/runtime.rs b/core/runtime.rs index 8cb38de2f..9ee3aad70 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -1099,9 +1099,21 @@ impl JsRuntime { let pending_state = self.event_loop_pending_state(); if !pending_state.is_pending() && !maybe_scheduling { if has_inspector { - let inspector_has_active_sessions = - self.inspector().borrow_mut().has_active_sessions(); - if wait_for_inspector && inspector_has_active_sessions { + let inspector = self.inspector(); + let has_active_sessions = inspector.borrow().has_active_sessions(); + let has_blocking_sessions = inspector.borrow().has_blocking_sessions(); + + if wait_for_inspector && has_active_sessions { + // If there are no blocking sessions (eg. REPL) we can now notify + // debugger that the program has finished running and we're ready + // to exit the process once debugger disconnects. + if !has_blocking_sessions { + let context = self.global_context(); + let scope = &mut self.handle_scope(); + inspector.borrow_mut().context_destroyed(scope, context); + println!("Program finished. Waiting for inspector to disconnect to exit the process..."); + } + return Poll::Pending; } } |