[directfb] Make QDirectFBInput a QThread to allow proper exits
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>
Sun, 18 Sep 2011 22:11:24 +0000 (00:11 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 21 Oct 2011 14:54:45 +0000 (16:54 +0200)
Without this patch the application will get stuck waiting for the
IDFBEventBuffer to report an event. We will use the
IDFBEventBuffer::WakeUp function to interrupt the waiting but this
produces the below error on exit:
QEventLoop: Cannot be used without QApplication
QThread: Destroyed while thread is still running

This is solved by making the QDirectFBInput a QThread, reimplement
the run() method to handle the events. It should work as this is
only posting events to the QApplication event loop.

Change-Id: I24adf2b080f96c72ede6a5499f484ac33fdd44fc
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
src/plugins/platforms/directfb/qdirectfbinput.cpp
src/plugins/platforms/directfb/qdirectfbinput.h
src/plugins/platforms/directfb/qdirectfbintegration.cpp

index d05729b..bedd3b8 100644 (file)
 
 #include <directfb.h>
 
-QDirectFbInput::QDirectFbInput(QObject *parent)
-    : QObject(parent), m_shouldStop(false)
+QDirectFbInput::QDirectFbInput()
+    : m_dfbInterface(QDirectFbConvenience::dfbInterface())
+    , m_shouldStop(false)
 {
-    m_dfbInterface = QDirectFbConvenience::dfbInterface();
-
     DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface,&m_eventBuffer);
     if (ok != DFB_OK)
         DirectFBError("Failed to initialise eventbuffer", ok);
 
     m_dfbInterface->GetDisplayLayer(m_dfbInterface,DLID_PRIMARY, &m_dfbDisplayLayer);
-
 }
 
-void QDirectFbInput::runInputEventLoop()
+void QDirectFbInput::run()
 {
-    while (true) {
-        m_eventBuffer->WaitForEvent(m_eventBuffer);
-        if (m_shouldStop) {
-            m_waitStop.release();
-            break;
-        }
-        handleEvents();
+    while (!m_shouldStop) {
+        if (m_eventBuffer->WaitForEvent(m_eventBuffer) == DFB_OK)
+            handleEvents();
     }
 }
 
 void QDirectFbInput::stopInputEventLoop()
 {
     m_shouldStop = true;
-    m_waitStop.acquire();
+    m_eventBuffer->WakeUp(m_eventBuffer);
 }
 
 void QDirectFbInput::addWindow(DFBWindowID id, QWindow *qt_window)
index 2930069..4165487 100644 (file)
@@ -42,8 +42,7 @@
 #ifndef QDIRECTFBINPUT_H
 #define QDIRECTFBINPUT_H
 
-#include <QSemaphore>
-#include <QObject>
+#include <QThread>
 #include <QHash>
 #include <QPoint>
 #include <QEvent>
 
 #include <directfb.h>
 
-class QDirectFbInput : public QObject
+class QDirectFbInput : public QThread
 {
     Q_OBJECT
 public:
-    QDirectFbInput(QObject *parent);
+    QDirectFbInput();
     void addWindow(DFBWindowID id, QWindow *window);
     void removeWindow(WId wId);
 
-public slots:
-    void runInputEventLoop();
     void stopInputEventLoop();
-    void handleEvents();
+
+protected:
+    void run();
 
 private:
+    void handleEvents();
     void handleMouseEvents(const DFBEvent &event);
     void handleWheelEvent(const DFBEvent &event);
     void handleKeyEvents(const DFBEvent &event);
@@ -78,8 +78,6 @@ private:
     IDirectFBEventBuffer *m_eventBuffer; // XXX: TODO: FIXME: leaked!!! (but it is a singleton)
 
     bool m_shouldStop;
-    QSemaphore m_waitStop;
-
     QHash<DFBWindowID,QWindow *>m_tlwMap;
 };
 
index 96ba391..cc667f4 100644 (file)
@@ -106,17 +106,14 @@ QDirectFbIntegration::QDirectFbIntegration()
     QDirectFbScreen *primaryScreen = new QDirectFbScreen(0);
     screenAdded(primaryScreen);
 
-    m_inputRunner.reset(new QThread);
-    m_input.reset(new QDirectFbInput(0));
-    m_input->moveToThread(m_inputRunner.data());
-    QObject::connect(m_inputRunner.data(), SIGNAL(started()),
-                     m_input.data(), SLOT(runInputEventLoop()));
-    m_inputRunner->start();
+    m_input.reset(new QDirectFbInput());
+    m_input->start();
 }
 
 QDirectFbIntegration::~QDirectFbIntegration()
 {
     m_input->stopInputEventLoop();
+    m_input->wait();
 }
 
 QPlatformPixmap *QDirectFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const