diff --git a/src/control/controlindicator.h b/src/control/controlindicator.h index ec16857b438..8557805af50 100644 --- a/src/control/controlindicator.h +++ b/src/control/controlindicator.h @@ -35,7 +35,7 @@ class ControlIndicator : public ControlObject { }; private: - enum BlinkValue m_blinkValue; + std::atomic m_blinkValue; parented_ptr m_pCOIndicator250millis; parented_ptr m_pCOIndicator500millis; }; diff --git a/src/mixxxapplication.cpp b/src/mixxxapplication.cpp index 3d45fe052b3..53312f762f0 100644 --- a/src/mixxxapplication.cpp +++ b/src/mixxxapplication.cpp @@ -140,29 +140,29 @@ void MixxxApplication::registerMetaTypes() { qRegisterMetaType("mixxx::FileInfo"); } -bool MixxxApplication::notify(QObject* target, QEvent* event) { +bool MixxxApplication::notify(QObject* pTarget, QEvent* pEvent) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // All touch events are translated into two simultaneous events: one for // the target QWidgetWindow and one for the target QWidget. // A second touch becomes a mouse move without additional press and release // events. - switch (event->type()) { + switch (pEvent->type()) { case QEvent::MouseButtonPress: { - QMouseEventEditable* mouseEvent = - static_cast(event); // clazy:exclude=wrong-qevent-cast - if (mouseEvent->source() == Qt::MouseEventSynthesizedByQt && - mouseEvent->button() == Qt::LeftButton && + QMouseEventEditable* pMouseEvent = + static_cast(pEvent); // clazy:exclude=wrong-qevent-cast + if (pMouseEvent->source() == Qt::MouseEventSynthesizedByQt && + pMouseEvent->button() == Qt::LeftButton && touchIsRightButton()) { // Assert the assumption that QT synthesizes only one click at a time // = two events (see above) VERIFY_OR_DEBUG_ASSERT(m_rightPressedButtons < 2) { break; } - mouseEvent->setButton(Qt::RightButton); + pMouseEvent->setButton(Qt::RightButton); m_rightPressedButtons++; } #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 4) && defined(__APPLE__) - if (mouseEvent->button() == Qt::RightButton && mouseEvent->buttons() == Qt::LeftButton) { + if (pMouseEvent->button() == Qt::RightButton && pMouseEvent->buttons() == Qt::LeftButton) { // Workaround for a bug in Qt 5.12 qnsview_mouse.mm, where the wrong value is // assigned to the event's mouseState for simulated rightbutton press events // (using ctrl+leftbotton), which results in a missing release event for that @@ -170,18 +170,18 @@ bool MixxxApplication::notify(QObject* target, QEvent* event) { // // Fixed in Qt 5.12.5. See // https://github.com/qt/qtbase/commit/9a47768b46f5e5eed407b70dfa9183fa1d21e242 - mouseEvent->setButtons(Qt::RightButton); + pMouseEvent->setButtons(Qt::RightButton); } #endif break; } case QEvent::MouseButtonRelease: { - QMouseEventEditable* mouseEvent = - static_cast(event); // clazy:exclude=wrong-qevent-cast - if (mouseEvent->source() == Qt::MouseEventSynthesizedByQt && - mouseEvent->button() == Qt::LeftButton && + QMouseEventEditable* pMouseEvent = + static_cast(pEvent); // clazy:exclude=wrong-qevent-cast + if (pMouseEvent->source() == Qt::MouseEventSynthesizedByQt && + pMouseEvent->button() == Qt::LeftButton && m_rightPressedButtons > 0) { - mouseEvent->setButton(Qt::RightButton); + pMouseEvent->setButton(Qt::RightButton); m_rightPressedButtons--; } break; @@ -197,18 +197,27 @@ bool MixxxApplication::notify(QObject* target, QEvent* event) { time.start(); } - bool ret = QApplication::notify(target, event); - - if (m_isDeveloper && time.elapsed() > kEventNotifyExecTimeWarningThreshold) { - qDebug() << "Processing event type" - << event->type() - << "for object" - << target->metaObject()->className() - << target->objectName() - << "running in thread:" - << target->thread()->objectName() - << "took" - << time.elapsed().debugMillisWithUnit(); + bool ret = QApplication::notify(pTarget, pEvent); + + if (m_isDeveloper && + time.elapsed() > kEventNotifyExecTimeWarningThreshold) { + if (pEvent->type() == QEvent::DeferredDelete) { + // pTarget can be already dangling in case of DeferredDelete + qDebug() << "Processing QEvent::DeferredDelete" + << "for object" + << static_cast(pTarget) // will print dangling address + << "took" + << time.elapsed().debugMillisWithUnit(); + } else { + qDebug() << "Processing" + << pEvent->type() + << "for object" + << pTarget // will print address, class and object name + << "running in thread:" + << pTarget->thread()->objectName() + << "took" + << time.elapsed().debugMillisWithUnit(); + } } return ret; diff --git a/src/waveform/visualplayposition.cpp b/src/waveform/visualplayposition.cpp index bb7cfc9ea93..825101aece5 100644 --- a/src/waveform/visualplayposition.cpp +++ b/src/waveform/visualplayposition.cpp @@ -11,9 +11,9 @@ PerformanceTimer VisualPlayPosition::m_timeInfoTime; double VisualPlayPosition::m_dCallbackEntryToDacSecs = 0; VisualPlayPosition::VisualPlayPosition(const QString& key) - : m_valid(false), - m_key(key), - m_noTransport(false) { + : m_valid{false}, + m_key{key}, + m_noTransport{false} { } VisualPlayPosition::~VisualPlayPosition() { @@ -53,7 +53,7 @@ void VisualPlayPosition::set( // Atomic write m_data.setValue(data); - m_valid = true; + m_valid.store(true); } double VisualPlayPosition::calcOffsetAtNextVSync( @@ -162,7 +162,7 @@ double VisualPlayPosition::determinePlayPosInLoopBoundries( } double VisualPlayPosition::getAtNextVSync(VSyncThread* pVSyncThread) { - if (m_valid) { + if (m_valid.load()) { const VisualPlayPositionData data = m_data.getValue(); const double offset = calcOffsetAtNextVSync(pVSyncThread, data); @@ -174,7 +174,7 @@ double VisualPlayPosition::getAtNextVSync(VSyncThread* pVSyncThread) { void VisualPlayPosition::getPlaySlipAtNextVSync(VSyncThread* pVSyncThread, double* pPlayPosition, double* pSlipPosition) { - if (m_valid) { + if (m_valid.load()) { const VisualPlayPositionData data = m_data.getValue(); const double offset = calcOffsetAtNextVSync(pVSyncThread, data); @@ -190,7 +190,7 @@ void VisualPlayPosition::getPlaySlipAtNextVSync(VSyncThread* pVSyncThread, } double VisualPlayPosition::getEnginePlayPos() { - if (m_valid) { + if (m_valid.load()) { VisualPlayPositionData data = m_data.getValue(); return data.m_playPos; } else { @@ -199,7 +199,7 @@ double VisualPlayPosition::getEnginePlayPos() { } void VisualPlayPosition::getTrackTime(double* pPlayPosition, double* pTempoTrackSeconds) { - if (m_valid) { + if (m_valid.load()) { VisualPlayPositionData data = m_data.getValue(); *pPlayPosition = data.m_playPos; *pTempoTrackSeconds = data.m_tempoTrackSeconds; diff --git a/src/waveform/visualplayposition.h b/src/waveform/visualplayposition.h index 71532d07d2f..a222799e1a9 100644 --- a/src/waveform/visualplayposition.h +++ b/src/waveform/visualplayposition.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "control/controlvalue.h" #include "engine/slipmodestate.h" @@ -83,15 +84,17 @@ class VisualPlayPosition : public QObject { // This is called by SoundDevicePortAudio just after the callback starts. static void setCallbackEntryToDacSecs(double secs, const PerformanceTimer& time); - void setInvalid() { m_valid = false; }; + void setInvalid() { + m_valid.store(false); + }; bool isValid() const { - return m_valid; + return m_valid.load(); } private: double calcOffsetAtNextVSync(VSyncThread* pVSyncThread, const VisualPlayPositionData& data); ControlValueAtomic m_data; - bool m_valid; + std::atomic m_valid; QString m_key; bool m_noTransport; diff --git a/src/waveform/vsyncthread.h b/src/waveform/vsyncthread.h index 48ded9f5f08..fb30e71ee4d 100644 --- a/src/waveform/vsyncthread.h +++ b/src/waveform/vsyncthread.h @@ -71,8 +71,8 @@ class VSyncThread : public QThread { // phase locked loop std::mutex m_pllMutex; PerformanceTimer m_pllTimer; - int m_pllInitCnt; - bool m_pllPendingUpdate; + std::atomic m_pllInitCnt; + std::atomic m_pllPendingUpdate; double m_pllInitSum; double m_pllInitAvg; double m_pllPhaseOut;