Skip to content

Commit

Permalink
Fix waking on windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvc94ch committed Nov 12, 2020
1 parent c4ae37c commit abfeb07
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 9 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ libc = "0.2.66"
async-io = "1.2.0"

[target.'cfg(windows)'.dependencies]
futures = { version = "0.3.8", default-features = false }
if-addrs = "0.6.5"
winapi = { version = "0.3.8", features = ["netioapi", "ntdef", "winerror", "ws2def"] }
18 changes: 9 additions & 9 deletions src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::IfEvent;
use futures::task::AtomicWaker;
use futures_lite::future::poll_fn;
use if_addrs::IfAddr;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
Expand All @@ -8,7 +9,7 @@ use std::{
atomic::{AtomicBool, Ordering},
Arc,
},
task::{Poll, Waker},
task::Poll,
};
use winapi::shared::{
netioapi::{
Expand All @@ -24,22 +25,24 @@ use winapi::shared::{
pub struct IfWatcher {
addrs: HashSet<IpNet>,
queue: VecDeque<IfEvent>,
waker: Option<Waker>,
notif: RouteChangeNotification,
waker: Arc<AtomicWaker>,
resync: Arc<AtomicBool>,
}

impl IfWatcher {
/// Create a watcher
pub async fn new() -> std::io::Result<Self> {
let resync = Arc::new(AtomicBool::new(true));
let waker = Arc::new(AtomicWaker::new());
Ok(Self {
addrs: Default::default(),
queue: Default::default(),
waker: Default::default(),
waker: waker.clone(),
resync: resync.clone(),
notif: RouteChangeNotification::new(Box::new(move |_, _| {
resync.store(true, Ordering::SeqCst);
resync.store(true, Ordering::Relaxed);
waker.wake();
}))?,
})
}
Expand All @@ -62,9 +65,6 @@ impl IfWatcher {
self.queue.push_back(IfEvent::Up(ipnet));
}
}
if let Some(waker) = self.waker.take() {
waker.wake();
}
Ok(())
}

Expand All @@ -75,8 +75,8 @@ impl IfWatcher {
/// Returns a future for the next event.
pub async fn next(&mut self) -> std::io::Result<IfEvent> {
poll_fn(|cx| {
self.waker = Some(cx.waker().clone());
if self.resync.load(Ordering::SeqCst) {
self.waker.register(cx.waker());
if self.resync.swap(false, Ordering::Relaxed) {
if let Err(error) = self.resync() {
return Poll::Ready(Err(error));
}
Expand Down

0 comments on commit abfeb07

Please sign in to comment.