Skip to content

Commit 01d45a8

Browse files
committed
Fixing Gooey compilation on MacOS
After trying to run Gooey again on my Mac for the first time in a few weeks, I found that I ran into the Condvar issue again. Rather than pasting AssertUnwindSafe in those files, I've both reported the discrepency in unwind safety (rust-lang/rust#118009) and moved the workaround into a type that only uses AssertUnwindsafe when compiling for Apple.
1 parent c39f8f3 commit 01d45a8

File tree

4 files changed

+43
-16
lines changed

4 files changed

+43
-16
lines changed

src/animation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use std::fmt::{Debug, Display};
4444
use std::ops::{ControlFlow, Deref, Div, Mul};
4545
use std::panic::{RefUnwindSafe, UnwindSafe};
4646
use std::str::FromStr;
47-
use std::sync::{Arc, Condvar, Mutex, MutexGuard, OnceLock};
47+
use std::sync::{Arc, Mutex, MutexGuard, OnceLock};
4848
use std::thread;
4949
use std::time::{Duration, Instant};
5050

@@ -57,11 +57,11 @@ use kludgine::Color;
5757

5858
use crate::animation::easings::Linear;
5959
use crate::styles::{Component, RequireInvalidation};
60-
use crate::utils::IgnorePoison;
60+
use crate::utils::{IgnorePoison, UnwindsafeCondvar};
6161
use crate::value::Dynamic;
6262

6363
static ANIMATIONS: Mutex<Animating> = Mutex::new(Animating::new());
64-
static NEW_ANIMATIONS: Condvar = Condvar::new();
64+
static NEW_ANIMATIONS: UnwindsafeCondvar = UnwindsafeCondvar::new();
6565

6666
fn thread_state() -> MutexGuard<'static, Animating> {
6767
static THREAD: OnceLock<()> = OnceLock::new();

src/tick.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::collections::HashSet;
22
use std::sync::atomic::{AtomicUsize, Ordering};
3-
use std::sync::{Arc, Condvar, Mutex, MutexGuard};
3+
use std::sync::{Arc, Mutex, MutexGuard};
44
use std::time::{Duration, Instant};
55

66
use kludgine::app::winit::event::KeyEvent;
77
use kludgine::app::winit::keyboard::Key;
88

99
use crate::context::WidgetContext;
10-
use crate::utils::IgnorePoison;
10+
use crate::utils::{IgnorePoison, UnwindsafeCondvar};
1111
use crate::value::Dynamic;
1212
use crate::widget::{EventHandling, HANDLED, IGNORED};
1313

@@ -65,7 +65,7 @@ impl Tick {
6565
input: InputState::default(),
6666
}),
6767
period: tick_every,
68-
sync: Condvar::new(),
68+
sync: UnwindsafeCondvar::new(),
6969
rendered_frame: AtomicUsize::new(0),
7070
tick_number: Dynamic::default(),
7171
});
@@ -117,7 +117,7 @@ pub struct InputState {
117117
struct TickData {
118118
state: Mutex<TickState>,
119119
period: Duration,
120-
sync: Condvar,
120+
sync: UnwindsafeCondvar,
121121
rendered_frame: AtomicUsize,
122122
tick_number: Dynamic<u64>,
123123
}

src/utils.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,40 @@
11
use std::ops::Deref;
2-
use std::sync::{OnceLock, PoisonError};
2+
use std::sync::{Condvar, OnceLock, PoisonError};
33

44
use kludgine::app::winit::event::Modifiers;
55
use kludgine::app::winit::keyboard::ModifiersState;
66

7+
/// This [`Condvar`] is a wrapper that on Mac OS/iOS asserts unwind safety. On
8+
/// all other platforms, this is a transparent wrapper around `Condvar`. See
9+
/// <https://github.com/rust-lang/rust/issues/118009> for more information.
10+
#[derive(Debug, Default)]
11+
pub struct UnwindsafeCondvar(
12+
#[cfg(any(target_os = "ios", target_os = "macos"))] std::panic::AssertUnwindSafe<Condvar>,
13+
#[cfg(not(any(target_os = "ios", target_os = "macos")))] Condvar,
14+
);
15+
16+
impl Deref for UnwindsafeCondvar {
17+
type Target = Condvar;
18+
19+
fn deref(&self) -> &Self::Target {
20+
&self.0
21+
}
22+
}
23+
24+
impl UnwindsafeCondvar {
25+
pub const fn new() -> Self {
26+
#[cfg(any(target_os = "ios", target_os = "macos"))]
27+
{
28+
Self(AssertUnwindSafe(Condvar::new()))
29+
}
30+
31+
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
32+
{
33+
Self(Condvar::new())
34+
}
35+
}
36+
}
37+
738
/// Invokes the provided macro with a pattern that can be matched using this
839
/// `macro_rules!` expression: `$($type:ident $field:tt $var:ident),+`, where `$type` is an
940
/// identifier to use for the generic parameter and `$field` is the field index

src/value.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use std::cell::Cell;
44
use std::fmt::{Debug, Display};
55
use std::future::Future;
66
use std::ops::{Deref, DerefMut};
7-
use std::panic::AssertUnwindSafe;
87
use std::str::FromStr;
9-
use std::sync::{Arc, Condvar, Mutex, MutexGuard, TryLockError};
8+
use std::sync::{Arc, Mutex, MutexGuard, TryLockError};
109
use std::task::{Poll, Waker};
1110
use std::thread::ThreadId;
1211

@@ -15,7 +14,7 @@ use intentional::Assert;
1514

1615
use crate::animation::{DynamicTransition, LinearInterpolate};
1716
use crate::context::{WidgetContext, WindowHandle};
18-
use crate::utils::{IgnorePoison, WithClone};
17+
use crate::utils::{IgnorePoison, UnwindsafeCondvar, WithClone};
1918
use crate::widget::{WidgetId, WidgetInstance};
2019
use crate::widgets::Switcher;
2120

@@ -40,7 +39,7 @@ impl<T> Dynamic<T> {
4039
widgets: AHashSet::new(),
4140
}),
4241
during_callback_state: Mutex::default(),
43-
sync: AssertUnwindSafe(Condvar::new()),
42+
sync: UnwindsafeCondvar::default(),
4443
}))
4544
}
4645

@@ -553,10 +552,7 @@ struct LockState {
553552
struct DynamicData<T> {
554553
state: Mutex<State<T>>,
555554
during_callback_state: Mutex<Option<LockState>>,
556-
557-
// The AssertUnwindSafe is only needed on Mac. For some reason on
558-
// Mac OS, Condvar isn't RefUnwindSafe.
559-
sync: AssertUnwindSafe<Condvar>,
555+
sync: UnwindsafeCondvar,
560556
}
561557

562558
impl<T> DynamicData<T> {

0 commit comments

Comments
 (0)