]> code.octet-stream.net Git - netwatcher/blobdiff - src/watch_win.rs
Improve Windows errors
[netwatcher] / src / watch_win.rs
index 41612b8ae5f51d979fcf99f697ae30646766401b..a247916b7aac1cf586f54d54a1526e1ad11cccdb 100644 (file)
@@ -23,7 +23,7 @@ struct WatchState {
     /// The last result that we captured, for diffing
     prev_list: List,
     /// User's callback
     /// 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) struct WatchHandle {
@@ -39,7 +39,7 @@ impl Drop for 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 {
     callback: F,
 ) -> Result<WatchHandle, Error> {
     let state = Box::pin(Mutex::new(WatchState {
@@ -60,17 +60,15 @@ pub(crate) fn watch_interfaces<F: FnMut(Update) + 'static>(
     };
     match res {
         NO_ERROR => {
     };
     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 })
         }
             // 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)),
     }
 }
 
     }
 }
 
@@ -81,15 +79,19 @@ unsafe extern "system" fn notif(
 ) {
     let state_ptr = ctx as *const Mutex<WatchState>;
     unsafe {
 ) {
     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;
     }
     if new_list == state.prev_list {
         return;
     }