From 92daf66fe636271f44daca3f39986fbf88bee320 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?joseLu=C3=ADs?=
Date: Mon, 3 Feb 2025 19:19:45 +0100
Subject: [PATCH] replace `OnceLock` with `AtomicPtr` in `NATIVE_DISPLAY`
- reduce locking overhead by replacing `OnceLock>` with `AtomicPtr>`.
- add `drop_display` to allow safely resetting `NATIVE_DISPLAY` while ensuring proper deallocation.
- implement `Drop` for `GlContext` and `MetalContext` to guarantee cleanup on context destruction.
- ensure memory safety using `Release/Acquire` ordering and explicit deallocation.
- add `native_display_blocking` and `native_display_nonblocking` for safer access.
- update documentation and rustfmt.
---
src/graphics/gl.rs | 8 ++-
src/graphics/gl/cache.rs | 4 +-
src/graphics/metal.rs | 5 ++
src/lib.rs | 119 ++++++++++++++++++++++++++----------
src/native/android.rs | 2 +-
src/native/ios.rs | 12 ++--
src/native/linux_wayland.rs | 2 +-
src/native/linux_x11.rs | 12 ++--
src/native/macos.rs | 24 ++++----
src/native/wasm.rs | 6 +-
src/native/windows.rs | 22 +++----
11 files changed, 138 insertions(+), 78 deletions(-)
diff --git a/src/graphics/gl.rs b/src/graphics/gl.rs
index 74be9fd9..4079fc00 100644
--- a/src/graphics/gl.rs
+++ b/src/graphics/gl.rs
@@ -520,6 +520,11 @@ pub struct GlContext {
pub(crate) cache: GlCache,
pub(crate) info: ContextInfo,
}
+impl Drop for GlContext {
+ fn drop(&mut self) {
+ crate::drop_display();
+ }
+}
impl GlContext {
pub fn new() -> GlContext {
@@ -1455,8 +1460,7 @@ impl RenderingBackend for GlContext {
TextureOrRenderbuffer::Renderbuffer(id) => id,
};
unsafe {
- self.cache
- .bind_texture(n, texture.params.kind.into(), raw);
+ self.cache.bind_texture(n, texture.params.kind.into(), raw);
glUniform1i(gl_loc, n as i32);
}
}
diff --git a/src/graphics/gl/cache.rs b/src/graphics/gl/cache.rs
index 11293161..de4e8f23 100644
--- a/src/graphics/gl/cache.rs
+++ b/src/graphics/gl/cache.rs
@@ -135,9 +135,7 @@ impl GlCache {
let cached_attr = &mut self.attributes[attr_index];
if cached_attr.is_some() {
- unsafe {
- glDisableVertexAttribArray(attr_index as GLuint)
- };
+ unsafe { glDisableVertexAttribArray(attr_index as GLuint) };
}
*cached_attr = None;
}
diff --git a/src/graphics/metal.rs b/src/graphics/metal.rs
index 7ac8870f..a5ccb508 100644
--- a/src/graphics/metal.rs
+++ b/src/graphics/metal.rs
@@ -280,6 +280,11 @@ pub struct MetalContext {
current_pipeline: Option,
current_ub_offset: u64,
}
+impl Drop for MetalContext {
+ fn drop(&mut self) {
+ crate::drop_display();
+ }
+}
impl MetalContext {
pub fn new() -> MetalContext {
diff --git a/src/lib.rs b/src/lib.rs
index 7385cd86..986c6a2d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -80,19 +80,72 @@ pub mod date {
pub type Context = dyn RenderingBackend;
-use std::sync::{Mutex, OnceLock};
+use std::ptr::null_mut;
+use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
+use std::sync::{Mutex, MutexGuard};
-static NATIVE_DISPLAY: OnceLock> = OnceLock::new();
+/// Atomic pointer to the global display instance, enabling safe concurrent access and resetting.
+static NATIVE_DISPLAY: AtomicPtr> = AtomicPtr::new(null_mut());
+/// Atomic flag indicating whether `NATIVE_DISPLAY` is initialized and safe to access.
+static NATIVE_DISPLAY_READY: AtomicBool = AtomicBool::new(false);
+/// Sets the global display, replacing any previous instance and ensuring visibility to all threads.
fn set_display(display: native::NativeDisplayData) {
- NATIVE_DISPLAY
- .set(Mutex::new(display))
- .unwrap_or_else(|_| panic!("NATIVE_DISPLAY already set"));
+ let new_data = Box::new(Mutex::new(display));
+ let ptr = Box::into_raw(new_data);
+
+ let old = NATIVE_DISPLAY.swap(ptr, Ordering::AcqRel);
+ if !old.is_null() {
+ // SAFETY: `old` was originally created using `Box::into_raw()`, meaning it must be
+ // properly deallocated using `Box::from_raw()` to prevent memory leaks.
+ unsafe { drop(Box::from_raw(old)) };
+ }
+ // Ensure all threads see the updated pointer before marking it as ready.
+ NATIVE_DISPLAY_READY.store(true, Ordering::Release);
+}
+
+/// Returns a reference to the global display mutex, or `None` if uninitialized.
+fn native_display() -> Option<&'static Mutex> {
+ // Ensure this thread sees the latest pointer update before dereferencing.
+ if !NATIVE_DISPLAY_READY.load(Ordering::Acquire) {
+ return None;
+ }
+ let ptr = NATIVE_DISPLAY.load(Ordering::Acquire);
+ if ptr.is_null() {
+ return None;
+ }
+ // SAFETY: The pointer was allocated using `Box::into_raw()` and is valid
+ // as long as `drop_display()` has not been called. Since `NATIVE_DISPLAY_READY`
+ // was checked, it is safe to assume `ptr` is not currently being deallocated.
+ unsafe { Some(&*ptr) }
}
-fn native_display() -> &'static Mutex {
- NATIVE_DISPLAY
- .get()
- .expect("Backend has not initialized NATIVE_DISPLAY yet.") //|| Mutex::new(Default::default()))
+
+/// Returns a blocking lock on the global display, panicking if uninitialized.
+fn native_display_blocking() -> MutexGuard<'static, native::NativeDisplayData> {
+ native_display()
+ .expect("Global display not initialized")
+ .lock()
+ .expect("Failed to acquire blocking lock on the global display")
+}
+
+/// Returns a non-blocking lock on the global display, panicking if unavailable.
+fn native_display_nonblocking() -> MutexGuard<'static, native::NativeDisplayData> {
+ native_display()
+ .expect("Global display not initialized")
+ .try_lock()
+ .expect("Failed to acquire non-blocking lock on the global display")
+}
+
+/// Drops the global display, ensuring it is safely deallocated and preventing further access.
+fn drop_display() {
+ // Prevent further access before deallocating.
+ NATIVE_DISPLAY_READY.store(false, Ordering::Release);
+ let old = NATIVE_DISPLAY.swap(null_mut(), Ordering::AcqRel);
+ if !old.is_null() {
+ // SAFETY: `swap(null_mut())` ensures that no other thread will access `old`
+ // after this point, so it is safe to drop it without causing a use-after-free.
+ unsafe { drop(Box::from_raw(old)) };
+ }
}
/// Window and associated to window rendering context related functions.
@@ -125,26 +178,26 @@ pub mod window {
/// The current framebuffer size in pixels
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn screen_size() -> (f32, f32) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
(d.screen_width as f32, d.screen_height as f32)
}
/// The dpi scaling factor (window pixels to framebuffer pixels)
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn dpi_scale() -> f32 {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.dpi_scale
}
/// True when high_dpi was requested and actually running in a high-dpi scenario
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn high_dpi() -> bool {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.high_dpi
}
pub fn blocking_event_loop() -> bool {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.blocking_event_loop
}
@@ -156,7 +209,7 @@ pub mod window {
/// happen in the order_quit implmentation) and execution might continue for some time after
/// But the window is going to be inevitably closed at some point.
pub fn order_quit() {
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.quit_ordered = true;
}
@@ -171,7 +224,7 @@ pub mod window {
/// If the event handler callback does nothing, the application will be quit as usual.
/// To prevent this, call the function "cancel_quit()"" from inside the event handler.
pub fn request_quit() {
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.quit_requested = true;
}
@@ -181,7 +234,7 @@ pub mod window {
/// function makes sense is from inside the event handler callback when
/// the "quit_requested_event" event has been received
pub fn cancel_quit() {
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.quit_requested = false;
}
/// Capture mouse cursor to the current window
@@ -191,7 +244,7 @@ pub mod window {
/// so set_cursor_grab(false) on window's focus lost is recommended.
/// TODO: implement window focus events
pub fn set_cursor_grab(grab: bool) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::SetCursorGrab(grab))
.unwrap();
@@ -205,7 +258,7 @@ pub mod window {
pub fn schedule_update() {
#[cfg(not(target_arch = "wasm32"))]
{
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::ScheduleUpdate)
.unwrap();
@@ -219,7 +272,7 @@ pub mod window {
/// Show or hide the mouse cursor
pub fn show_mouse(shown: bool) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::ShowMouse(shown))
.unwrap();
@@ -227,7 +280,7 @@ pub mod window {
/// Set the mouse cursor icon.
pub fn set_mouse_cursor(cursor_icon: CursorIcon) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::SetMouseCursor(cursor_icon))
.unwrap();
@@ -235,7 +288,7 @@ pub mod window {
/// Set the application's window size.
pub fn set_window_size(new_width: u32, new_height: u32) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::SetWindowSize {
new_width,
@@ -245,7 +298,7 @@ pub mod window {
}
pub fn set_window_position(new_x: u32, new_y: u32) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::SetWindowPosition { new_x, new_y })
.unwrap();
@@ -255,12 +308,12 @@ pub mod window {
/// TODO: implement for other platforms
#[cfg(any(target_os = "windows", target_os = "linux"))]
pub fn get_window_position() -> (u32, u32) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.screen_position
}
pub fn set_fullscreen(fullscreen: bool) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::SetFullscreen(fullscreen))
.unwrap();
@@ -268,32 +321,32 @@ pub mod window {
/// Get current OS clipboard value
pub fn clipboard_get() -> Option {
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.clipboard.get()
}
/// Save value to OS clipboard
pub fn clipboard_set(data: &str) {
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.clipboard.set(data)
}
pub fn dropped_file_count() -> usize {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.dropped_files.bytes.len()
}
pub fn dropped_file_bytes(index: usize) -> Option> {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.dropped_files.bytes.get(index).cloned()
}
pub fn dropped_file_path(index: usize) -> Option {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.dropped_files.paths.get(index).cloned()
}
/// Show/hide onscreen keyboard.
/// Only works on Android right now.
pub fn show_keyboard(show: bool) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.native_requests
.send(native::Request::ShowKeyboard(show))
.unwrap();
@@ -301,17 +354,17 @@ pub mod window {
#[cfg(target_vendor = "apple")]
pub fn apple_gfx_api() -> crate::conf::AppleGfxApi {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.gfx_api
}
#[cfg(target_vendor = "apple")]
pub fn apple_view() -> crate::native::apple::frameworks::ObjcId {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.view
}
#[cfg(target_os = "ios")]
pub fn apple_view_ctrl() -> crate::native::apple::frameworks::ObjcId {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
d.view_ctrl
}
}
diff --git a/src/native/android.rs b/src/native/android.rs
index 3148cc68..825fccdd 100644
--- a/src/native/android.rs
+++ b/src/native/android.rs
@@ -198,7 +198,7 @@ impl MainThreadState {
}
{
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = crate::native_display_blocking();
d.screen_width = width as _;
d.screen_height = height as _;
}
diff --git a/src/native/ios.rs b/src/native/ios.rs
index f600430c..478a9f5b 100644
--- a/src/native/ios.rs
+++ b/src/native/ios.rs
@@ -14,7 +14,7 @@ use {
},
NativeDisplayData,
},
- native_display,
+ native_display_blocking,
},
std::{
cell::RefCell,
@@ -143,7 +143,7 @@ pub fn define_glk_or_mtk_view(superclass: &Class) -> *const Class {
let ios_touch: ObjcId = msg_send![enumerator, nextObject];
let mut ios_pos: NSPoint = msg_send![ios_touch, locationInView: this];
- if native_display().lock().unwrap().high_dpi {
+ if native_display_blocking().high_dpi {
ios_pos.x *= 2.;
ios_pos.y *= 2.;
} else {
@@ -317,7 +317,7 @@ pub fn define_glk_or_mtk_view_dlg(superclass: &Class) -> *const Class {
let main_screen: ObjcId = unsafe { msg_send![class!(UIScreen), mainScreen] };
let screen_rect: NSRect = unsafe { msg_send![main_screen, bounds] };
- let high_dpi = native_display().lock().unwrap().high_dpi;
+ let high_dpi = native_display_blocking().high_dpi;
let (screen_width, screen_height) = if high_dpi {
(
@@ -332,11 +332,11 @@ pub fn define_glk_or_mtk_view_dlg(superclass: &Class) -> *const Class {
)
};
- if native_display().lock().unwrap().screen_width != screen_width
- || native_display().lock().unwrap().screen_height != screen_height
+ if native_display_blocking().screen_width != screen_width
+ || native_display_blocking().screen_height != screen_height
{
{
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.screen_width = screen_width;
d.screen_height = screen_height;
}
diff --git a/src/native/linux_wayland.rs b/src/native/linux_wayland.rs
index c82951e0..d6cc6b9e 100644
--- a/src/native/linux_wayland.rs
+++ b/src/native/linux_wayland.rs
@@ -483,7 +483,7 @@ unsafe extern "C" fn xdg_toplevel_handle_configure(
) -> () {
assert!(!data.is_null());
let payload: &mut WaylandPayload = &mut *(data as *mut _);
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = crate::native_display_blocking();
if width != 0 && height != 0 {
let (egl_w, egl_h) = if payload.decorations.is_some() {
diff --git a/src/native/linux_x11.rs b/src/native/linux_x11.rs
index 5ddb9eef..3ffe66b4 100644
--- a/src/native/linux_x11.rs
+++ b/src/native/linux_x11.rs
@@ -135,7 +135,7 @@ impl X11Display {
event_handler.window_minimized_event();
}
22 => {
- let mut d = crate::native_display().try_lock().unwrap();
+ let mut d = crate::native_display_nonblocking();
let left = (*event).xconfigure.x;
let top = (*event).xconfigure.y;
d.screen_position = (left as _, top as _);
@@ -151,7 +151,7 @@ impl X11Display {
}
}
33 => {
- let mut d = crate::native_display().try_lock().unwrap();
+ let mut d = crate::native_display_nonblocking();
if (*event).xclient.message_type == self.libx11.extensions.wm_protocols {
let protocol = (*event).xclient.data.l[0 as libc::c_int as usize] as Atom;
if protocol == self.libx11.extensions.wm_delete_window {
@@ -180,11 +180,11 @@ impl X11Display {
_ => {}
};
- let d = crate::native_display().try_lock().unwrap();
+ let d = crate::native_display_nonblocking();
if d.quit_requested && !d.quit_ordered {
drop(d);
event_handler.quit_requested_event();
- let mut d = crate::native_display().try_lock().unwrap();
+ let mut d = crate::native_display_nonblocking();
if d.quit_requested {
d.quit_ordered = true
}
@@ -425,7 +425,7 @@ where
let mut event_handler = (f.take().unwrap())();
- while !crate::native_display().try_lock().unwrap().quit_ordered {
+ while !crate::native_display_nonblocking().quit_ordered {
while let Ok(request) = rx.try_recv() {
display.process_request(request);
}
@@ -537,7 +537,7 @@ where
let mut event_handler = (f.take().unwrap())();
- while !crate::native_display().try_lock().unwrap().quit_ordered {
+ while !crate::native_display_nonblocking().quit_ordered {
while let Ok(request) = rx.try_recv() {
display.process_request(request);
}
diff --git a/src/native/macos.rs b/src/native/macos.rs
index c5aebef8..6cf40ff5 100644
--- a/src/native/macos.rs
+++ b/src/native/macos.rs
@@ -10,7 +10,7 @@ use {
apple::{apple_util::*, frameworks::*},
gl, NativeDisplayData, Request,
},
- native_display, CursorIcon,
+ native_display_blocking, CursorIcon,
},
std::{
collections::HashMap,
@@ -135,7 +135,7 @@ impl MacosDisplay {
impl MacosDisplay {
fn transform_mouse_point(&self, point: &NSPoint) -> (f32, f32) {
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
let new_x = point.x as f32 * d.dpi_scale;
let new_y = d.screen_height as f32 - (point.y as f32 * d.dpi_scale) - 1.;
@@ -155,7 +155,7 @@ impl MacosDisplay {
}
unsafe fn update_dimensions(&mut self) -> Option<(i32, i32)> {
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
unsafe {
if self.gl_context != nil {
msg_send_![self.gl_context, update];
@@ -270,20 +270,20 @@ pub fn define_cocoa_window_delegate() -> *const Class {
}
// only give user-code a chance to intervene when sapp_quit() wasn't already called
- if !native_display().lock().unwrap().quit_ordered {
+ if !native_display_blocking().quit_ordered {
// if window should be closed and event handling is enabled, give user code
// a chance to intervene via sapp_cancel_quit()
- native_display().lock().unwrap().quit_requested = true;
+ native_display_blocking().quit_requested = true;
if let Some(event_handler) = payload.context() {
event_handler.quit_requested_event();
}
// user code hasn't intervened, quit the app
- if native_display().lock().unwrap().quit_requested {
- native_display().lock().unwrap().quit_ordered = true;
+ if native_display_blocking().quit_requested {
+ native_display_blocking().quit_ordered = true;
}
}
- if native_display().lock().unwrap().quit_ordered {
+ if native_display_blocking().quit_ordered {
return YES;
} else {
return NO;
@@ -965,7 +965,7 @@ unsafe fn perform_redraw(
}
{
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
if d.quit_requested || d.quit_ordered {
drop(d);
let () = msg_send![display.window, performClose: nil];
@@ -1092,7 +1092,7 @@ where
AppleGfxApi::Metal => create_metal_view(&mut display, conf.sample_count, conf.high_dpi),
};
{
- let mut d = native_display().lock().unwrap();
+ let mut d = native_display_blocking();
d.view = view;
}
(*view).set_ivar("display_ptr", &mut display as *mut _ as *mut c_void);
@@ -1150,13 +1150,13 @@ where
let distant_future: ObjcId = msg_send![class!(NSDate), distantFuture];
let distant_past: ObjcId = msg_send![class!(NSDate), distantPast];
let mut done = false;
- while !(done || crate::native_display().lock().unwrap().quit_ordered) {
+ while !(done || native_display_blocking().quit_ordered) {
while let Ok(request) = display.native_requests.try_recv() {
display.process_request(request);
}
{
- let d = native_display().lock().unwrap();
+ let d = native_display_blocking();
if d.quit_requested || d.quit_ordered {
done = true;
}
diff --git a/src/native/wasm.rs b/src/native/wasm.rs
index 3ca4be42..94de803e 100644
--- a/src/native/wasm.rs
+++ b/src/native/wasm.rs
@@ -310,7 +310,7 @@ pub extern "C" fn key_up(key: u32, modifiers: u32) {
#[no_mangle]
pub extern "C" fn resize(width: i32, height: i32) {
{
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = crate::native_display_blocking();
d.screen_width = width as _;
d.screen_height = height as _;
}
@@ -340,7 +340,7 @@ pub extern "C" fn focus(has_focus: bool) {
#[no_mangle]
pub extern "C" fn on_files_dropped_start() {
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = crate::native_display_blocking();
d.dropped_files = Default::default();
}
@@ -356,7 +356,7 @@ pub extern "C" fn on_file_dropped(
bytes: *mut u8,
bytes_len: usize,
) {
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = crate::native_display_blocking();
let path = PathBuf::from(unsafe { String::from_raw_parts(path, path_len, path_len) });
let bytes = unsafe { Vec::from_raw_parts(bytes, bytes_len, bytes_len) };
diff --git a/src/native/windows.rs b/src/native/windows.rs
index a200442d..9afcc9f4 100644
--- a/src/native/windows.rs
+++ b/src/native/windows.rs
@@ -4,7 +4,7 @@ use crate::{
conf::{Conf, Icon},
event::{KeyMods, MouseButton},
native::{NativeDisplayData, Request},
- CursorIcon, EventHandler,
+ native_display_blocking, CursorIcon, EventHandler,
};
use winapi::{
@@ -178,7 +178,7 @@ impl WindowsDisplay {
);
} else {
let (w, h) = {
- let d = crate::native_display().lock().unwrap();
+ let d = native_display_blocking();
(d.screen_width, d.screen_height)
};
@@ -287,7 +287,7 @@ unsafe extern "system" fn win32_wndproc(
match umsg {
WM_CLOSE => {
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = native_display_blocking();
// only give user a chance to intervene when sapp_quit() wasn't already called
if !d.quit_ordered {
// if window should be closed and event handling is enabled, give user code
@@ -297,7 +297,7 @@ unsafe extern "system" fn win32_wndproc(
// the prevent event may require access to native_display
event_handler.quit_requested_event();
// Re-acquire native_display
- d = crate::native_display().lock().unwrap();
+ d = native_display_blocking();
// if user code hasn't intervened, quit the app
if d.quit_requested {
d.quit_ordered = true;
@@ -434,7 +434,7 @@ unsafe extern "system" fn win32_wndproc(
// convert from normalised absolute coordinates
if (data.data.mouse().usFlags & MOUSE_MOVE_ABSOLUTE) == MOUSE_MOVE_ABSOLUTE {
let (width, height) = {
- let d = crate::native_display().lock().unwrap();
+ let d = native_display_blocking();
(d.screen_width as f32, d.screen_height as f32)
};
@@ -499,7 +499,7 @@ unsafe extern "system" fn win32_wndproc(
SwapBuffers(payload.dc);
if payload.update_dimensions(hwnd) {
- let d = crate::native_display().lock().unwrap();
+ let d = native_display_blocking();
let width = d.screen_width as f32;
let height = d.screen_height as f32;
drop(d);
@@ -519,7 +519,7 @@ unsafe extern "system" fn win32_wndproc(
let mut path: [u16; MAX_PATH] = std::mem::uninitialized();
let num_drops = DragQueryFileW(hdrop, u32::MAX, std::ptr::null_mut(), 0);
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = native_display_blocking();
for i in 0..num_drops {
let path_len =
DragQueryFileW(hdrop, i, path.as_mut_ptr(), MAX_PATH as u32) as usize;
@@ -773,7 +773,7 @@ impl WindowsDisplay {
/// and window position from the window's rect.
/// returns true if size or position has changed
unsafe fn update_dimensions(&mut self, hwnd: HWND) -> bool {
- let mut d = crate::native_display().lock().unwrap();
+ let mut d = native_display_blocking();
let mut rect: RECT = std::mem::zeroed();
// Get the outer rectangle of the window in screen coordinates
@@ -942,7 +942,7 @@ where
SetWindowLong(wnd, GWLP_USERDATA, &mut display as *mut _ as isize);
let mut done = false;
- while !(done || crate::native_display().lock().unwrap().quit_ordered) {
+ while !(done || native_display_blocking().quit_ordered) {
while let Ok(request) = rx.try_recv() {
display.process_request(request);
}
@@ -975,7 +975,7 @@ where
}
if display.update_dimensions(wnd) {
- let d = crate::native_display().lock().unwrap();
+ let d = native_display_blocking();
let width = d.screen_width as f32;
let height = d.screen_height as f32;
drop(d);
@@ -985,7 +985,7 @@ where
.unwrap()
.resize_event(width, height);
}
- if crate::native_display().lock().unwrap().quit_requested {
+ if native_display_blocking().quit_requested {
PostMessageW(display.wnd, WM_CLOSE, 0, 0);
}
}