From 794c81c1eab54cb58f2143ab3efc90e9c4bf9092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 25 Aug 2011 13:39:07 +0200 Subject: Move XCB event reading to a separate thread. Work-around for bug in XCB which causes a xcb_wait_for_reply to block if xcb_poll_for_events() is called simultaneously from a different thread. If the XCB version is too old this work-around causes even more problems, so we kill two birds with one stone by only using the work-around if the XCB version has the recent xcb_poll_for_queue_event() function, which we also need to read events from a separate thread with reasonable efficiency. Change-Id: I8a899dad6ded381ce42cba0112e77da3c8aa6887 Reviewed-on: http://codereview.qt.nokia.com/3612 Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbconnection.h | 48 +++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms/xcb/qxcbconnection.h') diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 6a80f57972..8c05fe23e4 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -46,7 +46,9 @@ #include #include +#include #include +#include #include #define Q_XCB_DEBUG @@ -100,6 +102,9 @@ namespace QXcbAtom { _QT_SCROLL_DONE, _QT_INPUT_ENCODING, + // Qt/XCB specific + _QT_CLOSE_CONNECTION, + _MOTIF_WM_HINTS, DTWM_IS_RUNNING, @@ -222,6 +227,33 @@ namespace QXcbAtom { }; } +class QXcbEventReader : public QThread +{ + Q_OBJECT +public: + QXcbEventReader(xcb_connection_t *connection) + : m_connection(connection) + { + } + +#ifdef XCB_POLL_FOR_QUEUED_EVENT + void run(); +#endif + + QList *lock(); + void unlock(); + +signals: + void eventPending(); + +private: + void addEvent(xcb_generic_event_t *event); + + QMutex m_mutex; + QList m_events; + xcb_connection_t *m_connection; +}; + class QAbstractEventDispatcher; class QXcbConnection : public QObject { @@ -314,6 +346,8 @@ private: QByteArray m_displayName; + xcb_window_t m_connectionEventListener; + QXcbKeyboard *m_keyboard; QXcbClipboard *m_clipboard; QXcbDrag *m_drag; @@ -322,7 +356,7 @@ private: #if defined(XCB_USE_XLIB) void *m_xlib_display; #endif - + QXcbEventReader *m_reader; #ifdef XCB_USE_DRI2 uint32_t m_dri2_major; uint32_t m_dri2_minor; @@ -345,7 +379,6 @@ private: template friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line); #endif - QVector eventqueue; WindowMapper m_mapper; @@ -359,16 +392,17 @@ private: template xcb_generic_event_t *QXcbConnection::checkEvent(const T &checker) { - while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection())) - eventqueue.append(event); + QList *eventqueue = m_reader->lock(); - for (int i = 0; i < eventqueue.size(); ++i) { - xcb_generic_event_t *event = eventqueue.at(i); + for (int i = 0; i < eventqueue->size(); ++i) { + xcb_generic_event_t *event = eventqueue->at(i); if (checker.check(event)) { - eventqueue[i] = 0; + (*eventqueue)[i] = 0; + m_reader->unlock(); return event; } } + m_reader->unlock(); return 0; } -- cgit v1.2.3