From b3c6b05a5ce8dd1b039c2b79d9c362db4d07a824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 4 Dec 2024 23:04:30 +0100 Subject: [PATCH] use atomic access for shared_ptr --- src/controllers/bulk/bulkcontroller.cpp | 4 +-- src/controllers/midi/midicontroller.cpp | 36 +++++++++++++++++++------ src/controllers/midi/midicontroller.h | 9 ++++++- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/controllers/bulk/bulkcontroller.cpp b/src/controllers/bulk/bulkcontroller.cpp index 6a2d1212b65..4bb9189efab 100644 --- a/src/controllers/bulk/bulkcontroller.cpp +++ b/src/controllers/bulk/bulkcontroller.cpp @@ -283,8 +283,8 @@ void BulkController::send(const QList& data, unsigned int length) { void BulkController::sendBytes(const QByteArray& data) { VERIFY_OR_DEBUG_ASSERT(!m_pMapping || - m_pMapping->getDeviceDirection() & - LegacyControllerMapping::DeviceDirection::Outgoing) { + (m_pMapping->getDeviceDirection() & + LegacyControllerMapping::DeviceDirection::Outgoing)) { qDebug() << "The mapping for the bulk device" << getName() << "doesn't require sending data. Ignoring sending request."; return; diff --git a/src/controllers/midi/midicontroller.cpp b/src/controllers/midi/midicontroller.cpp index 6868b193e33..80cd7ca0b98 100644 --- a/src/controllers/midi/midicontroller.cpp +++ b/src/controllers/midi/midicontroller.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "control/controlobject.h" #include "controllers/defs_controllers.h" @@ -37,7 +38,7 @@ MidiController::MidiController(const QString& deviceName) void MidiController::slotBeforeEngineShutdown() { Controller::slotBeforeEngineShutdown(); - m_pMapping->removeInputHandlerMappings(); + getSharedMapping()->removeInputHandlerMappings(); } MidiController::~MidiController() { @@ -55,12 +56,21 @@ QString MidiController::mappingExtension() { } void MidiController::setMapping(std::shared_ptr pMapping) { - m_pMapping = downcastAndTakeOwnership(std::move(pMapping)); + std::shared_ptr pMidiMapping = + downcastAndTakeOwnership( + std::move(pMapping)); +#ifdef __cpp_lib_atomic_shared_ptr + // Used Spinlock + m_pMapping.store(pMidiMapping, std::memory_order_relaxed); +#else + // Uses Mutex + std::atomic_store_explicit(&m_pMapping, pMidiMapping, std::memory_order_relaxed); +#endif } std::shared_ptr MidiController::cloneMapping() { // Function becomes temporary shared owner - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); if (!pMapping) { return nullptr; } @@ -95,7 +105,7 @@ bool MidiController::applyMapping() { void MidiController::createOutputHandlers() { // Function becomes temporary shared owner - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); if (!pMapping) { return; } @@ -228,7 +238,7 @@ void MidiController::clearTemporaryInputMappings() { void MidiController::commitTemporaryInputMappings() { // Function becomes temporary shared owner - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); if (!pMapping) { return; } @@ -293,7 +303,7 @@ void MidiController::receivedShortMessage(unsigned char status, } // Function becomes temporary shared owner - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); auto it = pMapping->getInputMappings().constFind(mappingKey.key); for (; it != pMapping->getInputMappings().constEnd() && it.key() == mappingKey.key; ++it) { processInputMapping(it.value(), status, control, value, timestamp); @@ -593,7 +603,7 @@ void MidiController::receive(const QByteArray& data, mixxx::Duration timestamp) } // Function becomes temporary shared owner - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); const auto [inputMappingsBegin, inputMappingsEnd] = pMapping->getInputMappings().equal_range(mappingKey.key); std::for_each(inputMappingsBegin, inputMappingsEnd, [&](const auto& inputMapping) { @@ -646,7 +656,7 @@ QJSValue MidiController::makeInputHandler(int status, int midino, const QJSValue const auto midiKey = MidiKey(status, midino); // Function becomes temporary shared owner - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); auto it = pMapping->getInputMappings().constFind(midiKey.key); if (it != pMapping->getInputMappings().constEnd() && it.value().options.testFlag(MidiOption::Script) && @@ -667,3 +677,13 @@ QJSValue MidiController::makeInputHandler(int status, int midino, const QJSValue pMapping->addInputMapping(inputMapping.key.key, inputMapping); return pJsEngine->newQObject(new MidiInputHandleJSProxy(pMapping, inputMapping)); } + +std::shared_ptr MidiController::getSharedMapping() const { +#ifdef __cpp_lib_atomic_shared_ptr + // Used Spinlock + return m_pMapping.load(std::memory_order_relaxed); +#else + // Uses Mutex + return std::atomic_load_explicit(&m_pMapping, std::memory_order_relaxed); +#endif +} diff --git a/src/controllers/midi/midicontroller.h b/src/controllers/midi/midicontroller.h index 25947e8c791..6b6db0531c4 100644 --- a/src/controllers/midi/midicontroller.h +++ b/src/controllers/midi/midicontroller.h @@ -43,7 +43,7 @@ class MidiController : public Controller { virtual std::shared_ptr cloneMapping() override; bool isMappable() const override { - std::shared_ptr pMapping = m_pMapping; + std::shared_ptr pMapping = getSharedMapping(); if (!pMapping) { return false; } @@ -104,10 +104,17 @@ class MidiController : public Controller { void createOutputHandlers(); void updateAllOutputs(); void destroyOutputHandlers(); + std::shared_ptr getSharedMapping() const; QHash m_temporaryInputMappings; QList m_outputs; + +#ifdef __cpp_lib_atomic_shared_ptr + std::atomic> m_pMapping; +#else std::shared_ptr m_pMapping; +#endif + SoftTakeoverCtrl m_st; QList> m_fourteen_bit_queued_mappings;