zng_view/
low_memory.rs

1//! Low memory event for desktop systems
2
3#[cfg(windows)]
4mod windows {
5    use windows::Win32::{
6        Foundation::{BOOL, CloseHandle, HANDLE},
7        System::Memory::*,
8    };
9
10    pub struct LowMemoryMonitor {
11        handle: HANDLE,
12        is_low: bool,
13    }
14    impl LowMemoryMonitor {
15        pub fn new() -> Option<LowMemoryMonitor> {
16            // SAFETY: its save, strongly typed call.
17            let handle = match unsafe { CreateMemoryResourceNotification(LowMemoryResourceNotification) } {
18                Ok(h) => h,
19                Err(e) => {
20                    tracing::error!("cannot create memory monitor, {e}");
21                    return None;
22                }
23            };
24
25            if handle.is_invalid() {
26                tracing::error!("cannot create memory monitor, handle is invalid");
27                return None;
28            }
29
30            Some(Self { handle, is_low: false })
31        }
32
33        pub fn notify(&mut self) -> bool {
34            let mut is_low = BOOL::from(false);
35            // SAFETY: strongly typed function called as documented in CreateMemoryResourceNotification msdn page.
36            if let Err(e) = unsafe { QueryMemoryResourceNotification(self.handle, &mut is_low) } {
37                tracing::error!("failed to query memory monitor, {e}");
38                is_low = BOOL::from(false);
39            }
40            if self.is_low != is_low.as_bool() {
41                self.is_low = is_low.as_bool();
42                return self.is_low;
43            }
44            false
45        }
46    }
47    impl Drop for LowMemoryMonitor {
48        fn drop(&mut self) {
49            // SAFETY: strongly typed function called as documented in CreateMemoryResourceNotification msdn page.
50            if let Err(e) = unsafe { CloseHandle(self.handle) } {
51                tracing::error!("failed to close memory monitor, {e}");
52            }
53        }
54    }
55}
56
57#[cfg(windows)]
58pub use windows::LowMemoryMonitor;