/// The last result that we captured, for diffing
prev_list: List,
/// User's callback
- cb: Box<dyn FnMut(Update) + 'static>,
+ cb: Box<dyn FnMut(Update) + Send + 'static>,
}
pub(crate) struct WatchHandle {
}
}
-pub(crate) fn watch_interfaces<F: FnMut(Update) + 'static>(
+pub(crate) fn watch_interfaces<F: FnMut(Update) + Send + 'static>(
callback: F,
) -> Result<WatchHandle, Error> {
let state = Box::pin(Mutex::new(WatchState {
};
match res {
NO_ERROR => {
- // Trigger an initial update.
- // This is allowed to race with true updates because it
- // will always calculate a diff and discard no-ops.
- handle_notif(&mut state.lock().unwrap());
+ // Trigger an initial update
+ handle_notif(&mut state.lock().unwrap(), crate::list::list_interfaces()?);
// Then return the handle
Ok(WatchHandle { hnd, _state: state })
}
- ERROR_INVALID_HANDLE => Err(Error::Internal),
- ERROR_INVALID_PARAMETER => Err(Error::Internal),
- ERROR_NOT_ENOUGH_MEMORY => Err(Error::Internal),
- _ => Err(Error::Internal), // TODO: Use FormatMessage and get real error
+ ERROR_INVALID_HANDLE => Err(Error::InvalidHandle),
+ ERROR_INVALID_PARAMETER => Err(Error::InvalidParameter),
+ ERROR_NOT_ENOUGH_MEMORY => Err(Error::NotEnoughMemory),
+ _ => Err(Error::UnexpectedWindowsResult(res.0)),
}
}
) {
let state_ptr = ctx as *const Mutex<WatchState>;
unsafe {
- let state_guard = &mut *state_ptr.as_ref().unwrap().lock().unwrap();
- handle_notif(state_guard);
+ let state_guard = &mut *state_ptr
+ .as_ref()
+ .expect("callback ctx should never be null")
+ .lock()
+ .unwrap();
+ let Ok(new_list) = crate::list::list_interfaces() else {
+ return;
+ };
+ handle_notif(state_guard, new_list);
}
}
-fn handle_notif(state: &mut WatchState) {
- let Ok(new_list) = crate::list::list_interfaces() else {
- return;
- };
+fn handle_notif(state: &mut WatchState, new_list: List) {
if new_list == state.prev_list {
return;
}