Skip to content

Commit 3c7a52f

Browse files
committed
Fixed deadlocks
1 parent b74c7fe commit 3c7a52f

File tree

7 files changed

+157
-75
lines changed

7 files changed

+157
-75
lines changed

src/event.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub enum StartCause {
8080
Poll,
8181

8282
/// Sent once, immediately after `run` is called. Indicates that the loop was just initialized.
83-
Init
83+
Init,
8484
}
8585

8686
/// Describes an event from a `Window`.

src/platform/macos.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl WindowBuilderExtMacOS for WindowBuilder {
138138
}
139139
}
140140

141-
/// Additional methods on `MonitorHandle` that are specific to MacOS.
141+
/// Additional methods on `MonitorHandle` that are specific to macOS.
142142
pub trait MonitorHandleExtMacOS {
143143
/// Returns the identifier of the monitor for Cocoa.
144144
fn native_id(&self) -> u32;

src/platform_impl/macos/event_loop.rs

+40-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
2-
collections::VecDeque, hint::unreachable_unchecked,
3-
marker::PhantomData, os::raw::*, process::exit, sync::{Arc, Mutex, Weak},
2+
collections::VecDeque, hint::unreachable_unchecked, marker::PhantomData,
3+
mem, os::raw::*, process::exit, sync::{Arc, Mutex, Weak},
44
};
55

66
use cocoa::{
@@ -15,7 +15,7 @@ use cocoa::{
1515
use {
1616
event::{
1717
self, DeviceEvent, ElementState, Event, KeyboardInput,
18-
ModifiersState, TouchPhase, WindowEvent,
18+
ModifiersState, StartCause, TouchPhase, WindowEvent,
1919
},
2020
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW},
2121
window,
@@ -59,10 +59,8 @@ impl PendingEvents {
5959
self.pending.append(&mut events);
6060
}
6161

62-
fn process_events<F: FnMut(Event<T>), T: 'static>(&mut self, mut callback: F) {
63-
for event in self.pending.drain(0..) {
64-
callback(event.userify());
65-
}
62+
fn take(&mut self) -> VecDeque<Event<Never>> {
63+
mem::replace(&mut self.pending, Default::default())
6664
}
6765
}
6866

@@ -148,17 +146,27 @@ impl<T> EventLoop<T> {
148146
}
149147

150148
let mut control_flow = Default::default();
149+
let mut cause = StartCause::Init;
151150

152151
loop {
153-
self.elw_target.inner.pending_events
154-
.lock()
155-
.unwrap()
156-
.process_events(|event| {
157-
callback(event, self.window_target(), &mut control_flow);
158-
});
152+
callback(Event::NewEvents(cause), self.window_target(), &mut control_flow);
159153

160-
if let ControlFlow::Exit = control_flow {
161-
exit(0);
154+
{
155+
trace!("Locked pending events in `run`");
156+
let mut pending = self.elw_target
157+
.inner
158+
.pending_events
159+
.lock()
160+
.unwrap()
161+
.take();
162+
trace!("Unlocked pending events in `run`");
163+
for event in pending.drain(0..) {
164+
callback(
165+
event.userify(),
166+
self.window_target(),
167+
&mut control_flow,
168+
);
169+
}
162170
}
163171

164172
let maybe_event = unsafe {
@@ -183,10 +191,16 @@ impl<T> EventLoop<T> {
183191

184192
if let Some(event) = maybe_event {
185193
callback(event.userify(), self.window_target(), &mut control_flow);
186-
if let ControlFlow::Exit = control_flow {
187-
exit(0);
188-
}
189194
}
195+
196+
callback(Event::EventsCleared, self.window_target(), &mut control_flow);
197+
198+
if let ControlFlow::Exit = control_flow {
199+
callback(Event::LoopDestroyed, self.window_target(), &mut control_flow);
200+
exit(0);
201+
}
202+
203+
cause = StartCause::Poll;
190204
}
191205
}
192206

@@ -304,10 +318,12 @@ impl<T> EventLoop<T> {
304318
}
305319

306320
let event = events.pop_front();
321+
trace!("Locked pending events in `translate_event`");
307322
self.elw_target.inner.pending_events
308323
.lock()
309324
.unwrap()
310325
.queue_events(events);
326+
trace!("Unlocked pending events in `translate_event`");
311327
event
312328
},
313329

@@ -336,10 +352,12 @@ impl<T> EventLoop<T> {
336352
modifiers: event_mods(ns_event),
337353
};
338354
let event = Event::WindowEvent { window_id: window::WindowId(window.id()), event: window_event };
355+
trace!("Locked pending events in `translate_event`");
339356
self.elw_target.inner.pending_events
340357
.lock()
341358
.unwrap()
342359
.queue_event(event);
360+
trace!("Unlocked pending events in `translate_event`");
343361
Some(into_event(WindowEvent::CursorEntered { device_id: DEVICE_ID }))
344362
},
345363
appkit::NSMouseExited => { Some(into_event(WindowEvent::CursorLeft { device_id: DEVICE_ID })) },
@@ -379,10 +397,12 @@ impl<T> EventLoop<T> {
379397
}
380398

381399
let event = events.pop_front();
400+
trace!("Locked pending events in `translate_event`");
382401
self.elw_target.inner.pending_events
383402
.lock()
384403
.unwrap()
385404
.queue_events(events);
405+
trace!("Unlocked pending events in `translate_event`");
386406
event
387407
},
388408

@@ -410,6 +430,7 @@ impl<T> EventLoop<T> {
410430
NSEventPhase::NSEventPhaseEnded => TouchPhase::Ended,
411431
_ => TouchPhase::Moved,
412432
};
433+
trace!("Locked pending events in `translate_event`");
413434
self.elw_target.inner.pending_events.lock().unwrap().queue_event(Event::DeviceEvent {
414435
device_id: DEVICE_ID,
415436
event: DeviceEvent::MouseWheel {
@@ -426,6 +447,7 @@ impl<T> EventLoop<T> {
426447
},
427448
}
428449
});
450+
trace!("Unlocked pending events in `translate_event`");
429451
let window_event = WindowEvent::MouseWheel {
430452
device_id: DEVICE_ID,
431453
delta,

src/platform_impl/macos/util.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ pub fn bottom_left_to_top_left(rect: NSRect) -> f64 {
8989
CGDisplay::main().pixels_high() as f64 - (rect.origin.y + rect.size.height)
9090
}
9191

92-
pub unsafe fn set_style_mask(window: id, view: id, mask: NSWindowStyleMask) {
92+
pub unsafe fn set_style_mask(nswindow: id, nsview: id, mask: NSWindowStyleMask) {
93+
trace!("`set_style_mask` {:?} {:?} {:?}", nswindow, nsview, mask);
9394
use cocoa::appkit::NSWindow;
94-
window.setStyleMask_(mask);
95+
nswindow.setStyleMask_(mask);
9596
// If we don't do this, key handling will break. Therefore, never call `setStyleMask` directly!
96-
window.makeFirstResponder_(view);
97+
nswindow.makeFirstResponder_(nsview);
9798
}
9899

99100
pub unsafe fn create_input_context(view: id) -> IdRef {

src/platform_impl/macos/view.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,15 @@ extern fn init_with_winit(this: &Object, _sel: Sel, state: *mut c_void) -> id {
216216
}
217217

218218
extern fn has_marked_text(this: &Object, _sel: Sel) -> BOOL {
219-
debug!("hasMarkedText");
219+
trace!("Triggered `hasMarkedText`");
220220
unsafe {
221221
let marked_text: id = *this.get_ivar("markedText");
222222
(marked_text.length() > 0) as i8
223223
}
224224
}
225225

226226
extern fn marked_range(this: &Object, _sel: Sel) -> NSRange {
227-
debug!("markedRange");
227+
trace!("Triggered `markedRange`");
228228
unsafe {
229229
let marked_text: id = *this.get_ivar("markedText");
230230
let length = marked_text.length();
@@ -237,7 +237,7 @@ extern fn marked_range(this: &Object, _sel: Sel) -> NSRange {
237237
}
238238

239239
extern fn selected_range(_this: &Object, _sel: Sel) -> NSRange {
240-
debug!("selectedRange");
240+
trace!("Triggered `selectedRange`");
241241
util::EMPTY_RANGE
242242
}
243243

@@ -248,7 +248,7 @@ extern fn set_marked_text(
248248
_selected_range: NSRange,
249249
_replacement_range: NSRange,
250250
) {
251-
debug!("setMarkedText");
251+
trace!("Triggered `setMarkedText`");
252252
unsafe {
253253
let marked_text_ref: &mut id = this.get_mut_ivar("markedText");
254254
let _: () = msg_send![(*marked_text_ref), release];
@@ -264,7 +264,7 @@ extern fn set_marked_text(
264264
}
265265

266266
extern fn unmark_text(this: &Object, _sel: Sel) {
267-
debug!("unmarkText");
267+
trace!("Triggered `unmarkText`");
268268
unsafe {
269269
let marked_text: id = *this.get_ivar("markedText");
270270
let mutable_string = marked_text.mutableString();
@@ -275,7 +275,7 @@ extern fn unmark_text(this: &Object, _sel: Sel) {
275275
}
276276

277277
extern fn valid_attributes_for_marked_text(_this: &Object, _sel: Sel) -> id {
278-
debug!("validAttributesForMarkedText");
278+
trace!("Triggered `validAttributesForMarkedText`");
279279
unsafe { msg_send![class!(NSArray), array] }
280280
}
281281

@@ -285,12 +285,12 @@ extern fn attributed_substring_for_proposed_range(
285285
_range: NSRange,
286286
_actual_range: *mut c_void, // *mut NSRange
287287
) -> id {
288-
debug!("attributedSubstringForProposedRange");
288+
trace!("Triggered `attributedSubstringForProposedRange`");
289289
nil
290290
}
291291

292292
extern fn character_index_for_point(_this: &Object, _sel: Sel, _point: NSPoint) -> NSUInteger {
293-
debug!("characterIndexForPoint");
293+
trace!("Triggered `characterIndexForPoint`");
294294
0
295295
}
296296

@@ -300,7 +300,7 @@ extern fn first_rect_for_character_range(
300300
_range: NSRange,
301301
_actual_range: *mut c_void, // *mut NSRange
302302
) -> NSRect {
303-
debug!("firstRectForCharacterRange");
303+
trace!("Triggered `firstRectForCharacterRange`");
304304
unsafe {
305305
let state_ptr: *mut c_void = *this.get_ivar("winitState");
306306
let state = &mut *(state_ptr as *mut ViewState);
@@ -322,7 +322,7 @@ extern fn first_rect_for_character_range(
322322
}
323323

324324
extern fn insert_text(this: &Object, _sel: Sel, string: id, _replacement_range: NSRange) {
325-
debug!("insertText");
325+
trace!("Triggered `insertText`");
326326
unsafe {
327327
let state_ptr: *mut c_void = *this.get_ivar("winitState");
328328
let state = &mut *(state_ptr as *mut ViewState);
@@ -359,7 +359,7 @@ extern fn insert_text(this: &Object, _sel: Sel, string: id, _replacement_range:
359359
}
360360

361361
extern fn do_command_by_selector(this: &Object, _sel: Sel, command: Sel) {
362-
debug!("doCommandBySelector");
362+
trace!("Triggered `doCommandBySelector`");
363363
// Basically, we're sent this message whenever a keyboard event that doesn't generate a "human readable" character
364364
// happens, i.e. newlines, tabs, and Ctrl+C.
365365
unsafe {
@@ -404,7 +404,7 @@ fn get_characters(event: id) -> Option<String> {
404404
}
405405

406406
extern fn key_down(this: &Object, _sel: Sel, event: id) {
407-
debug!("keyDown");
407+
trace!("Triggered `keyDown`");
408408
unsafe {
409409
let state_ptr: *mut c_void = *this.get_ivar("winitState");
410410
let state = &mut *(state_ptr as *mut ViewState);
@@ -440,7 +440,7 @@ extern fn key_down(this: &Object, _sel: Sel, event: id) {
440440
let slice = slice::from_raw_parts(
441441
characters.UTF8String() as *const c_uchar,
442442
characters.len(),
443-
);
443+
);
444444
let string = str::from_utf8_unchecked(slice);
445445

446446
state.raw_characters = {
@@ -475,7 +475,7 @@ extern fn key_down(this: &Object, _sel: Sel, event: id) {
475475
}
476476

477477
extern fn key_up(this: &Object, _sel: Sel, event: id) {
478-
debug!("keyUp");
478+
trace!("Triggered `keyUp`");
479479
unsafe {
480480
let state_ptr: *mut c_void = *this.get_ivar("winitState");
481481
let state = &mut *(state_ptr as *mut ViewState);

0 commit comments

Comments
 (0)