From e82219b344ee471dbb5d8e7f1351404ff9616d6c Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Fri, 12 Mar 2010 09:27:42 +0100
Subject: [PATCH] Symbian: Fix crash when launching trk on device after
 canceled prompt.

Introduce clearWriteQueue to TrkDevice and call it a device is
released to the SymbianDeviceManager in state 'open'.
In addition, if a launcher is destroyed before the protocol is through,
close the device (if the closeDevice property is set).
Task-number: QTCREATORBUG-858
---
 src/shared/symbianutils/launcher.cpp           |  3 +++
 .../symbianutils/symbiandevicemanager.cpp      |  2 ++
 src/shared/symbianutils/trkdevice.cpp          | 18 ++++++++++++++++++
 src/shared/symbianutils/trkdevice.h            |  3 +++
 4 files changed, 26 insertions(+)

diff --git a/src/shared/symbianutils/launcher.cpp b/src/shared/symbianutils/launcher.cpp
index 3bf0f134155..f91bb1e93d0 100644
--- a/src/shared/symbianutils/launcher.cpp
+++ b/src/shared/symbianutils/launcher.cpp
@@ -94,6 +94,9 @@ Launcher::Launcher(Actions startupActions,
 
 Launcher::~Launcher()
 {
+    // Destroyed before protocol was through: Close
+    if (d->m_closeDevice && d->m_device->isOpen())
+        d->m_device->close();
     emit destroyed(d->m_device->port());
     logMessage("Shutting down.\n");
     delete d;
diff --git a/src/shared/symbianutils/symbiandevicemanager.cpp b/src/shared/symbianutils/symbiandevicemanager.cpp
index d92a07919a8..8bc3cdd1c85 100644
--- a/src/shared/symbianutils/symbiandevicemanager.cpp
+++ b/src/shared/symbianutils/symbiandevicemanager.cpp
@@ -165,6 +165,8 @@ void SymbianDevice::releaseDevice(TrkDevicePtr *ptr /* = 0 */)
         qDebug() << "SymbianDevice::releaseDevice" << m_data->portName
                 << " open: " << isOpen();
     if (m_data->deviceAcquired) {
+        if (m_data->device->isOpen())
+            m_data->device->clearWriteQueue();
         // Release if a valid pointer was passed in.
         if (ptr && !ptr->isNull()) {
             ptr->data()->disconnect();
diff --git a/src/shared/symbianutils/trkdevice.cpp b/src/shared/symbianutils/trkdevice.cpp
index 8ba23aee03a..72d91723a8b 100644
--- a/src/shared/symbianutils/trkdevice.cpp
+++ b/src/shared/symbianutils/trkdevice.cpp
@@ -208,7 +208,10 @@ void TrkWriteQueue::clear()
     m_trkWriteToken = 0;
     m_trkWriteBusy = false;
     m_trkWriteQueue.clear();
+    const int discarded = m_writtenTrkMessages.size();
     m_writtenTrkMessages.clear();
+    if (verboseTrk)
+        qDebug() << "TrkWriteQueue::clear: discarded " << discarded;
 }
 
 byte TrkWriteQueue::nextTrkWriteToken()
@@ -360,6 +363,8 @@ public:
                         const QByteArray &data, const QVariant &cookie);
     void queueTrkInitialPing();
 
+    void clearWriteQueue();
+
     // Call this from the device read notification with the results.
     void slotHandleResult(const TrkResult &result);
 
@@ -565,6 +570,13 @@ void WriterThread::queueTrkMessage(byte code, TrkCallback callback,
     tryWrite();
 }
 
+void WriterThread::clearWriteQueue()
+{
+    m_dataMutex.lock();
+    m_queue.clear();
+    m_dataMutex.unlock();
+}
+
 void WriterThread::queueTrkInitialPing()
 {
     m_dataMutex.lock();
@@ -1092,6 +1104,12 @@ void TrkDevice::emitError(const QString &s)
     emit error(s);
 }
 
+void TrkDevice::clearWriteQueue()
+{
+    if (isOpen())
+        d->writerThread->clearWriteQueue();
+}
+
 void TrkDevice::sendTrkMessage(byte code, TrkCallback callback,
      const QByteArray &data, const QVariant &cookie)
 {
diff --git a/src/shared/symbianutils/trkdevice.h b/src/shared/symbianutils/trkdevice.h
index a5ddc558984..9c2f1f29292 100644
--- a/src/shared/symbianutils/trkdevice.h
+++ b/src/shared/symbianutils/trkdevice.h
@@ -101,6 +101,9 @@ public:
     // Send an Ack synchronously, bypassing the queue
     bool sendTrkAck(unsigned char token);
 
+public slots:
+    void clearWriteQueue();
+
 signals:
     void messageReceived(const trk::TrkResult &result);
     // Emitted with the contents of messages enclosed in 07e, not for log output
-- 
GitLab