From b571362bf116f069521619f6b7312f3545ee870f Mon Sep 17 00:00:00 2001 From: Ryan Goldstein Date: Thu, 20 Jun 2019 21:46:01 -0700 Subject: [PATCH] Fix a panic due to double-borrow --- Cargo.toml | 3 ++ src/platform_impl/stdweb/event_loop.rs | 49 +++++++++++++++----------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4ee84239..5127f78f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,3 +77,6 @@ version = "0.8" [target.'cfg(target_arch = "wasm32")'.dependencies] stdweb = { path = "../stdweb", optional = true } instant = { version = "0.1", features = ["stdweb"] } + +[patch.crates-io] +stdweb = { path = "../stdweb" } diff --git a/src/platform_impl/stdweb/event_loop.rs b/src/platform_impl/stdweb/event_loop.rs index 822ebcea..97d582ff 100644 --- a/src/platform_impl/stdweb/event_loop.rs +++ b/src/platform_impl/stdweb/event_loop.rs @@ -333,9 +333,9 @@ impl EventLoopRunnerShared { } // Determine if event handling is in process, and then release the borrow on the runner - match *self.0.runner.borrow() { + let (start_cause, event_is_start) = match *self.0.runner.borrow() { Some(ref runner) if !runner.is_busy => { - let (start_cause, event_is_start) = if let Event::NewEvents(cause) = event { + if let Event::NewEvents(cause) = event { (cause, true) } else { (match runner.control { @@ -359,29 +359,30 @@ impl EventLoopRunnerShared { }, ControlFlowStatus::Exit => { return; } }, false) - }; - let mut control = runner.control.to_control_flow(); - // Handle starting a new batch of events - // - // The user is informed via Event::NewEvents that there is a batch of events to process - // However, there is only one of these per batch of events - self.handle_event(Event::NewEvents(start_cause), &mut control); - if !event_is_start { - self.handle_event(event, &mut control); - } - self.handle_event(Event::EventsCleared, &mut control); - - self.apply_control_flow(control); - - // If the event loop is closed, it has been closed this iteration and now the closing - // event should be emitted - if self.closed() { - self.handle_event(Event::LoopDestroyed, &mut control); } } _ => { + // Events are currently being handled, so queue this one and don't try to + // double-process the event queue self.0.events.borrow_mut().push_back(event); + return; } + }; + let mut control = self.current_control_flow(); + // Handle starting a new batch of events + // + // The user is informed via Event::NewEvents that there is a batch of events to process + // However, there is only one of these per batch of events + self.handle_event(Event::NewEvents(start_cause), &mut control); + if !event_is_start { + self.handle_event(event, &mut control); + } + self.handle_event(Event::EventsCleared, &mut control); + self.apply_control_flow(control); + // If the event loop is closed, it has been closed this iteration and now the closing + // event should be emitted + if self.closed() { + self.handle_event(Event::LoopDestroyed, &mut control); } } @@ -464,5 +465,13 @@ impl EventLoopRunnerShared { None => false, // If the event loop is None, it has not been intialised yet, so it cannot be closed } } + + // Get the current control flow state + fn current_control_flow(&self) -> ControlFlow { + match *self.0.runner.borrow() { + Some(ref runner) => runner.control.to_control_flow(), + None => ControlFlow::Poll, + } + } }