summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-07-07 09:24:31 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-07-07 09:24:31 +0200
commit887349f12a71a2c6a3bce49ba7d86df353be71a6 (patch)
treedbc317bddcb38a7a919b0db48f9add5be0ee22bf
parentb4a25a2afcb03c516c3b714a6248a978c6183238 (diff)
parent20b0ed34eb637f1efa34810d7ab5f0fb44b67f50 (diff)
downloadmullvadvpn-887349f12a71a2c6a3bce49ba7d86df353be71a6.tar.xz
mullvadvpn-887349f12a71a2c6a3bce49ba7d86df353be71a6.zip
Merge branch 'win-fix-power-mgmt-queue'
-rw-r--r--CHANGELOG.md1
-rw-r--r--talpid-core/src/windows/window.rs36
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()
}
}