1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-28 07:29:45 +00:00

Eliminates potential race conditions on validity of delegate_.

This commit is contained in:
Thomas Harte 2020-02-18 20:33:31 -05:00
parent f43c31da1f
commit a5e1765ce4
2 changed files with 12 additions and 6 deletions

View File

@ -124,7 +124,8 @@ template <typename SampleSource> class LowpassSpeaker: public Speaker {
at construction, filtering it and passing it on to the speaker's delegate if there is one.
*/
void run_for(const Cycles cycles) {
if(!delegate_) return;
const auto delegate = delegate_.load();
if(!delegate) return;
std::size_t cycles_remaining = size_t(cycles.as_integral());
if(!cycles_remaining) return;
@ -138,7 +139,7 @@ template <typename SampleSource> class LowpassSpeaker: public Speaker {
}
if(filter_parameters.parameters_are_dirty) update_filter_coefficients(filter_parameters);
if(filter_parameters.input_rate_changed) {
delegate_->speaker_did_change_input_clock(this);
delegate->speaker_did_change_input_clock(this);
}
switch(conversion_) {

View File

@ -9,6 +9,7 @@
#ifndef Speaker_hpp
#define Speaker_hpp
#include <atomic>
#include <cstdint>
#include <vector>
@ -82,12 +83,16 @@ class Speaker {
protected:
void did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer, bool is_stereo) {
// Test the delegate for existence again, as it may have changed.
const auto delegate = delegate_.load();
if(!delegate) return;
++completed_sample_sets_;
// Hope for the fast path first: producer and consumer agree about
// number of channels.
if(is_stereo == stereo_output_) {
delegate_->speaker_did_complete_samples(this, buffer);
delegate->speaker_did_complete_samples(this, buffer);
return;
}
@ -106,9 +111,9 @@ class Speaker {
mix_buffer_[(c << 1) + 0] = mix_buffer_[(c << 1) + 1] = buffer[c];
}
}
delegate_->speaker_did_complete_samples(this, mix_buffer_);
delegate->speaker_did_complete_samples(this, mix_buffer_);
}
Delegate *delegate_ = nullptr;
std::atomic<Delegate *> delegate_ = nullptr;
private:
void compute_output_rate() {
@ -121,7 +126,7 @@ class Speaker {
float input_rate_multiplier_ = 1.0f;
float output_cycles_per_second_ = 1.0f;
int output_buffer_size_ = 1;
bool stereo_output_ = false;
std::atomic<bool> stereo_output_ = false;
std::vector<int16_t> mix_buffer_;
};