Skip to content

Commit 3d721a0

Browse files
committed
Enable garbage collector thread only for online AudioContext
Fixes #367
1 parent 05a67ac commit 3d721a0

File tree

5 files changed

+40
-30
lines changed

5 files changed

+40
-30
lines changed

src/context/offline.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ impl OfflineAudioContext {
5757
number_of_channels,
5858
receiver,
5959
frames_played_clone,
60-
None,
61-
None,
6260
);
6361

6462
// first, setup the base audio context

src/io/cpal.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,14 @@ impl AudioBackendManager for CpalBackend {
186186
// shared atomic to report output latency to the control thread
187187
let output_latency = Arc::new(AtomicF64::new(0.));
188188

189-
let renderer = RenderThread::new(
189+
let mut renderer = RenderThread::new(
190190
sample_rate,
191191
preferred_config.channels as usize,
192192
ctrl_msg_recv.clone(),
193193
Arc::clone(&frames_played),
194-
Some(load_value_send.clone()),
195-
Some(event_send.clone()),
196194
);
195+
renderer.set_event_channels(load_value_send.clone(), event_send.clone());
196+
renderer.spawn_garbage_collector_thread();
197197

198198
log::debug!(
199199
"Attempt output stream with preferred config: {:?}",
@@ -227,14 +227,14 @@ impl AudioBackendManager for CpalBackend {
227227
&supported_config
228228
);
229229

230-
let renderer = RenderThread::new(
230+
let mut renderer = RenderThread::new(
231231
sample_rate,
232232
supported_config.channels as usize,
233233
ctrl_msg_recv,
234234
frames_played,
235-
Some(load_value_send),
236-
Some(event_send),
237235
);
236+
renderer.set_event_channels(load_value_send, event_send);
237+
renderer.spawn_garbage_collector_thread();
238238

239239
let spawned = spawn_output_stream(
240240
&device,

src/io/cubeb.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,14 @@ impl AudioBackendManager for CubebBackend {
182182
_ => cubeb::ChannelLayout::UNDEFINED, // TODO, does this work?
183183
};
184184

185-
let renderer = RenderThread::new(
185+
let mut renderer = RenderThread::new(
186186
sample_rate,
187187
number_of_channels,
188188
ctrl_msg_recv,
189189
frames_played,
190-
Some(load_value_send),
191-
Some(event_send),
192190
);
191+
renderer.set_event_channels(load_value_send, event_send);
192+
renderer.spawn_garbage_collector_thread();
193193

194194
let params = cubeb::StreamParamsBuilder::new()
195195
.format(cubeb::SampleFormat::Float32NE) // use float (native endian)

src/io/none.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,10 @@ impl AudioBackendManager for NoneBackend {
7777
event_send,
7878
} = render_thread_init;
7979

80-
let render_thread = RenderThread::new(
81-
sample_rate,
82-
MAX_CHANNELS,
83-
ctrl_msg_recv,
84-
frames_played,
85-
Some(load_value_send),
86-
Some(event_send),
87-
);
80+
let mut render_thread =
81+
RenderThread::new(sample_rate, MAX_CHANNELS, ctrl_msg_recv, frames_played);
82+
render_thread.set_event_channels(load_value_send, event_send);
83+
render_thread.spawn_garbage_collector_thread();
8884

8985
// Use a bounded channel for real-time safety. A maximum of 32 control messages (resume,
9086
// suspend, ..) will be handled per render quantum. The control thread will block when the

src/render/thread.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub(crate) struct RenderThread {
3232
buffer_offset: Option<(usize, AudioRenderQuantum)>,
3333
load_value_sender: Option<Sender<AudioRenderCapacityLoad>>,
3434
event_sender: Option<Sender<EventDispatch>>,
35-
garbage_collector: llq::Producer<Box<dyn Any + Send>>,
35+
garbage_collector: Option<llq::Producer<Box<dyn Any + Send>>>,
3636
}
3737

3838
// SAFETY:
@@ -52,21 +52,34 @@ impl RenderThread {
5252
number_of_channels: usize,
5353
receiver: Receiver<ControlMessage>,
5454
frames_played: Arc<AtomicU64>,
55-
load_value_sender: Option<Sender<AudioRenderCapacityLoad>>,
56-
event_sender: Option<Sender<EventDispatch>>,
5755
) -> Self {
58-
let (gc_producer, gc_consumer) = llq::Queue::new().split();
59-
spawn_garbage_collector_thread(gc_consumer);
6056
Self {
6157
graph: None,
6258
sample_rate,
6359
number_of_channels,
6460
frames_played,
6561
receiver: Some(receiver),
6662
buffer_offset: None,
67-
load_value_sender,
68-
event_sender,
69-
garbage_collector: gc_producer,
63+
load_value_sender: None,
64+
event_sender: None,
65+
garbage_collector: None,
66+
}
67+
}
68+
69+
pub(crate) fn set_event_channels(
70+
&mut self,
71+
load_value_sender: Sender<AudioRenderCapacityLoad>,
72+
event_sender: Sender<EventDispatch>,
73+
) {
74+
self.load_value_sender = Some(load_value_sender);
75+
self.event_sender = Some(event_sender);
76+
}
77+
78+
pub(crate) fn spawn_garbage_collector_thread(&mut self) {
79+
if self.garbage_collector.is_none() {
80+
let (gc_producer, gc_consumer) = llq::Queue::new().split();
81+
spawn_garbage_collector_thread(gc_consumer);
82+
self.garbage_collector = Some(gc_producer);
7083
}
7184
}
7285

@@ -129,7 +142,9 @@ impl RenderThread {
129142
}
130143
NodeMessage { id, mut msg } => {
131144
self.graph.as_mut().unwrap().route_message(id, msg.as_mut());
132-
self.garbage_collector.push(msg);
145+
if let Some(gc) = self.garbage_collector.as_mut() {
146+
gc.push(msg)
147+
}
133148
}
134149
}
135150
}
@@ -301,8 +316,9 @@ impl RenderThread {
301316

302317
impl Drop for RenderThread {
303318
fn drop(&mut self) {
304-
self.garbage_collector
305-
.push(llq::Node::new(Box::new(TerminateGarbageCollectorThread)));
319+
if let Some(gc) = self.garbage_collector.as_mut() {
320+
gc.push(llq::Node::new(Box::new(TerminateGarbageCollectorThread)))
321+
}
306322
log::info!("Audio render thread has been dropped");
307323
}
308324
}

0 commit comments

Comments
 (0)