Skip to content

Commit 237d323

Browse files
authored
X11: Fix GL related memory leak and crash (#209)
This PR fixes a `BadDrawable` error when closing the window in the middle of drawing by joining with the event loop thread in `WindowHandle::close()`.
1 parent 05d8b62 commit 237d323

File tree

2 files changed

+8
-16
lines changed

2 files changed

+8
-16
lines changed

src/x11/event_loop.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ impl EventLoop {
108108

109109
// Check if the parents's handle was dropped (such as when the host
110110
// requested the window to close)
111-
//
112-
// FIXME: This will need to be changed from just setting an atomic to somehow
113-
// synchronizing with the window being closed (using a synchronous channel, or
114-
// by joining on the event loop thread).
115111
if let Some(parent_handle) = &self.parent_handle {
116112
if parent_handle.parent_did_drop() {
117113
self.handle_must_close();

src/x11/window.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ffi::c_void;
44
use std::sync::atomic::{AtomicBool, Ordering};
55
use std::sync::mpsc;
66
use std::sync::Arc;
7-
use std::thread;
7+
use std::thread::{self, JoinHandle};
88

99
use raw_window_handle::{
1010
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, XlibDisplayHandle,
@@ -31,18 +31,16 @@ use crate::x11::visual_info::WindowVisualConfig;
3131

3232
pub struct WindowHandle {
3333
raw_window_handle: Option<RawWindowHandle>,
34+
event_loop_handle: Option<JoinHandle<()>>,
3435
close_requested: Arc<AtomicBool>,
3536
is_open: Arc<AtomicBool>,
3637
}
3738

3839
impl WindowHandle {
3940
pub fn close(&mut self) {
40-
if self.raw_window_handle.take().is_some() {
41-
// FIXME: This will need to be changed from just setting an atomic to somehow
42-
// synchronizing with the window being closed (using a synchronous channel, or
43-
// by joining on the event loop thread).
44-
45-
self.close_requested.store(true, Ordering::Relaxed);
41+
self.close_requested.store(true, Ordering::Relaxed);
42+
if let Some(event_loop) = self.event_loop_handle.take() {
43+
let _ = event_loop.join();
4644
}
4745
}
4846

@@ -72,9 +70,9 @@ impl ParentHandle {
7270
pub fn new() -> (Self, WindowHandle) {
7371
let close_requested = Arc::new(AtomicBool::new(false));
7472
let is_open = Arc::new(AtomicBool::new(true));
75-
7673
let handle = WindowHandle {
7774
raw_window_handle: None,
75+
event_loop_handle: None,
7876
close_requested: Arc::clone(&close_requested),
7977
is_open: Arc::clone(&is_open),
8078
};
@@ -134,17 +132,15 @@ impl<'a> Window<'a> {
134132
};
135133

136134
let (tx, rx) = mpsc::sync_channel::<WindowOpenResult>(1);
137-
138135
let (parent_handle, mut window_handle) = ParentHandle::new();
139-
140-
thread::spawn(move || {
136+
let join_handle = thread::spawn(move || {
141137
Self::window_thread(Some(parent_id), options, build, tx.clone(), Some(parent_handle))
142138
.unwrap();
143139
});
144140

145141
let raw_window_handle = rx.recv().unwrap().unwrap();
146142
window_handle.raw_window_handle = Some(raw_window_handle.0);
147-
143+
window_handle.event_loop_handle = Some(join_handle);
148144
window_handle
149145
}
150146

0 commit comments

Comments
 (0)