diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-03-30 13:39:09 (GMT) |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2011-03-30 13:57:45 (GMT) |
commit | a3524950a04329b7f37f0d1107902a59f86b2c3b (patch) | |
tree | bba4bfbfad73f41fe300b272f397c2cf98c4be50 | |
parent | b69d64dfe615bbbfbaf317debbab5b9933895b4a (diff) | |
download | Qt-a3524950a04329b7f37f0d1107902a59f86b2c3b.zip Qt-a3524950a04329b7f37f0d1107902a59f86b2c3b.tar.gz Qt-a3524950a04329b7f37f0d1107902a59f86b2c3b.tar.bz2 |
Fixed dead-locks in XCB window surface.
Move the mutex lock into the window surface instead of belonging to the
QXcbShmImage, which will be destroyed and recreated in resize().
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindowsurface.cpp | 21 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindowsurface.h | 3 |
2 files changed, 11 insertions, 13 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp index 8ab0140..c90ebb5 100644 --- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp +++ b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp @@ -44,7 +44,6 @@ #include "qxcbconnection.h" #include "qxcbscreen.h" #include "qxcbwindow.h" -#include "qmutex.h" #include <xcb/shm.h> #include <xcb/xcb_image.h> @@ -65,9 +64,6 @@ public: void put(xcb_window_t window, const QPoint &dst, const QRect &source); void preparePaint(const QRegion ®ion); - void lock() { m_surfaceLock.lock(); } - void unlock() { m_surfaceLock.unlock(); } - private: void destroy(); @@ -81,7 +77,6 @@ private: xcb_window_t m_gc_window; QRegion m_dirty; - QMutex m_surfaceLock; }; QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size) @@ -114,7 +109,8 @@ void QXcbShmImage::destroy() xcb_image_destroy(m_xcb_image); shmdt(m_shm_info.shmaddr); shmctl(m_shm_info.shmid, IPC_RMID, 0); - Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); + if (m_gc) + Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); } void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source) @@ -175,13 +171,13 @@ QPaintDevice *QXcbWindowSurface::paintDevice() void QXcbWindowSurface::beginPaint(const QRegion ®ion) { - m_image->lock(); + m_surfaceLock.lock(); m_image->preparePaint(region); } void QXcbWindowSurface::endPaint(const QRegion &) { - m_image->unlock(); + m_surfaceLock.unlock(); } void QXcbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) @@ -189,18 +185,18 @@ void QXcbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoi Q_UNUSED(region); Q_UNUSED(offset); + connection()->sync(); + QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow()); extern QWidgetData* qt_widget_data(QWidget *); QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft(); - m_image->lock(); + QMutexLocker(&m_surfaceLock); QVector<QRect> rects = region.rects(); for (int i = 0; i < rects.size(); ++i) m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset)); - - m_image->unlock(); } void QXcbWindowSurface::resize(const QSize &size) @@ -209,8 +205,7 @@ void QXcbWindowSurface::resize(const QSize &size) QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window())); - if (m_image) - m_image->lock(); + QMutexLocker(&m_surfaceLock); delete m_image; m_image = new QXcbShmImage(screen, size); diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.h b/src/plugins/platforms/xcb/qxcbwindowsurface.h index f87e122..e508fe6 100644 --- a/src/plugins/platforms/xcb/qxcbwindowsurface.h +++ b/src/plugins/platforms/xcb/qxcbwindowsurface.h @@ -48,6 +48,8 @@ #include "qxcbobject.h" +#include <QMutex> + class QXcbShmImage; class QXcbWindowSurface : public QXcbObject, public QWindowSurface @@ -66,6 +68,7 @@ public: private: QXcbShmImage *m_image; + QMutex m_surfaceLock; }; #endif |