diff options
| author | David Lönnhager <david.l@mullvad.net> | 2022-07-07 09:24:31 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-07-07 09:24:31 +0200 |
| commit | 887349f12a71a2c6a3bce49ba7d86df353be71a6 (patch) | |
| tree | dbc317bddcb38a7a919b0db48f9add5be0ee22bf | |
| parent | b4a25a2afcb03c516c3b714a6248a978c6183238 (diff) | |
| parent | 20b0ed34eb637f1efa34810d7ab5f0fb44b67f50 (diff) | |
| download | mullvadvpn-887349f12a71a2c6a3bce49ba7d86df353be71a6.tar.xz mullvadvpn-887349f12a71a2c6a3bce49ba7d86df353be71a6.zip | |
Merge branch 'win-fix-power-mgmt-queue'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | talpid-core/src/windows/window.rs | 36 |
2 files changed, 29 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 77b9608775..882cfe1971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Line wrap the file at 100 chars. Th #### Windows - Only use the most recent list of apps to split when resuming from hibernation/sleep if applying it was successful. +- Fix app occasionally getting stuck in the offline state after being suspended. ### Security #### Android diff --git a/talpid-core/src/windows/window.rs b/talpid-core/src/windows/window.rs index 103d74a780..006e5b8e16 100644 --- a/talpid-core/src/windows/window.rs +++ b/talpid-core/src/windows/window.rs @@ -1,7 +1,7 @@ //! Utilities for windows. use std::{os::windows::io::AsRawHandle, ptr, sync::Arc, thread}; -use tokio::sync::watch; +use tokio::sync::broadcast; use winapi::{ shared::{ basetsd::LONG_PTR, @@ -156,21 +156,24 @@ impl PowerManagementEvent { } /// Provides power management events to listeners -#[derive(Clone)] pub struct PowerManagementListener { _window: Arc<WindowScopedHandle>, - rx: watch::Receiver<Option<PowerManagementEvent>>, + rx: broadcast::Receiver<PowerManagementEvent>, } impl PowerManagementListener { /// Creates a new listener. This is expensive compared to cloning an existing instance. pub fn new() -> Self { - let (tx, rx) = tokio::sync::watch::channel(None); + let (tx, rx) = tokio::sync::broadcast::channel(16); let power_broadcast_callback = move |window, message, wparam, lparam| { if message == WM_POWERBROADCAST { if let Some(event) = PowerManagementEvent::try_from_winevent(wparam) { - tx.send_replace(Some(event)); + if tx.send(event).is_err() { + log::debug!("Stopping power management event monitor"); + unsafe { PostQuitMessage(0) }; + return 0; + } } } unsafe { DefWindowProcW(window, message, wparam, lparam) } @@ -186,10 +189,27 @@ impl PowerManagementListener { /// Returns the next power event. pub async fn next(&mut self) -> Option<PowerManagementEvent> { - if self.rx.changed().await.is_err() { - return None; + loop { + match self.rx.recv().await { + Ok(event) => break Some(event), + Err(broadcast::error::RecvError::Closed) => { + log::error!("Sender was unexpectedly dropped"); + break None; + } + Err(broadcast::error::RecvError::Lagged(num_skipped)) => { + log::warn!("Skipped {num_skipped} power broadcast events"); + } + } + } + } +} + +impl Clone for PowerManagementListener { + fn clone(&self) -> Self { + Self { + _window: self._window.clone(), + rx: self.rx.resubscribe(), } - *self.rx.borrow_and_update() } } |
