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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! Hot-reload handle: atomic snapshot swap of a compiled [`Graph`] (Phase C,
//! ROADMAP §5 strategy B).
//!
//! Gated behind the `distributed` feature (which brings in `arc-swap`).
//!
//! The control thread builds and compiles a NEW [`Graph`], then calls
//! [`RtHandle::install`] to atomically publish it. The RT thread calls
//! [`RtHandle::process_cycle`], which performs a wait-free load of the current
//! graph and runs one cycle. The old graph stays alive (via its `Arc`) until no
//! RT cycle is using it, then is dropped — so hot-reload is **lossless and
//! pause-free**.
//!
//! # Real-time safety
//!
//! `process_cycle` performs only a wait-free [`arc_swap::ArcSwap::load`] (no
//! allocation, no lock, no syscall) followed by the already-alloc-free
//! [`Graph::process_cycle`]. The single-RT-thread invariant on
//! [`crate::GraphScratch`] still holds: the RT thread is the sole mutator of the
//! loaded graph's scratch.
use Arc;
use ArcSwap;
use crate::;
use ProcessContext;
/// A real-time handle to a [`Graph`] that can be atomically swapped without
/// stopping the RT thread.
///
/// Wrap a compiled [`Graph`] in an `RtHandle`; the RT thread drives cycles via
/// [`RtHandle::process_cycle`], and the control thread publishes replacements
/// via [`RtHandle::install`].
///
/// # Example
///
/// ```no_run
/// # use audio_graph_bsd::{Graph, GraphConfig, RtHandle};
/// # use audio_core_bsd::ProcessContext;
/// # let compiled_graph: Graph = { /* ...build + compile... */ Graph::new() };
/// let handle = RtHandle::new(compiled_graph);
///
/// // RT thread:
/// let mut ctx = ProcessContext::new(256, 0, 48_000);
/// handle.process_cycle(&mut ctx).unwrap();
///
/// // Control thread — publish a freshly-built graph without stopping RT:
/// let new_graph: Graph = { /* ...rebuild + recompile... */ Graph::new() };
/// handle.install(new_graph);
/// ```