Skip to content

Commit ddf5e24

Browse files
authored
Merge pull request #312 from orottier/feature/controller-atomics
Controller & Scheduler: use single Arc instead of 1 per field
2 parents 7632594 + d1b2208 commit ddf5e24

File tree

1 file changed

+52
-31
lines changed

1 file changed

+52
-31
lines changed

src/control.rs

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,49 @@ use crate::AtomicF64;
88
/// Helper struct to start and stop audio streams
99
#[derive(Clone, Debug)]
1010
pub(crate) struct Scheduler {
11-
start: Arc<AtomicF64>,
12-
stop: Arc<AtomicF64>,
11+
inner: Arc<SchedulerInner>,
1312
}
1413

14+
#[derive(Debug)]
15+
struct SchedulerInner {
16+
start: AtomicF64,
17+
stop: AtomicF64,
18+
}
19+
20+
// Uses the canonical ordering for handover of values, i.e. `Acquire` on load and `Release` on
21+
// store.
1522
impl Scheduler {
1623
/// Create a new Scheduler. Initial playback state will be: inactive.
1724
pub fn new() -> Self {
25+
let inner = SchedulerInner {
26+
start: AtomicF64::new(f64::MAX),
27+
stop: AtomicF64::new(f64::MAX),
28+
};
1829
Self {
19-
start: Arc::new(AtomicF64::new(f64::MAX)),
20-
stop: Arc::new(AtomicF64::new(f64::MAX)),
30+
inner: Arc::new(inner),
2131
}
2232
}
2333

2434
/// Retrieve playback start value
2535
pub fn get_start_at(&self) -> f64 {
26-
self.start.load(Ordering::SeqCst)
36+
self.inner.start.load(Ordering::Acquire)
2737
}
2838

2939
/// Schedule playback start at this timestamp
3040
pub fn start_at(&self, start: f64) {
3141
// todo panic on invalid values, or when already called
32-
self.start.store(start, Ordering::SeqCst);
42+
self.inner.start.store(start, Ordering::Release);
3343
}
3444

3545
/// Retrieve playback stop value
3646
pub fn get_stop_at(&self) -> f64 {
37-
self.stop.load(Ordering::SeqCst)
47+
self.inner.stop.load(Ordering::Acquire)
3848
}
3949

4050
/// Stop playback at this timestamp
4151
pub fn stop_at(&self, stop: f64) {
4252
// todo panic on invalid values, or when already called
43-
self.stop.store(stop, Ordering::SeqCst);
53+
self.inner.stop.store(stop, Ordering::Release);
4454
}
4555
}
4656

@@ -53,69 +63,80 @@ impl Default for Scheduler {
5363
/// Helper struct to control audio streams
5464
#[derive(Clone, Debug)]
5565
pub(crate) struct Controller {
56-
scheduler: Arc<Scheduler>,
57-
loop_: Arc<AtomicBool>,
58-
loop_start: Arc<AtomicF64>,
59-
loop_end: Arc<AtomicF64>,
60-
offset: Arc<AtomicF64>,
61-
duration: Arc<AtomicF64>,
66+
inner: Arc<ControllerInner>,
6267
}
6368

69+
#[derive(Debug)]
70+
struct ControllerInner {
71+
scheduler: Scheduler,
72+
loop_: AtomicBool,
73+
loop_start: AtomicF64,
74+
loop_end: AtomicF64,
75+
offset: AtomicF64,
76+
duration: AtomicF64,
77+
}
78+
79+
// Uses the canonical ordering for handover of values, i.e. `Acquire` on load and `Release` on
80+
// store.
6481
impl Controller {
6582
/// Create a new Controller. It will not be active
6683
pub fn new() -> Self {
84+
let inner = ControllerInner {
85+
scheduler: Scheduler::new(),
86+
loop_: AtomicBool::new(false),
87+
loop_start: AtomicF64::new(0.),
88+
loop_end: AtomicF64::new(f64::MAX),
89+
offset: AtomicF64::new(f64::MAX),
90+
duration: AtomicF64::new(f64::MAX),
91+
};
92+
6793
Self {
68-
scheduler: Arc::new(Scheduler::new()),
69-
loop_: Arc::new(AtomicBool::new(false)),
70-
loop_start: Arc::new(AtomicF64::new(0.)),
71-
loop_end: Arc::new(AtomicF64::new(f64::MAX)),
72-
offset: Arc::new(AtomicF64::new(f64::MAX)),
73-
duration: Arc::new(AtomicF64::new(f64::MAX)),
94+
inner: Arc::new(inner),
7495
}
7596
}
7697

7798
pub fn scheduler(&self) -> &Scheduler {
78-
&self.scheduler
99+
&self.inner.scheduler
79100
}
80101

81102
pub fn loop_(&self) -> bool {
82-
self.loop_.load(Ordering::SeqCst)
103+
self.inner.loop_.load(Ordering::Acquire)
83104
}
84105

85106
pub fn set_loop(&self, loop_: bool) {
86-
self.loop_.store(loop_, Ordering::SeqCst);
107+
self.inner.loop_.store(loop_, Ordering::Release);
87108
}
88109

89110
pub fn loop_start(&self) -> f64 {
90-
self.loop_start.load(Ordering::SeqCst)
111+
self.inner.loop_start.load(Ordering::Acquire)
91112
}
92113

93114
pub fn set_loop_start(&self, loop_start: f64) {
94-
self.loop_start.store(loop_start, Ordering::SeqCst);
115+
self.inner.loop_start.store(loop_start, Ordering::Release);
95116
}
96117

97118
pub fn loop_end(&self) -> f64 {
98-
self.loop_end.load(Ordering::SeqCst)
119+
self.inner.loop_end.load(Ordering::Acquire)
99120
}
100121

101122
pub fn set_loop_end(&self, loop_end: f64) {
102-
self.loop_end.store(loop_end, Ordering::SeqCst);
123+
self.inner.loop_end.store(loop_end, Ordering::Release);
103124
}
104125

105126
pub fn offset(&self) -> f64 {
106-
self.offset.load(Ordering::SeqCst)
127+
self.inner.offset.load(Ordering::Acquire)
107128
}
108129

109130
pub fn set_offset(&self, offset: f64) {
110-
self.offset.store(offset, Ordering::SeqCst);
131+
self.inner.offset.store(offset, Ordering::Release);
111132
}
112133

113134
pub fn duration(&self) -> f64 {
114-
self.duration.load(Ordering::SeqCst)
135+
self.inner.duration.load(Ordering::Acquire)
115136
}
116137

117138
pub fn set_duration(&self, duration: f64) {
118-
self.duration.store(duration, Ordering::SeqCst)
139+
self.inner.duration.store(duration, Ordering::Release)
119140
}
120141
}
121142

0 commit comments

Comments
 (0)