summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Cooksey <thomas.cooksey@nokia.com>2009-07-17 14:17:41 (GMT)
committerTom Cooksey <thomas.cooksey@nokia.com>2009-07-17 14:52:15 (GMT)
commit079f46af1a5821f981fcb53bf7484885f18b5b86 (patch)
tree4d2d62b16ed9de4cde6f1ba080eda47ff4f52cf6 /src
parentb4d801bf4d6e664ad729e3e95b212b83cc0c784f (diff)
downloadQt-079f46af1a5821f981fcb53bf7484885f18b5b86.zip
Qt-079f46af1a5821f981fcb53bf7484885f18b5b86.tar.gz
Qt-079f46af1a5821f981fcb53bf7484885f18b5b86.tar.bz2
Fix deadlock in the QWS server when destroying lots of windows
First, don't call QWSWindowSurface::winId() in the destructor, as it will actually request a new id if there isn't already one around - which is a bit silly and highlighted the "real" bug. Second, make sure QWSDisplay::Data::takeId() asks for 1 new id before waiting for more ids to arrive. This is because waitForCreation() calls QWSServer::processEventQueue(). If the events in the queue cause takeId() to be called, QWSDisplay::Data::takeId() gets called recursively. Even though there will be a create 15 ids command in the queue, that will only allow 15 QWSDisplay::Data::takeId() calls to return. The 16th call to QWSDisplay::Data::takeId() on the stack will not be able to return because all the IDs have been taken and (because it has been called recursively) no new create id commands have been generated. So the 16th call to takeId() spins in waitForCreate(). Reviewed-by: Paul
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qapplication_qws.cpp8
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp3
2 files changed, 8 insertions, 3 deletions
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index 1e158fc..ab2062c 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -661,10 +661,14 @@ void QWSDisplay::Data::sendSynchronousCommand(QWSCommand & cmd)
int QWSDisplay::Data::takeId()
{
- if (unused_identifiers.count() == 10)
+ int unusedIdCount = unused_identifiers.count();
+ if (unusedIdCount == 10)
create(15);
- if (unused_identifiers.count() == 0)
+ if (unusedIdCount == 0) {
+ create(1); // Make sure we have an incoming id to wait for, just in case we're recursive
waitForCreation();
+ }
+
return unused_identifiers.takeFirst();
}
diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp
index 639bc92..d5a5c20 100644
--- a/src/gui/painting/qwindowsurface_qws.cpp
+++ b/src/gui/painting/qwindowsurface_qws.cpp
@@ -421,7 +421,8 @@ QWSWindowSurface::QWSWindowSurface(QWidget *widget)
QWSWindowSurface::~QWSWindowSurface()
{
#ifdef Q_BACKINGSTORE_SUBSURFACES
- winIdToSurfaceMap()->remove(winId());
+ if (d_ptr->winId)
+ winIdToSurfaceMap()->remove(d_ptr->winId);
#endif
delete d_ptr;