Windows: Auto close HANDLE (#9429)
`HANDLE` is wrapped in a RAII struct. Release Notes: - N/A Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
868616d62e
commit
250528d28f
2 changed files with 42 additions and 20 deletions
|
@ -59,7 +59,7 @@ pub(crate) struct WindowsPlatformInner {
|
||||||
text_system: Arc<WindowsTextSystem>,
|
text_system: Arc<WindowsTextSystem>,
|
||||||
callbacks: Mutex<Callbacks>,
|
callbacks: Mutex<Callbacks>,
|
||||||
pub raw_window_handles: RwLock<SmallVec<[HWND; 4]>>,
|
pub raw_window_handles: RwLock<SmallVec<[HWND; 4]>>,
|
||||||
pub(crate) dispatch_event: HANDLE,
|
pub(crate) dispatch_event: OwnedHandle,
|
||||||
pub(crate) settings: RefCell<WindowsPlatformSystemSettings>,
|
pub(crate) settings: RefCell<WindowsPlatformSystemSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +76,6 @@ impl WindowsPlatformInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for WindowsPlatformInner {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { CloseHandle(self.dispatch_event) }.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Callbacks {
|
struct Callbacks {
|
||||||
open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
|
open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
|
||||||
|
@ -152,8 +146,9 @@ impl WindowsPlatform {
|
||||||
OleInitialize(None).expect("unable to initialize Windows OLE");
|
OleInitialize(None).expect("unable to initialize Windows OLE");
|
||||||
}
|
}
|
||||||
let (main_sender, main_receiver) = flume::unbounded::<Runnable>();
|
let (main_sender, main_receiver) = flume::unbounded::<Runnable>();
|
||||||
let dispatch_event = unsafe { CreateEventW(None, false, false, None) }.unwrap();
|
let dispatch_event =
|
||||||
let dispatcher = Arc::new(WindowsDispatcher::new(main_sender, dispatch_event));
|
OwnedHandle::new(unsafe { CreateEventW(None, false, false, None) }.unwrap());
|
||||||
|
let dispatcher = Arc::new(WindowsDispatcher::new(main_sender, dispatch_event.to_raw()));
|
||||||
let background_executor = BackgroundExecutor::new(dispatcher.clone());
|
let background_executor = BackgroundExecutor::new(dispatcher.clone());
|
||||||
let foreground_executor = ForegroundExecutor::new(dispatcher);
|
let foreground_executor = ForegroundExecutor::new(dispatcher);
|
||||||
let text_system = Arc::new(WindowsTextSystem::new());
|
let text_system = Arc::new(WindowsTextSystem::new());
|
||||||
|
@ -208,14 +203,15 @@ impl Platform for WindowsPlatform {
|
||||||
|
|
||||||
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>) {
|
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>) {
|
||||||
on_finish_launching();
|
on_finish_launching();
|
||||||
let dispatch_event = self.inner.dispatch_event;
|
let dispatch_event = self.inner.dispatch_event.to_raw();
|
||||||
let vsync_event = unsafe { CreateEventW(None, false, false, None) }.unwrap();
|
let vsync_event = create_event().unwrap();
|
||||||
let timer_stop_event = unsafe { CreateEventW(None, false, false, None) }.unwrap();
|
let timer_stop_event = create_event().unwrap();
|
||||||
begin_vsync_timer(vsync_event, timer_stop_event);
|
let raw_timer_stop_event = timer_stop_event.to_raw();
|
||||||
|
begin_vsync_timer(vsync_event.to_raw(), timer_stop_event);
|
||||||
'a: loop {
|
'a: loop {
|
||||||
let wait_result = unsafe {
|
let wait_result = unsafe {
|
||||||
MsgWaitForMultipleObjects(
|
MsgWaitForMultipleObjects(
|
||||||
Some(&[vsync_event, dispatch_event]),
|
Some(&[vsync_event.to_raw(), dispatch_event]),
|
||||||
false,
|
false,
|
||||||
INFINITE,
|
INFINITE,
|
||||||
QS_ALLINPUT,
|
QS_ALLINPUT,
|
||||||
|
@ -257,8 +253,7 @@ impl Platform for WindowsPlatform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_vsync_timer(timer_stop_event);
|
end_vsync_timer(raw_timer_stop_event);
|
||||||
unsafe { CloseHandle(dispatch_event) }.log_err();
|
|
||||||
|
|
||||||
let mut callbacks = self.inner.callbacks.lock();
|
let mut callbacks = self.inner.callbacks.lock();
|
||||||
if let Some(callback) = callbacks.quit.as_mut() {
|
if let Some(callback) = callbacks.quit.as_mut() {
|
||||||
|
@ -737,15 +732,14 @@ unsafe fn show_savefile_dialog(directory: PathBuf) -> Result<IFileSaveDialog> {
|
||||||
Ok(dialog)
|
Ok(dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_vsync_timer(vsync_event: HANDLE, timer_stop_event: HANDLE) {
|
fn begin_vsync_timer(vsync_event: HANDLE, timer_stop_event: OwnedHandle) {
|
||||||
let vsync_fn = select_vsync_fn();
|
let vsync_fn = select_vsync_fn();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
while vsync_fn(timer_stop_event) {
|
while vsync_fn(timer_stop_event.to_raw()) {
|
||||||
if unsafe { SetEvent(vsync_event) }.log_err().is_none() {
|
if unsafe { SetEvent(vsync_event) }.log_err().is_none() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe { CloseHandle(timer_stop_event) }.log_err();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use windows::Win32::{Foundation::*, UI::WindowsAndMessaging::*};
|
use util::ResultExt;
|
||||||
|
use windows::Win32::{Foundation::*, System::Threading::*, UI::WindowsAndMessaging::*};
|
||||||
|
|
||||||
pub(crate) trait HiLoWord {
|
pub(crate) trait HiLoWord {
|
||||||
fn hiword(&self) -> u16;
|
fn hiword(&self) -> u16;
|
||||||
|
@ -69,6 +70,33 @@ pub(crate) unsafe fn set_window_long(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct OwnedHandle(HANDLE);
|
||||||
|
|
||||||
|
impl OwnedHandle {
|
||||||
|
pub(crate) fn new(handle: HANDLE) -> Self {
|
||||||
|
Self(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn to_raw(&self) -> HANDLE {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for OwnedHandle {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.0.is_invalid() {
|
||||||
|
unsafe { CloseHandle(self.0) }.log_err();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_event() -> windows::core::Result<OwnedHandle> {
|
||||||
|
Ok(OwnedHandle::new(unsafe {
|
||||||
|
CreateEventW(None, false, false, None)?
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn windows_credentials_target_name(url: &str) -> String {
|
pub(crate) fn windows_credentials_target_name(url: &str) -> String {
|
||||||
format!("zed:url={}", url)
|
format!("zed:url={}", url)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue