1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Host wake-up bridge — the C callback the iOS / Android shell
//! registers so the runtime can ask the host to schedule another
//! `whisker_tick`.
//!
//! Lives outside [`view`] / [`reactive`] because both crates need it:
//! - [`crate::reactive::scheduler`] calls [`wake_runtime`] on the
//! empty→non-empty edge of the pending queue so the host wakes
//! up to drain effects.
//! - [`crate::whisker_dev_runtime`] (Tier 1 hot-reload receiver)
//! calls [`wake_runtime`] from its WebSocket thread after parking
//! a patch, so the host runs another tick that picks the patch
//! up.
//!
//! Pre-Phase-6.5a this lived in `signal.rs` alongside the old
//! `Signal<T>` API. With that gone it's a standalone module.
use c_void;
use Mutex;
/// "Wake the host" callback. The host registers one of these during
/// init via [`set_request_frame_callback`]; whenever the runtime
/// transitions from idle to "we have pending work", it fires the
/// callback so the host can resume its render loop (e.g. unpause a
/// `CADisplayLink`).
///
/// Stored as a raw fn pointer + opaque `user_data` rather than a
/// boxed closure so the C ABI can pass it through unchanged.
/// SAFETY: `user_data` is an opaque host pointer. The host promises
/// it remains valid for the lifetime of the dev session and is safe
/// to call from any thread (the registered callbacks on Android /
/// iOS just post a "wake" message onto the runtime thread).
unsafe
unsafe
/// Cross-thread mirror of the registered callback. Stored globally
/// so threads other than the TASM thread (e.g. the WebSocket
/// receiver in `whisker-dev-runtime`) can wake the runtime via
/// [`wake_runtime`] without needing thread-local access. The TASM
/// thread also writes through here, since there's only one slot
/// and locking is cheap on the rare path that uses it.
static REMOTE_WAKE: = new;
/// Register the host's wake-up callback. Pass `None` to clear.
///
/// In production this is called once during
/// `whisker-driver::bootstrap::run` and never again.
/// Fire the registered wake callback, if any. Safe to call from any
/// thread — the host's callback contract is "any-thread, posts a
/// message to the TASM thread". No-op if no callback is registered
/// (signal writes during init may happen before bootstrap has wired
/// anything up).
/// (Test only) clear the registered callback.