Merge pull request #239 from glennw/fix-close-crash

Fix crash on close in some X11 drivers
This commit is contained in:
tomaka 2015-01-29 22:47:15 +01:00
commit 26c0c966d5

View file

@ -7,7 +7,7 @@ use std::cell::Cell;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::collections::RingBuf; use std::collections::RingBuf;
use super::ffi; use super::ffi;
use std::sync::{Arc, Once, ONCE_INIT}; use std::sync::{Arc, Once, ONCE_INIT, Weak};
use std::sync::{StaticMutex, MUTEX_INIT}; use std::sync::{StaticMutex, MUTEX_INIT};
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor}; pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
@ -36,7 +36,7 @@ fn ensure_thread_init() {
fn with_c_str<F, T>(s: &str, f: F) -> T where F: FnOnce(*const libc::c_char) -> T { fn with_c_str<F, T>(s: &str, f: F) -> T where F: FnOnce(*const libc::c_char) -> T {
use std::ffi::CString; use std::ffi::CString;
let c_str = CString::from_slice(s.as_bytes()); let c_str = CString::from_slice(s.as_bytes());
f(c_str.as_slice_with_nul().as_ptr()) f(c_str.as_slice_with_nul().as_ptr())
} }
struct XWindow { struct XWindow {
@ -50,6 +50,9 @@ struct XWindow {
im: ffi::XIM, im: ffi::XIM,
} }
unsafe impl Send for XWindow {}
unsafe impl Sync for XWindow {}
unsafe impl Send for Window {} unsafe impl Send for Window {}
unsafe impl Sync for Window {} unsafe impl Sync for Window {}
@ -74,25 +77,30 @@ impl Drop for XWindow {
#[derive(Clone)] #[derive(Clone)]
pub struct WindowProxy { pub struct WindowProxy {
x: Arc<XWindow>, x: Weak<XWindow>,
} }
impl WindowProxy { impl WindowProxy {
pub fn wakeup_event_loop(&self) { pub fn wakeup_event_loop(&self) {
let mut xev = ffi::XClientMessageEvent { match self.x.upgrade() {
type_: ffi::ClientMessage, Some(x) => {
window: self.x.window, let mut xev = ffi::XClientMessageEvent {
format: 32, type_: ffi::ClientMessage,
message_type: 0, window: x.window,
serial: 0, format: 32,
send_event: 0, message_type: 0,
display: self.x.display, serial: 0,
l: [0, 0, 0, 0, 0], send_event: 0,
}; display: x.display,
l: [0, 0, 0, 0, 0],
};
unsafe { unsafe {
ffi::XSendEvent(self.x.display, self.x.window, 0, 0, mem::transmute(&mut xev)); ffi::XSendEvent(x.display, x.window, 0, 0, mem::transmute(&mut xev));
ffi::XFlush(self.x.display); ffi::XFlush(x.display);
}
}
None => {}
} }
} }
} }
@ -488,7 +496,7 @@ impl Window {
pub fn create_window_proxy(&self) -> WindowProxy { pub fn create_window_proxy(&self) -> WindowProxy {
WindowProxy { WindowProxy {
x: self.x.clone() x: self.x.downgrade()
} }
} }