Skip to content

Commit b0f443b

Browse files
committed
fix race condition on relinquish focus v result return for dynamic and progress modals
There's a race condition between the return of a blocking scalar and when focus is relinquished. This causes chained graphics operations to get dropped sometimes. Move the return result to after the focus switch; this allows us to elimate some dead waits.
1 parent 5a0e3e5 commit b0f443b

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

services/modals/src/lib.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,15 @@ impl Modals {
334334
Ok(())
335335
}
336336

337-
/// close the progress bar, regardless of the current state
337+
/// Close the progress bar, regardless of the current state
338+
/// This is a blocking call, because you want the GAM to revert focus back to your context before you
339+
/// continue with any drawing operations. Otherwise, they could be missed as the modal is still covering
340+
/// your window.
338341
pub fn finish_progress(&self) -> Result<(), xous::Error> {
339342
self.lock();
340343
send_message(
341344
self.conn,
342-
Message::new_scalar(
345+
Message::new_blocking_scalar(
343346
Opcode::StopProgress.to_usize().unwrap(),
344347
self.token[0] as usize,
345348
self.token[1] as usize,

services/modals/src/main.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -331,15 +331,15 @@ fn wrapped_main() -> ! {
331331
)
332332
.expect("couldn't initiate UX op");
333333
}
334-
Some(Opcode::StopProgress) => msg_scalar_unpack!(msg, t0, t1, t2, t3, {
334+
Some(Opcode::StopProgress) => msg_blocking_scalar_unpack!(msg, t0, t1, t2, t3, {
335335
let token = [t0 as u32, t1 as u32, t2 as u32, t3 as u32];
336336
if token != token_lock.unwrap_or(default_nonce) {
337337
log::warn!("Attempt to access modals without a mutex lock. Ignoring.");
338338
continue;
339339
}
340340
send_message(
341341
renderer_cid,
342-
Message::new_scalar(Opcode::FinishProgress.to_usize().unwrap(), 0, 0, 0, 0),
342+
Message::new_scalar(Opcode::FinishProgress.to_usize().unwrap(), msg.sender as usize, 0, 0, 0),
343343
)
344344
.expect("couldn't update progress bar");
345345
}),
@@ -401,10 +401,6 @@ fn wrapped_main() -> ! {
401401
log::warn!("Attempt to access modals without a mutex lock. Ignoring.");
402402
continue;
403403
}
404-
if let Some(sender) = dynamic_notification_listener.take() {
405-
// unblock the listener with no key hit response
406-
xous::return_scalar2(sender, 0, 0,).unwrap();
407-
}
408404
send_message(
409405
renderer_cid,
410406
Message::new_scalar(
@@ -700,9 +696,11 @@ fn wrapped_main() -> ! {
700696
}
701697
}
702698
}
703-
Some(Opcode::FinishProgress) => {
699+
Some(Opcode::FinishProgress) => msg_scalar_unpack!(msg, caller, _, _, _, {
704700
renderer_modal.gam.relinquish_focus().unwrap();
705701
op = RendererState::None;
702+
// unblock the caller, which was forwarded on as the first argument
703+
xous::return_scalar(caller as Sender, 0).ok();
706704
token_lock = next_lock(&mut work_queue);
707705
/*
708706
if work_queue.len() > 0 {
@@ -712,7 +710,7 @@ fn wrapped_main() -> ! {
712710
} else {
713711
token_lock = None;
714712
}*/
715-
}
713+
}),
716714
Some(Opcode::DoUpdateDynamicNotification) => match op {
717715
RendererState::RunDynamicNotification(config) => {
718716
//log::set_max_level(log::LevelFilter::Trace);
@@ -747,6 +745,10 @@ fn wrapped_main() -> ! {
747745
Some(Opcode::DoCloseDynamicNotification) => {
748746
renderer_modal.gam.relinquish_focus().unwrap();
749747
op = RendererState::None;
748+
if let Some(sender) = dynamic_notification_listener.take() {
749+
// unblock the listener with no key hit response
750+
xous::return_scalar2(sender, 0, 0,).unwrap();
751+
}
750752
token_lock = next_lock(&mut work_queue);
751753
},
752754
Some(Opcode::HandleDynamicNotificationKeyhit) => msg_scalar_unpack!(msg, k, _, _, _, {

services/shellchat/src/main.rs

-1
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ fn wrapped_main() -> ! {
457457
}
458458
}
459459
}
460-
tt.sleep_ms(100).ok(); // this allows the shellchat context to foreground before calling the redraw
461460
xous::send_message(main_conn,
462461
xous::Message::new_scalar(ShellOpcode::Redraw.to_usize().unwrap(), 0, 0, 0, 0)
463462
).ok();

0 commit comments

Comments
 (0)