I have a QThread running some code and I wanted it to do exit nicely and do some cleanings so the code goes as:
testdevice.h
class testDevice : public QThread
{
Q_OBJECT
... // some definitions
protected:
void run(void);
private:
hid_device *handle;
bool abort;
public:
~testDevice(void);
};
testdevice.cpp
testDevice::~testDevice(void)
{
mutex.lock();
abort = true;
mutex.unlock();
wait();
if (handle != NULL)
{
hid_close(handle);
}
hid_exit();
}
void testDevice::run(void)
{
while(true)
{
mutex.lock();
if(abort)
{
return;
}
mutex.unlock();
if (_connected)
{
//... more code
}
else // Case device is not connected
{
emit deviceConnected(_connected);// A breakpoint in here is not triggered after abort is true
handle = hid_open(TEST_VID, TEST_PID, NULL); // this is where VS2010 shows the error "Unhandled exception at 0x71241a95 in project.exe: 0xC0000005: Access violation."
//...code continues
The behaviour I was expecting was run()
to be called and when ~testDevice()
destructor is called abort
is set to true
and wait
blocks the destructor, and run
returns and then the destructor continues.
What is happening is that run()
is called and when I close the application the destructors ~testDevice()
is called and abort
is set to true
and wait()
returns and the destructor finishes...BUT then run()
keeps running and I get Unhandled exception at 0x71241a95 in project.exe: 0xC0000005: Access violation.....I am running this as VS2010 debug, if I place breakpoints I get this all the time, but with no breakpoints I just got this once in a while...any clues?
Something weird is that when I place a breakpoint in abort = true;
sometimes the first breakpoint that hits in there has a small blue '!' sign, and the second time it hits is a regular all red one. The same happens for the breakpoint at emit deviceConnected(_connected);
but this is kinda random as well...I dont know what this '!' means...could all of this be a debug problem?
My general suspicion is that HIDAPI is running in a separate thread and it has its own bugs when someone call hid_exit();
maybe hid_read();
continues to run and since hid_quit();
was called, hid_read();
looses some pointers and doesnt close...just a wild shot and to confirm this I need some developer at the HIDAPI to come foward and say something...I hope they read this
You seem to be using
QThread
in a custom way rather than the usualstart()
andquit()
execution. The best would be that in an ideal world if you could refactor your code usingquit()
for quiting aQThread
since that would be closer to the signal/slot mechanism of this QObject subclass.However, I agree that it is not always possible. I cannot yet tell you based on your few lines you provided that it would make sense in this particular case, but at least I would encourage you to think about it.
Also, you could possibly use the
QWaitCondition
for waiting for something to happen rather than low-level or/and customwait()
calls.As for quickly working around the issue you are facing if the issue at hand is compiler optimization of a boolean value like putting it into the cache, you could try having making it atomic by using the std::atomic (C++11) or QAtomicInt option. This will make sure that the compiler cannot optimize the reads and writes out.
You would write something like this with the std typedef:
If you need to support pre C++-11 compilers as well as Qt 4, you would use the Qt class like this: