QThread internal error while waiting for adopted threads: 87
I'm occasionally seeing the above warning in my pyqt app. It looks like it's coming from the qthread watch dog. Any ideas? I don't specifically create any QThreads - just use regular python threads, gstreamer threads, and signal back to the gui thread. I typically see this when launching some QDialog's and then it stops when I close one or open another qdialog. Also, the error code 87 means ERROR_INVALID_PARAMETER ...
Qt watch dog code snippet where the warning is coming from:
void qt_adopted_thread_watcher_function(void *)
{
forever {
qt_adopted_thread_watcher_mutex.lock();
if (qt_adopted_thread_handles.count() == 1) {
qt_adopted_thread_watcher_handle = 0;
qt_adopted_thread_watcher_mutex.unlock();
break;
}
QVector<HANDLE> handlesCopy = qt_adopted_thread_handles;
qt_adopted_thread_watcher_mutex.unlock();
DWORD ret = WAIT_TIMEOUT;
int loops = (handlesCopy.count() / MAXIMUM_WAIT_OBJECTS) + 1, offset, count;
if (loops == 1) {
// no need to loop, no timeout
offset = 0;
count = handlesCopy.count();
ret = WaitForMultipleObjects(handlesCopy.count(), handlesCopy.constData(), false, INFINITE);
} else {
int loop = 0;
do {
offset = loop * MAXIMUM_WAIT_OBJECTS;
count = qMin(handlesCopy.count() - offset, MAXIMUM_WAIT_OBJECTS);
ret = WaitForMultipleObjects(count, handlesCopy.constData() + offset, false, 100);
loop = (loop + 1) % loops;
} while (ret == WAIT_TIMEOUT);
}
if (ret == WAIT_FAILED || !(ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + uint(count))) {
qWarning("QThread internal error while waiting for adopted threads: %d", int(GetLastError()));
continue;
}
const int handleIndex = offset + ret - WAIT_OBJECT_0;
if (handleIndex == 0){
// New handle to watch was added.
continue;
} else {
// printf("(qt) - qt_adopted_thread_watcher_function... called\n");
const int qthreadIndex = handleIndex - 1;
QThreadData::get2(qt_adopted_qthreads.at(qthreadIn dex))->deref();
CloseHandle(qt_adopted_thread_handles.at(handleInd ex));
QMutexLocker lock(&qt_adopted_thread_watcher_mutex);
qt_adopted_thread_handles.remove(handleIndex);
qt_adopted_qthreads.remove(qthreadIndex);
}
}
}
Re: QThread internal error while waiting for adopted threads: 87
Re: QThread internal error while waiting for adopted threads: 87
Try reproducing the problem with a simple example.
Re: QThread internal error while waiting for adopted threads: 87
I have the same problem. It's a small bug in Qt. It won't make much trouble, but It's annoying. The problem ist hier:
int loops = (handlesCopy.count() / MAXIMUM_WAIT_OBJECTS) + 1, offset, count;
...
int loop = 0;
do {
offset = loop * MAXIMUM_WAIT_OBJECTS;
count = qMin(handlesCopy.count() - offset, MAXIMUM_WAIT_OBJECTS);
ret = WaitForMultipleObjects(count, handlesCopy.constData() + offset, false, 100);
loop = (loop + 1) % loops;
} while (ret == WAIT_TIMEOUT);
If handlesCopy.count() % MAXIMUM_WAIT_OBJECTS == 0, then the last call to WaitForMultipleObjects will have count == 0.
For example, if you habe 64 (== MAXIMUM_WAIT_OBJECTS) Threads, then loop will be 2. The first call will habe 64 handles. And the second one will habe 0 handles.
But see MSDN for WaitForMultipleObjects:
nCount [in]
The number of object handles in the array pointed to by lpHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS. This parameter cannot be zero.
The nCount CAN NOT BE ZERO. That is why you get this message.
The possible work around is not to call QThread::currentThread() in threads started not over QThread. Because in this case the adopted threads are used. In my case, I used Recursive QMutex. This also leads to calling QThreadData::current().
So in my case, I will just not use QMutex classe in non-QThread threads.
Why is this bug STILL OPEN AFTER 3 YEARS ???? :-(
The fix would be
int loops = (handlesCopy.count() / MAXIMUM_WAIT_OBJECTS), offset, count;
if ( (handlesCopy.count() % MAXIMUM_WAIT_OBJECTS) > 0 )
{
loops++
}