Replace mutex lock/unlock pairs with guards, cleanups

This commit is contained in:
vsonnier 2016-06-02 23:56:31 +02:00
parent ad94fe6de3
commit 5bb43f5aaa
17 changed files with 265 additions and 199 deletions

View File

@ -47,39 +47,39 @@ bool DeviceConfig::getAGCMode() {
void DeviceConfig::setDeviceId(std::string deviceId) { void DeviceConfig::setDeviceId(std::string deviceId) {
busy_lock.lock(); std::lock_guard < std::mutex > lock(busy_lock);
this->deviceId = deviceId; this->deviceId = deviceId;
busy_lock.unlock();
} }
std::string DeviceConfig::getDeviceId() { std::string DeviceConfig::getDeviceId() {
std::string tmp; std::string tmp;
busy_lock.lock(); std::lock_guard < std::mutex > lock(busy_lock);
tmp = deviceId; tmp = deviceId;
busy_lock.unlock();
return tmp; return tmp;
} }
void DeviceConfig::setDeviceName(std::string deviceName) { void DeviceConfig::setDeviceName(std::string deviceName) {
busy_lock.lock(); std::lock_guard < std::mutex > lock(busy_lock);
this->deviceName = deviceName; this->deviceName = deviceName;
busy_lock.unlock();
} }
std::string DeviceConfig::getDeviceName() { std::string DeviceConfig::getDeviceName() {
std::string tmp; std::string tmp;
busy_lock.lock(); std::lock_guard < std::mutex > lock(busy_lock);
tmp = (deviceName=="")?deviceId:deviceName; tmp = (deviceName=="")?deviceId:deviceName;
busy_lock.unlock();
return tmp; return tmp;
} }
void DeviceConfig::save(DataNode *node) { void DeviceConfig::save(DataNode *node) {
busy_lock.lock(); std::lock_guard < std::mutex > lock(busy_lock);
*node->newChild("id") = deviceId; *node->newChild("id") = deviceId;
*node->newChild("name") = deviceName; *node->newChild("name") = deviceName;
*node->newChild("ppm") = (int)ppm.load(); *node->newChild("ppm") = (int)ppm.load();
@ -115,11 +115,11 @@ void DeviceConfig::save(DataNode *node) {
*gainNode->newChild("value") = gain_i->second; *gainNode->newChild("value") = gain_i->second;
} }
} }
busy_lock.unlock();
} }
void DeviceConfig::load(DataNode *node) { void DeviceConfig::load(DataNode *node) {
busy_lock.lock(); std::lock_guard < std::mutex > lock(busy_lock);
if (node->hasAnother("name")) { if (node->hasAnother("name")) {
deviceName = node->getNext("name")->element()->toString(); deviceName = node->getNext("name")->element()->toString();
} }
@ -201,7 +201,7 @@ void DeviceConfig::load(DataNode *node) {
} }
} }
} }
busy_lock.unlock();
} }
void DeviceConfig::setStreamOpts(ConfigSettings opts) { void DeviceConfig::setStreamOpts(ConfigSettings opts) {

View File

@ -1611,10 +1611,10 @@ bool AppFrame::loadSession(std::string fileName) {
if (header->hasAnother("center_freq")) { if (header->hasAnother("center_freq")) {
long long center_freq = *header->getNext("center_freq"); long long center_freq = *header->getNext("center_freq");
// std::cout << "\tCenter Frequency: " << center_freq << std::endl; // std::cout << "\tCenter Frequency: " << center_freq << std::endl;
wxGetApp().setFrequency(center_freq); wxGetApp().setFrequency(center_freq);
} }
if (header->hasAnother("sample_rate")) { if (header->hasAnother("sample_rate")) {
int sample_rate = *header->getNext("sample_rate"); int sample_rate = *header->getNext("sample_rate");
@ -1739,7 +1739,7 @@ bool AppFrame::loadSession(std::string fileName) {
newDemod->run(); newDemod->run();
newDemod->setActive(true); newDemod->setActive(true);
demodsLoaded.push_back(newDemod); demodsLoaded.push_back(newDemod);
// wxGetApp().bindDemodulator(newDemod); // wxGetApp().bindDemodulator(newDemod);
std::cout << "\tAdded demodulator at frequency " << newDemod->getFrequency() << " type " << type << std::endl; std::cout << "\tAdded demodulator at frequency " << newDemod->getFrequency() << " type " << type << std::endl;
// std::cout << "\t\tBandwidth: " << bandwidth << std::endl; // std::cout << "\t\tBandwidth: " << bandwidth << std::endl;

View File

@ -397,7 +397,10 @@ void CubicSDR::removeRemote(std::string remoteAddr) {
} }
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) { void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
notify_busy.lock();
std::lock_guard < std::mutex > lock(notify_busy);
if (state == SDRThread::SDR_THREAD_INITIALIZED) { if (state == SDRThread::SDR_THREAD_INITIALIZED) {
appframe->initDeviceParams(getDevice()); appframe->initDeviceParams(getDevice());
} }
@ -415,12 +418,13 @@ void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string mess
// info->ShowModal(); // info->ShowModal();
} }
//if (appframe) { appframe->SetStatusText(message); } //if (appframe) { appframe->SetStatusText(message); }
notify_busy.unlock();
} }
void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message) { void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message) {
notify_busy.lock(); std::lock_guard < std::mutex > lock(notify_busy);
if (state == SDREnumerator::SDR_ENUM_MESSAGE) { if (state == SDREnumerator::SDR_ENUM_MESSAGE) {
notifyMessage = message; notifyMessage = message;
} }
@ -432,7 +436,7 @@ void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::strin
devicesFailed.store(true); devicesFailed.store(true);
} }
//if (appframe) { appframe->SetStatusText(message); } //if (appframe) { appframe->SetStatusText(message); }
notify_busy.unlock();
} }
@ -748,9 +752,9 @@ bool CubicSDR::areModulesMissing() {
std::string CubicSDR::getNotification() { std::string CubicSDR::getNotification() {
std::string msg; std::string msg;
notify_busy.lock(); std::lock_guard < std::mutex > lock(notify_busy);
msg = notifyMessage; msg = notifyMessage;
notify_busy.unlock();
return msg; return msg;
} }

View File

@ -212,7 +212,9 @@ private:
std::atomic_bool useLocalMod; std::atomic_bool useLocalMod;
std::string notifyMessage; std::string notifyMessage;
std::string modulePath; std::string modulePath;
std::mutex notify_busy; std::mutex notify_busy;
std::atomic_bool frequency_locked; std::atomic_bool frequency_locked;
std::atomic_llong lock_freq; std::atomic_llong lock_freq;
FrequencyDialog::FrequencyDialogTarget fdlgTarget; FrequencyDialog::FrequencyDialogTarget fdlgTarget;

View File

@ -37,6 +37,12 @@ public:
std::lock_guard < std::recursive_mutex > lock(m_mutex); std::lock_guard < std::recursive_mutex > lock(m_mutex);
return refCount; return refCount;
} }
// Access to the own mutex protecting the ReferenceCounter, i.e the monitor of the class
std::recursive_mutex& getMonitor() const {
return m_mutex;
}
protected: protected:
//this is a basic mutex for all ReferenceCounter derivatives operations INCLUDING the counter itself for consistency ! //this is a basic mutex for all ReferenceCounter derivatives operations INCLUDING the counter itself for consistency !
mutable std::recursive_mutex m_mutex; mutable std::recursive_mutex m_mutex;

View File

@ -20,7 +20,6 @@ public:
float peak; float peak;
int type; int type;
std::vector<float> data; std::vector<float> data;
std::mutex busy_update;
AudioThreadInput() : AudioThreadInput() :
frequency(0), sampleRate(0), channels(0), peak(0) { frequency(0), sampleRate(0), channels(0), peak(0) {

View File

@ -53,7 +53,7 @@ public:
long long frequency; long long frequency;
long long sampleRate; long long sampleRate;
std::vector<liquid_float_complex> data; std::vector<liquid_float_complex> data;
std::mutex busy_rw;
DemodulatorThreadIQData() : DemodulatorThreadIQData() :
frequency(0), sampleRate(0) { frequency(0), sampleRate(0) {

View File

@ -31,7 +31,7 @@ DemodulatorMgr::~DemodulatorMgr() {
} }
DemodulatorInstance *DemodulatorMgr::newThread() { DemodulatorInstance *DemodulatorMgr::newThread() {
std::lock_guard < std::mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
DemodulatorInstance *newDemod = new DemodulatorInstance; DemodulatorInstance *newDemod = new DemodulatorInstance;
std::stringstream label; std::stringstream label;
@ -44,8 +44,9 @@ DemodulatorInstance *DemodulatorMgr::newThread() {
} }
void DemodulatorMgr::terminateAll() { void DemodulatorMgr::terminateAll() {
std::lock_guard < std::mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
while (demods.size()) { while (demods.size()) {
DemodulatorInstance *d = demods.back(); DemodulatorInstance *d = demods.back();
demods.pop_back(); demods.pop_back();
wxGetApp().removeDemodulator(d); wxGetApp().removeDemodulator(d);
@ -54,11 +55,12 @@ void DemodulatorMgr::terminateAll() {
} }
std::vector<DemodulatorInstance *> &DemodulatorMgr::getDemodulators() { std::vector<DemodulatorInstance *> &DemodulatorMgr::getDemodulators() {
std::lock_guard < std::mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
return demods; return demods;
} }
std::vector<DemodulatorInstance *> DemodulatorMgr::getOrderedDemodulators(bool actives) { std::vector<DemodulatorInstance *> DemodulatorMgr::getOrderedDemodulators(bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> demods_ordered = demods; std::vector<DemodulatorInstance *> demods_ordered = demods;
if (actives) { if (actives) {
std::sort(demods_ordered.begin(), demods_ordered.end(), inactiveCompare); std::sort(demods_ordered.begin(), demods_ordered.end(), inactiveCompare);
@ -74,11 +76,13 @@ std::vector<DemodulatorInstance *> DemodulatorMgr::getOrderedDemodulators(bool a
demods_ordered.erase(demods_ordered.begin(), i); demods_ordered.erase(demods_ordered.begin(), i);
} }
} }
std::sort(demods_ordered.begin(), demods_ordered.end(), demodFreqCompare); //if by chance they have the same frequency, keep their relative order
std::stable_sort(demods_ordered.begin(), demods_ordered.end(), demodFreqCompare);
return demods_ordered; return demods_ordered;
} }
DemodulatorInstance *DemodulatorMgr::getPreviousDemodulator(DemodulatorInstance *demod, bool actives) { DemodulatorInstance *DemodulatorMgr::getPreviousDemodulator(DemodulatorInstance *demod, bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!getLastActiveDemodulator()) { if (!getLastActiveDemodulator()) {
return nullptr; return nullptr;
} }
@ -94,6 +98,7 @@ DemodulatorInstance *DemodulatorMgr::getPreviousDemodulator(DemodulatorInstance
} }
DemodulatorInstance *DemodulatorMgr::getNextDemodulator(DemodulatorInstance *demod, bool actives) { DemodulatorInstance *DemodulatorMgr::getNextDemodulator(DemodulatorInstance *demod, bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!getLastActiveDemodulator()) { if (!getLastActiveDemodulator()) {
return nullptr; return nullptr;
} }
@ -112,16 +117,20 @@ DemodulatorInstance *DemodulatorMgr::getNextDemodulator(DemodulatorInstance *dem
} }
DemodulatorInstance *DemodulatorMgr::getLastDemodulator() { DemodulatorInstance *DemodulatorMgr::getLastDemodulator() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators(); std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators();
return *(demods_ordered.end()); return *(demods_ordered.end());
} }
DemodulatorInstance *DemodulatorMgr::getFirstDemodulator() { DemodulatorInstance *DemodulatorMgr::getFirstDemodulator() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators(); std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators();
return *(demods_ordered.begin()); return *(demods_ordered.begin());
} }
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) { void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *>::iterator i; std::vector<DemodulatorInstance *>::iterator i;
i = std::find(demods.begin(), demods.end(), demod); i = std::find(demods.begin(), demods.end(), demod);
@ -145,7 +154,7 @@ void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
} }
std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(long long freq, int bandwidth) { std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(long long freq, int bandwidth) {
std::lock_guard < std::mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> *foundDemods = new std::vector<DemodulatorInstance *>(); std::vector<DemodulatorInstance *> *foundDemods = new std::vector<DemodulatorInstance *>();
for (int i = 0, iMax = demods.size(); i < iMax; i++) { for (int i = 0, iMax = demods.size(); i < iMax; i++) {
@ -166,7 +175,7 @@ std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(long long
} }
bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) { bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
std::lock_guard < std::mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
for (int i = 0, iMax = demods.size(); i < iMax; i++) { for (int i = 0, iMax = demods.size(); i < iMax; i++) {
DemodulatorInstance *testDemod = demods[i]; DemodulatorInstance *testDemod = demods[i];
@ -177,6 +186,7 @@ bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
long long halfBuffer = bandwidth / 2; long long halfBuffer = bandwidth / 2;
if ((freq <= (freqTest + ((testDemod->getDemodulatorType() != "LSB")?halfBandwidthTest:0) + halfBuffer)) && (freq >= (freqTest - ((testDemod->getDemodulatorType() != "USB")?halfBandwidthTest:0) - halfBuffer))) { if ((freq <= (freqTest + ((testDemod->getDemodulatorType() != "LSB")?halfBandwidthTest:0) + halfBuffer)) && (freq >= (freqTest - ((testDemod->getDemodulatorType() != "USB")?halfBandwidthTest:0) - halfBuffer))) {
return true; return true;
} }
} }
@ -186,6 +196,7 @@ bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool temporary) { void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool temporary) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!temporary) { if (!temporary) {
if (activeDemodulator != NULL) { if (activeDemodulator != NULL) {
lastActiveDemodulator = activeDemodulator; lastActiveDemodulator = activeDemodulator;
@ -218,6 +229,7 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool tempo
} }
activeDemodulator = demod; activeDemodulator = demod;
} }
DemodulatorInstance *DemodulatorMgr::getActiveDemodulator() { DemodulatorInstance *DemodulatorMgr::getActiveDemodulator() {
@ -231,9 +243,10 @@ DemodulatorInstance *DemodulatorMgr::getLastActiveDemodulator() {
return lastActiveDemodulator; return lastActiveDemodulator;
} }
//Private internal method, no need to protect it with demods_busy
void DemodulatorMgr::garbageCollect() { void DemodulatorMgr::garbageCollect() {
std::lock_guard < std::mutex > lock(demods_busy);
if (demods_deleted.size()) { if (demods_deleted.size()) {
std::vector<DemodulatorInstance *>::iterator i; std::vector<DemodulatorInstance *>::iterator i;
for (i = demods_deleted.begin(); i != demods_deleted.end(); i++) { for (i = demods_deleted.begin(); i != demods_deleted.end(); i++) {
@ -245,13 +258,16 @@ void DemodulatorMgr::garbageCollect() {
delete deleted; delete deleted;
return; return;
} }
} }
} }
} }
void DemodulatorMgr::updateLastState() { void DemodulatorMgr::updateLastState() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (std::find(demods.begin(), demods.end(), lastActiveDemodulator) == demods.end()) { if (std::find(demods.begin(), demods.end(), lastActiveDemodulator) == demods.end()) {
if (activeDemodulator && activeDemodulator->isActive()) { if (activeDemodulator && activeDemodulator->isActive()) {
lastActiveDemodulator = activeDemodulator; lastActiveDemodulator = activeDemodulator;

View File

@ -72,7 +72,9 @@ private:
bool lastMuted; bool lastMuted;
bool lastDeltaLock; bool lastDeltaLock;
std::mutex demods_busy; //protects access to demods lists and such, need to be recursive
//because of the usage of public re-entrant methods
std::recursive_mutex demods_busy;
std::map<std::string, ModemSettings> lastModemSettings; std::map<std::string, ModemSettings> lastModemSettings;
}; };

View File

@ -54,24 +54,27 @@ bool SpectrumVisualProcessor::isView() {
} }
void SpectrumVisualProcessor::setView(bool bView) { void SpectrumVisualProcessor::setView(bool bView) {
busy_run.lock();
std::lock_guard < std::mutex > busy_lock(busy_run);
is_view.store(bView); is_view.store(bView);
busy_run.unlock();
} }
void SpectrumVisualProcessor::setView(bool bView, long long centerFreq_in, long bandwidth_in) { void SpectrumVisualProcessor::setView(bool bView, long long centerFreq_in, long bandwidth_in) {
busy_run.lock();
std::lock_guard < std::mutex > busy_lock(busy_run);
is_view.store(bView); is_view.store(bView);
bandwidth.store(bandwidth_in); bandwidth.store(bandwidth_in);
centerFreq.store(centerFreq_in); centerFreq.store(centerFreq_in);
busy_run.unlock();
} }
void SpectrumVisualProcessor::setFFTAverageRate(float fftAverageRate) { void SpectrumVisualProcessor::setFFTAverageRate(float fftAverageRate) {
busy_run.lock();
std::lock_guard < std::mutex > busy_lock(busy_run);
this->fft_average_rate.store(fftAverageRate); this->fft_average_rate.store(fftAverageRate);
busy_run.unlock();
} }
float SpectrumVisualProcessor::getFFTAverageRate() { float SpectrumVisualProcessor::getFFTAverageRate() {
@ -79,9 +82,10 @@ float SpectrumVisualProcessor::getFFTAverageRate() {
} }
void SpectrumVisualProcessor::setCenterFrequency(long long centerFreq_in) { void SpectrumVisualProcessor::setCenterFrequency(long long centerFreq_in) {
busy_run.lock();
std::lock_guard < std::mutex > busy_lock(busy_run);
centerFreq.store(centerFreq_in); centerFreq.store(centerFreq_in);
busy_run.unlock();
} }
long long SpectrumVisualProcessor::getCenterFrequency() { long long SpectrumVisualProcessor::getCenterFrequency() {
@ -89,9 +93,10 @@ long long SpectrumVisualProcessor::getCenterFrequency() {
} }
void SpectrumVisualProcessor::setBandwidth(long bandwidth_in) { void SpectrumVisualProcessor::setBandwidth(long bandwidth_in) {
busy_run.lock();
std::lock_guard < std::mutex > busy_lock(busy_run);
bandwidth.store(bandwidth_in); bandwidth.store(bandwidth_in);
busy_run.unlock();
} }
long SpectrumVisualProcessor::getBandwidth() { long SpectrumVisualProcessor::getBandwidth() {
@ -99,6 +104,7 @@ long SpectrumVisualProcessor::getBandwidth() {
} }
void SpectrumVisualProcessor::setPeakHold(bool peakHold_in) { void SpectrumVisualProcessor::setPeakHold(bool peakHold_in) {
if (peakHold.load() && peakHold_in) { if (peakHold.load() && peakHold_in) {
peakReset.store(PEAK_RESET_COUNT); peakReset.store(PEAK_RESET_COUNT);
} else { } else {
@ -116,7 +122,8 @@ int SpectrumVisualProcessor::getDesiredInputSize() {
} }
void SpectrumVisualProcessor::setup(unsigned int fftSize_in) { void SpectrumVisualProcessor::setup(unsigned int fftSize_in) {
busy_run.lock();
std::lock_guard < std::mutex > busy_lock(busy_run);
fftSize = fftSize_in; fftSize = fftSize_in;
fftSizeInternal = fftSize_in * SPECTRUM_VZM; fftSizeInternal = fftSize_in * SPECTRUM_VZM;
@ -190,7 +197,6 @@ void SpectrumVisualProcessor::setup(unsigned int fftSize_in) {
fftPlan = fft_create_plan(fftSizeInternal, fftInput, fftOutput, LIQUID_FFT_FORWARD, 0); fftPlan = fft_create_plan(fftSizeInternal, fftInput, fftOutput, LIQUID_FFT_FORWARD, 0);
#endif #endif
busy_run.unlock();
} }
void SpectrumVisualProcessor::setFFTSize(unsigned int fftSize_in) { void SpectrumVisualProcessor::setFFTSize(unsigned int fftSize_in) {
@ -235,8 +241,15 @@ void SpectrumVisualProcessor::process() {
return; return;
} }
iqData->busy_rw.lock();
busy_run.lock(); //Start by locking concurrent access to iqData
std::lock_guard < std::recursive_mutex > lock(iqData->getMonitor());
//then get the busy_lock
std::lock_guard < std::mutex > busy_lock(busy_run);
bool doPeak = peakHold.load() && (peakReset.load() == 0); bool doPeak = peakHold.load() && (peakReset.load() == 0);
if (fft_result.size() != fftSizeInternal) { if (fft_result.size() != fftSizeInternal) {
@ -275,8 +288,7 @@ void SpectrumVisualProcessor::process() {
if (is_view.load()) { if (is_view.load()) {
if (!iqData->frequency || !iqData->sampleRate) { if (!iqData->frequency || !iqData->sampleRate) {
iqData->decRefCount(); iqData->decRefCount();
iqData->busy_rw.unlock();
busy_run.unlock();
return; return;
} }
@ -706,8 +718,7 @@ void SpectrumVisualProcessor::process() {
} }
iqData->decRefCount(); iqData->decRefCount();
iqData->busy_rw.unlock();
busy_run.unlock();
lastView = is_view.load(); lastView = is_view.load();
} }

View File

@ -97,6 +97,7 @@ private:
std::vector<liquid_float_complex> shiftBuffer; std::vector<liquid_float_complex> shiftBuffer;
std::vector<liquid_float_complex> resampleBuffer; std::vector<liquid_float_complex> resampleBuffer;
std::atomic_int desiredInputSize; std::atomic_int desiredInputSize;
std::mutex busy_run; std::mutex busy_run;
std::atomic_bool hideDC, peakHold; std::atomic_bool hideDC, peakHold;
std::atomic_int peakReset; std::atomic_int peakReset;

View File

@ -13,10 +13,14 @@ public:
} }
bool isInputEmpty() { bool isInputEmpty() {
std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
return input->empty(); return input->empty();
} }
bool isOutputEmpty() { bool isOutputEmpty() {
std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) {
if ((*outputs_i)->full()) { if ((*outputs_i)->full()) {
return false; return false;
@ -26,6 +30,8 @@ public:
} }
bool isAnyOutputEmpty() { bool isAnyOutputEmpty() {
std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) {
if (!(*outputs_i)->full()) { if (!(*outputs_i)->full()) {
return true; return true;
@ -35,34 +41,37 @@ public:
} }
void setInput(ThreadQueue<InputDataType *> *vis_in) { void setInput(ThreadQueue<InputDataType *> *vis_in) {
busy_update.lock(); std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
input = vis_in; input = vis_in;
busy_update.unlock();
} }
void attachOutput(ThreadQueue<OutputDataType *> *vis_out) { void attachOutput(ThreadQueue<OutputDataType *> *vis_out) {
// attach an output queue // attach an output queue
busy_update.lock(); std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
outputs.push_back(vis_out); outputs.push_back(vis_out);
busy_update.unlock();
} }
void removeOutput(ThreadQueue<OutputDataType *> *vis_out) { void removeOutput(ThreadQueue<OutputDataType *> *vis_out) {
// remove an output queue // remove an output queue
busy_update.lock(); std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
typename std::vector<ThreadQueue<OutputDataType *> *>::iterator i = std::find(outputs.begin(), outputs.end(), vis_out); typename std::vector<ThreadQueue<OutputDataType *> *>::iterator i = std::find(outputs.begin(), outputs.end(), vis_out);
if (i != outputs.end()) { if (i != outputs.end()) {
outputs.erase(i); outputs.erase(i);
} }
busy_update.unlock();
} }
void run() { void run() {
busy_update.lock();
std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
if (input && !input->empty()) { if (input && !input->empty()) {
process(); process();
} }
busy_update.unlock();
} }
protected: protected:
@ -73,6 +82,8 @@ protected:
void distribute(OutputDataType *output) { void distribute(OutputDataType *output) {
// distribute outputs // distribute outputs
std::lock_guard < std::recursive_mutex > busy_lock(busy_update);
output->setRefCount(outputs.size()); output->setRefCount(outputs.size());
for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) {
if ((*outputs_i)->full()) { if ((*outputs_i)->full()) {
@ -86,7 +97,9 @@ protected:
ThreadQueue<InputDataType *> *input; ThreadQueue<InputDataType *> *input;
std::vector<ThreadQueue<OutputDataType *> *> outputs; std::vector<ThreadQueue<OutputDataType *> *> outputs;
typename std::vector<ThreadQueue<OutputDataType *> *>::iterator outputs_i; typename std::vector<ThreadQueue<OutputDataType *> *>::iterator outputs_i;
std::mutex busy_update;
//protects input and outputs, must be recursive because ao reentrance
std::recursive_mutex busy_update;
}; };

View File

@ -27,9 +27,12 @@ SDRPostThread::~SDRPostThread() {
} }
void SDRPostThread::bindDemodulator(DemodulatorInstance *demod) { void SDRPostThread::bindDemodulator(DemodulatorInstance *demod) {
std::lock_guard < std::mutex > lock(busy_demod); std::lock_guard < std::mutex > lock(busy_demod);
demodulators.push_back(demod); demodulators.push_back(demod);
doRefresh.store(true); doRefresh.store(true);
} }
void SDRPostThread::bindDemodulators(std::vector<DemodulatorInstance *> *demods) { void SDRPostThread::bindDemodulators(std::vector<DemodulatorInstance *> *demods) {
@ -37,10 +40,12 @@ void SDRPostThread::bindDemodulators(std::vector<DemodulatorInstance *> *demods)
return; return;
} }
std::lock_guard < std::mutex > lock(busy_demod); std::lock_guard < std::mutex > lock(busy_demod);
for (std::vector<DemodulatorInstance *>::iterator di = demods->begin(); di != demods->end(); di++) { for (std::vector<DemodulatorInstance *>::iterator di = demods->begin(); di != demods->end(); di++) {
demodulators.push_back(*di); demodulators.push_back(*di);
doRefresh.store(true); doRefresh.store(true);
} }
} }
void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) { void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) {
@ -49,12 +54,14 @@ void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) {
} }
std::lock_guard < std::mutex > lock(busy_demod); std::lock_guard < std::mutex > lock(busy_demod);
std::vector<DemodulatorInstance *>::iterator i = std::find(demodulators.begin(), demodulators.end(), demod); std::vector<DemodulatorInstance *>::iterator i = std::find(demodulators.begin(), demodulators.end(), demod);
if (i != demodulators.end()) { if (i != demodulators.end()) {
demodulators.erase(i); demodulators.erase(i);
doRefresh.store(true); doRefresh.store(true);
} }
} }
void SDRPostThread::initPFBChannelizer() { void SDRPostThread::initPFBChannelizer() {

View File

@ -29,10 +29,14 @@ protected:
DemodulatorThreadInputQueue *iqVisualQueue; DemodulatorThreadInputQueue *iqVisualQueue;
DemodulatorThreadInputQueue *iqActiveDemodVisualQueue; DemodulatorThreadInputQueue *iqActiveDemodVisualQueue;
//protects access to demodulators lists and such
std::mutex busy_demod; std::mutex busy_demod;
std::vector<DemodulatorInstance *> demodulators; std::vector<DemodulatorInstance *> demodulators;
private: private:
void initPFBChannelizer(); void initPFBChannelizer();
void updateActiveDemodulators(); void updateActiveDemodulators();
void updateChannels(); void updateChannels();

View File

@ -126,7 +126,9 @@ void SDRThread::init() {
settingChanged.erase(settingChanged.begin(), settingChanged.end()); settingChanged.erase(settingChanged.begin(), settingChanged.end());
} }
setting_busy.lock(); { //enter scoped-lock
std::lock_guard < std::mutex > lock(setting_busy);
for (settings_i = settingsInfo.begin(); settings_i != settingsInfo.end(); settings_i++) { for (settings_i = settingsInfo.begin(); settings_i != settingsInfo.end(); settings_i++) {
SoapySDR::ArgInfo setting = (*settings_i); SoapySDR::ArgInfo setting = (*settings_i);
if ((settingChanged.find(setting.key) != settingChanged.end()) && (settings.find(setting.key) != settings.end())) { if ((settingChanged.find(setting.key) != settingChanged.end()) && (settings.find(setting.key) != settings.end())) {
@ -139,7 +141,7 @@ void SDRThread::init() {
} }
setting_value_changed.store(false); setting_value_changed.store(false);
setting_busy.unlock(); } //leave lock guard scope
updateSettings(); updateSettings();
@ -316,21 +318,22 @@ void SDRThread::updateSettings() {
} }
if (gain_value_changed.load() && !agc_mode.load()) { if (gain_value_changed.load() && !agc_mode.load()) {
gain_busy.lock(); std::lock_guard < std::mutex > lock(gain_busy);
for (std::map<std::string,bool>::iterator gci = gainChanged.begin(); gci != gainChanged.end(); gci++) { for (std::map<std::string,bool>::iterator gci = gainChanged.begin(); gci != gainChanged.end(); gci++) {
if (gci->second) { if (gci->second) {
device->setGain(SOAPY_SDR_RX, 0, gci->first, gainValues[gci->first]); device->setGain(SOAPY_SDR_RX, 0, gci->first, gainValues[gci->first]);
gainChanged[gci->first] = false; gainChanged[gci->first] = false;
} }
} }
gain_busy.unlock();
gain_value_changed.store(false); gain_value_changed.store(false);
} }
if (setting_value_changed.load()) { if (setting_value_changed.load()) {
setting_busy.lock();
std::lock_guard < std::mutex > lock(setting_busy);
for (std::map<std::string, bool>::iterator sci = settingChanged.begin(); sci != settingChanged.end(); sci++) { for (std::map<std::string, bool>::iterator sci = settingChanged.begin(); sci != settingChanged.end(); sci++) {
if (sci->second) { if (sci->second) {
@ -340,7 +343,6 @@ void SDRThread::updateSettings() {
} }
setting_value_changed.store(false); setting_value_changed.store(false);
setting_busy.unlock();
doUpdate = true; doUpdate = true;
} }
@ -511,11 +513,10 @@ bool SDRThread::getIQSwap() {
} }
void SDRThread::setGain(std::string name, float value) { void SDRThread::setGain(std::string name, float value) {
gain_busy.lock(); std::lock_guard < std::mutex > lock(gain_busy);
gainValues[name] = value; gainValues[name] = value;
gainChanged[name] = true; gainChanged[name] = true;
gain_value_changed.store(true); gain_value_changed.store(true);
gain_busy.unlock();
DeviceConfig *devConfig = deviceConfig.load(); DeviceConfig *devConfig = deviceConfig.load();
if (devConfig) { if (devConfig) {
@ -524,28 +525,30 @@ void SDRThread::setGain(std::string name, float value) {
} }
float SDRThread::getGain(std::string name) { float SDRThread::getGain(std::string name) {
gain_busy.lock(); std::lock_guard < std::mutex > lock(gain_busy);
float val = gainValues[name]; float val = gainValues[name];
gain_busy.unlock();
return val; return val;
} }
void SDRThread::writeSetting(std::string name, std::string value) { void SDRThread::writeSetting(std::string name, std::string value) {
setting_busy.lock();
std::lock_guard < std::mutex > lock(setting_busy);
settings[name] = value; settings[name] = value;
settingChanged[name] = true; settingChanged[name] = true;
setting_value_changed.store(true); setting_value_changed.store(true);
if (deviceConfig.load() != nullptr) { if (deviceConfig.load() != nullptr) {
deviceConfig.load()->setSetting(name, value); deviceConfig.load()->setSetting(name, value);
} }
setting_busy.unlock();
} }
std::string SDRThread::readSetting(std::string name) { std::string SDRThread::readSetting(std::string name) {
std::string val; std::string val;
setting_busy.lock(); std::lock_guard < std::mutex > lock(setting_busy);
val = device->readSetting(name); val = device->readSetting(name);
setting_busy.unlock();
return val; return val;
} }

View File

@ -83,7 +83,7 @@ void WaterfallCanvas::attachSpectrumCanvas(SpectrumCanvas *canvas_in) {
} }
void WaterfallCanvas::processInputQueue() { void WaterfallCanvas::processInputQueue() {
tex_update.lock(); std::lock_guard < std::mutex > lock(tex_update);
gTimer.update(); gTimer.update();
@ -118,11 +118,11 @@ void WaterfallCanvas::processInputQueue() {
glContext->SetCurrent(*this); glContext->SetCurrent(*this);
waterfallPanel.update(); waterfallPanel.update();
} }
tex_update.unlock();
} }
void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
tex_update.lock(); std::lock_guard < std::mutex > lock(tex_update);
wxPaintDC dc(this); wxPaintDC dc(this);
const wxSize ClientSize = GetClientSize(); const wxSize ClientSize = GetClientSize();
@ -341,7 +341,6 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->EndDraw(); glContext->EndDraw();
SwapBuffers(); SwapBuffers();
tex_update.unlock();
} }
void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) { void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
@ -905,7 +904,7 @@ void WaterfallCanvas::updateCenterFrequency(long long freq) {
} }
void WaterfallCanvas::setLinesPerSecond(int lps) { void WaterfallCanvas::setLinesPerSecond(int lps) {
tex_update.lock(); std::lock_guard < std::mutex > lock(tex_update);
linesPerSecond = lps; linesPerSecond = lps;
while (!visualDataQueue.empty()) { while (!visualDataQueue.empty()) {
SpectrumVisualData *vData; SpectrumVisualData *vData;
@ -915,7 +914,6 @@ void WaterfallCanvas::setLinesPerSecond(int lps) {
vData->decRefCount(); vData->decRefCount();
} }
} }
tex_update.unlock();
} }
void WaterfallCanvas::setMinBandwidth(int min) { void WaterfallCanvas::setMinBandwidth(int min) {