Browse Source

joystick: fix crash on app exit

This fixes a pure virtual method call exception during exit when a joystick
is connected.

The problem was that ~Joystick() waited for the thread to exit, while the
thread called the virtual method _close(). But at this point the destructor
of the derived class (JoystickSDL in my case) was already called.

To resolve the problem a separate stop() method is added that is called
before deleting the object.
QGC4.4
Beat Küng 4 years ago committed by Don Gagne
parent
commit
538b448ae0
  1. 9
      src/Joystick/Joystick.cc
  2. 6
      src/Joystick/Joystick.h
  3. 1
      src/Joystick/JoystickManager.cc

9
src/Joystick/Joystick.cc

@ -121,10 +121,17 @@ Joystick::Joystick(const QString& name, int axisCount, int buttonCount, int hatC
connect(_multiVehicleManager, &MultiVehicleManager::activeVehicleChanged, this, &Joystick::_activeVehicleChanged); connect(_multiVehicleManager, &MultiVehicleManager::activeVehicleChanged, this, &Joystick::_activeVehicleChanged);
} }
Joystick::~Joystick() void Joystick::stop()
{ {
_exitThread = true; _exitThread = true;
wait(); wait();
}
Joystick::~Joystick()
{
if (!_exitThread) {
qWarning() << "Joystick thread still running!";
}
delete[] _rgAxisValues; delete[] _rgAxisValues;
delete[] _rgCalibration; delete[] _rgCalibration;
delete[] _rgButtonValues; delete[] _rgButtonValues;

6
src/Joystick/Joystick.h

@ -18,6 +18,7 @@
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "MultiVehicleManager.h" #include "MultiVehicleManager.h"
#include <atomic>
Q_DECLARE_LOGGING_CATEGORY(JoystickLog) Q_DECLARE_LOGGING_CATEGORY(JoystickLog)
Q_DECLARE_LOGGING_CATEGORY(JoystickValuesLog) Q_DECLARE_LOGGING_CATEGORY(JoystickValuesLog)
@ -53,7 +54,7 @@ class Joystick : public QThread
public: public:
Joystick(const QString& name, int axisCount, int buttonCount, int hatCount, MultiVehicleManager* multiVehicleManager); Joystick(const QString& name, int axisCount, int buttonCount, int hatCount, MultiVehicleManager* multiVehicleManager);
~Joystick(); virtual ~Joystick();
typedef struct Calibration_t { typedef struct Calibration_t {
int min; int min;
@ -137,6 +138,7 @@ public:
void setFunctionAxis(AxisFunction_t function, int axis); void setFunctionAxis(AxisFunction_t function, int axis);
int getFunctionAxis(AxisFunction_t function); int getFunctionAxis(AxisFunction_t function);
void stop();
/* /*
// Joystick index used by sdl library // Joystick index used by sdl library
@ -263,7 +265,7 @@ protected:
uint8_t*_rgButtonValues = nullptr; uint8_t*_rgButtonValues = nullptr;
bool _exitThread = false; ///< true: signal thread to exit std::atomic<bool> _exitThread{false}; ///< true: signal thread to exit
bool _calibrationMode = false; bool _calibrationMode = false;
int* _rgAxisValues = nullptr; int* _rgAxisValues = nullptr;
Calibration_t* _rgCalibration = nullptr; Calibration_t* _rgCalibration = nullptr;

1
src/Joystick/JoystickManager.cc

@ -38,6 +38,7 @@ JoystickManager::~JoystickManager() {
QMap<QString, Joystick*>::iterator i; QMap<QString, Joystick*>::iterator i;
for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) { for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
qCDebug(JoystickManagerLog) << "Releasing joystick:" << i.key(); qCDebug(JoystickManagerLog) << "Releasing joystick:" << i.key();
i.value()->stop();
delete i.value(); delete i.value();
} }
qDebug() << "Done"; qDebug() << "Done";

Loading…
Cancel
Save