summaryrefslogtreecommitdiff
path: root/src/shared/trk/trkdevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/trk/trkdevice.cpp')
-rw-r--r--src/shared/trk/trkdevice.cpp60
1 files changed, 50 insertions, 10 deletions
diff --git a/src/shared/trk/trkdevice.cpp b/src/shared/trk/trkdevice.cpp
index a303ba1c2d..a76cff79c2 100644
--- a/src/shared/trk/trkdevice.cpp
+++ b/src/shared/trk/trkdevice.cpp
@@ -436,15 +436,52 @@ void WriterThread::terminate()
}
#ifdef Q_OS_WIN
-static inline bool overlappedSyncWrite(HANDLE file, const char *data,
+
+static inline QString msgTerminated(int size)
+{
+ return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size);
+}
+
+// Interruptible synchronous write function.
+static inline bool overlappedSyncWrite(HANDLE file,
+ const bool &terminateFlag,
+ const char *data,
DWORD size, DWORD *charsWritten,
- OVERLAPPED *overlapped)
+ OVERLAPPED *overlapped,
+ QString *errorMessage)
{
if (WriteFile(file, data, size, charsWritten, overlapped))
return true;
- if (GetLastError() != ERROR_IO_PENDING)
+ const DWORD writeError = GetLastError();
+ if (writeError != ERROR_IO_PENDING) {
+ *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError));
+ return false;
+ }
+ // Wait for written or thread terminated
+ const DWORD timeoutMS = 200;
+ const unsigned maxAttempts = 20;
+ DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS);
+ for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag;
+ wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++);
+ if (terminateFlag) {
+ *errorMessage = msgTerminated(size);
+ return false;
+ }
+ switch (wr) {
+ case WAIT_OBJECT_0:
+ break;
+ case WAIT_TIMEOUT:
+ *errorMessage = QString::fromLatin1("Write timed out.");
+ return false;
+ default:
+ *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError()));
+ return false;
+ }
+ if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) {
+ *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError()));
return false;
- return GetOverlappedResult(file, overlapped, charsWritten, TRUE);
+ }
+ return true;
}
#endif
@@ -453,8 +490,7 @@ bool WriterThread::write(const QByteArray &data, QString *errorMessage)
QMutexLocker locker(&m_context->mutex);
#ifdef Q_OS_WIN
DWORD charsWritten;
- if (!overlappedSyncWrite(m_context->device, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped)) {
- *errorMessage = QString::fromLatin1("Error writing data: %1").arg(winErrorMessage(GetLastError()));
+ if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) {
return false;
}
FlushFileBuffers(m_context->device);
@@ -473,8 +509,10 @@ bool WriterThread::trkWriteRawMessage(const TrkMessage &msg)
const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame);
QString errorMessage;
const bool rc = write(ba, &errorMessage);
- if (!rc)
+ if (!rc) {
+ qWarning("%s\n", qPrintable(errorMessage));
emit error(errorMessage);
+ }
return rc;
}
@@ -844,7 +882,7 @@ TrkDevice::~TrkDevice()
bool TrkDevice::open(const QString &port, QString *errorMessage)
{
if (d->verbose)
- qDebug() << "Opening" << port << "is open: " << isOpen();
+ qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame();
close();
#ifdef Q_OS_WIN
d->deviceContext->device = CreateFile(port.toStdWString().c_str(),
@@ -917,8 +955,10 @@ void TrkDevice::close()
{
if (!isOpen())
return;
- d->readerThread->terminate();
- d->writerThread->terminate();
+ if (d->readerThread)
+ d->readerThread->terminate();
+ if (d->writerThread)
+ d->writerThread->terminate();
#ifdef Q_OS_WIN
CloseHandle(d->deviceContext->device);
d->deviceContext->device = INVALID_HANDLE_VALUE;