Hi,
Under Windows CE6 R3/Embedded Compact 7, QT 4.7.3, built against the Windows Mobile Professional 6 SDK, the following error message is displayed under two different conditions:
QThread internal error while waiting for adopted threads error: 6
The error code here appears to indicate the thread code is referencing an invalid handle.
First scenario:
This code is taken from an online example for capturing and playing audio
void DlgVolumeSettings:nPlayClicked(void)
{
qDebug("onPlayClicked\r");
inputFile.setFileName(RAW_AUDIO_FILENAME);
inputFile.open(QIODevice::ReadOnly);
QAudioFormat format;
// Set up the format, eg.
format.setFrequency(8000);
format.setChannels(1);
format.setSampleSize(8);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format)) {
qWarning()<<"raw audio format not supported by backend, cannot play audio.";
return;
}
audioOut = new QAudioOutput(format, this);
connect(audioOut,SIGNAL(stateChanged(QAudio::State )),SLOT(finishedPlaying(QAudio::State)));
audioOut->start(&inputFile);
}
void DlgVolumeSettings::finishedPlaying(QAudio::State state)
{
qDebug("finishedPlaying\r");
if(state == QAudio::IdleState)
{
audioOut->stop();
inputFile.close();
delete(audioOut);
}
}
Here, as soon as audioOut->Start is called, these messages are observed.
Scenario 2:
A class is used to make a call into a DLL. During this call, it passes pointers to the DLL to it's own static methods, which are used as callbacks from the DLL. Upon the DLL calling these callbacks, this same error message is generated. Here is the QT code being invoked:
From qthread_win.cpp
/*! \internal
This function loops and waits for native adopted threads to finish.
When this happens it derefs the QThreadData for the adopted thread
to make sure it gets cleaned up properly.
*/
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();
#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
CloseHandle(qt_adopted_thread_handles.at(handleInd ex));
#endif
QMutexLocker lock(&qt_adopted_thread_watcher_mutex);
qt_adopted_thread_handles.remove(handleIndex);
qt_adopted_qthreads.remove(qthreadIndex);
}
}
}
It's not clear to me if and how to implement a work-around for these scenarios. Under the same conditions for a Windows desktop build, these warning messages are not generated. Thanks,
Nick
Bookmarks