Fix a deadlock in GPIO monitor

pull/8/head
Michael Zanetti 2021-11-19 23:39:18 +01:00
parent 8d300d84c5
commit 530fc9130a
3 changed files with 7 additions and 15 deletions

View File

@ -139,6 +139,7 @@ Gpio::Gpio(int gpio, QObject *parent) :
m_direction(Gpio::DirectionInvalid), m_direction(Gpio::DirectionInvalid),
m_gpioDirectory(QDir(QString("/sys/class/gpio/gpio%1").arg(QString::number(gpio)))) m_gpioDirectory(QDir(QString("/sys/class/gpio/gpio%1").arg(QString::number(gpio))))
{ {
qRegisterMetaType<Gpio::Value>();
} }

View File

@ -81,8 +81,8 @@ GpioMonitor::GpioMonitor(int gpio, QObject *parent) :
m_gpioNumber(gpio) m_gpioNumber(gpio)
{ {
// Inform about the thread status // Inform about the thread status
connect(this, &GpioMonitor::started, this, &GpioMonitor::onThreadStarted, Qt::DirectConnection); connect(this, &GpioMonitor::started, this, &GpioMonitor::onThreadStarted);
connect(this, &GpioMonitor::finished, this, &GpioMonitor::onThreadFinished, Qt::DirectConnection); connect(this, &GpioMonitor::finished, this, &GpioMonitor::onThreadFinished);
} }
/*! Destroys and unexports the Gpio. */ /*! Destroys and unexports the Gpio. */
@ -130,7 +130,6 @@ void GpioMonitor::setActiveLow(bool activeLow)
/*! Returns the current value of the Gpio. */ /*! Returns the current value of the Gpio. */
Gpio::Value GpioMonitor::value() Gpio::Value GpioMonitor::value()
{ {
QMutexLocker valueLocker(&m_valueMutex);
return m_value; return m_value;
} }
@ -140,9 +139,8 @@ bool GpioMonitor::enabled() const
return m_enabled; return m_enabled;
} }
void GpioMonitor::setValue(Gpio::Value value) void GpioMonitor::onValueChanged(Gpio::Value value)
{ {
QMutexLocker valueLocker(&m_valueMutex);
m_value = value; m_value = value;
switch (m_value) { switch (m_value) {
@ -241,11 +239,8 @@ void GpioMonitor::run()
// Notify the main thread about the interrupt // Notify the main thread about the interrupt
readStream >> valueString; readStream >> valueString;
if (valueString == "0") { Gpio::Value value = valueString == "1" ? Gpio::ValueHigh : Gpio::ValueLow;
setValue(Gpio::ValueLow); QMetaObject::invokeMethod(this, "onValueChanged", Qt::QueuedConnection, Q_ARG(Gpio::Value, value));
} else {
setValue(Gpio::ValueHigh);
}
} }
} }
@ -280,7 +275,6 @@ bool GpioMonitor::enable()
return false; return false;
} }
QMutexLocker locker(&m_stopMutex);
m_stop = false; m_stop = false;
// Everything looks good, lets start the poll thread and inform about the result // Everything looks good, lets start the poll thread and inform about the result
@ -294,6 +288,5 @@ void GpioMonitor::disable()
qCDebug(dcGpio()) << "Disabling gpio monitor"; qCDebug(dcGpio()) << "Disabling gpio monitor";
// Stop the thread if not already disabled // Stop the thread if not already disabled
QMutexLocker locker(&m_stopMutex); QMutexLocker locker(&m_stopMutex);
if (m_stop) return;
m_stop = true; m_stop = true;
} }

View File

@ -62,14 +62,11 @@ private:
bool m_activeLow = true; bool m_activeLow = true;
bool m_enabled = false; bool m_enabled = false;
// Thread stuff
QMutex m_valueMutex;
Gpio::Value m_value = Gpio::ValueInvalid; Gpio::Value m_value = Gpio::ValueInvalid;
QMutex m_stopMutex; QMutex m_stopMutex;
bool m_stop = false; bool m_stop = false;
void setValue(Gpio::Value value);
void setEnabled(bool enabled); void setEnabled(bool enabled);
protected: protected:
@ -82,6 +79,7 @@ signals:
private slots: private slots:
void onThreadStarted(); void onThreadStarted();
void onThreadFinished(); void onThreadFinished();
void onValueChanged(Gpio::Value value);
public slots: public slots:
bool enable(); bool enable();