From 2b1b617664bfc78f6e95e53dc0f9749bd1f2d27a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 7 Jan 2011 15:57:28 +0000 Subject: Fix handle leak in symbian QTimer implementation The timer handle was only being closed when a timer was cancelled, which resulted in a leak for one shot timers that have completed normally. Instead the timer is now closed in a destructor (closing null handles is safe, so it doesn't matter if the handle was never created - e.g. in the case of a zero timer) Also added a handle check before creating a timer to prevent a leak in case the start function is called twice in the backend. Task-number: QTBUG-16380 Reviewed-by: mread --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 6 ++-- tests/auto/qtimer/tst_qtimer.cpp | 38 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index bb9bd01..99c4087 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -217,13 +217,13 @@ QTimerActiveObject::QTimerActiveObject(QEventDispatcherSymbian *dispatcher, Symb QTimerActiveObject::~QTimerActiveObject() { Cancel(); + m_rTimer.Close(); //close of null handle is safe } void QTimerActiveObject::DoCancel() { if (m_timerInfo->interval > 0) { m_rTimer.Cancel(); - m_rTimer.Close(); } else { if (iStatus.Int() == KRequestPending) { TRequestStatus *status = &iStatus; @@ -302,7 +302,9 @@ void QTimerActiveObject::Start() CActiveScheduler::Add(this); m_timerInfo->msLeft = m_timerInfo->interval; if (m_timerInfo->interval > 0) { - m_rTimer.CreateLocal(); + if (!m_rTimer.Handle()) { + qt_symbian_throwIfError(m_rTimer.CreateLocal()); + } StartTimer(); } else { iStatus = KRequestPending; diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 102308e..e964728 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -90,6 +90,9 @@ private slots: void QTBUG13633_dontBlockEvents(); void postedEventsShouldNotStarveTimers(); +#ifdef Q_OS_SYMBIAN + void handleLeaks(); +#endif }; class TimerHelper : public QObject @@ -750,5 +753,40 @@ void tst_QTimer::postedEventsShouldNotStarveTimers() QVERIFY(timerHelper.count > 5); } +#ifdef Q_OS_SYMBIAN +void tst_QTimer::handleLeaks() +{ + const int timercount = 5; + int processhandles_start; + int threadhandles_start; + RThread().HandleCount(processhandles_start, threadhandles_start); + { + TimerHelper timerHelper; + QList timers; + for (int i=0;isetSingleShot(true); + timer->start(i); //test both zero and normal timeouts + } + int processhandles_mid; + int threadhandles_mid; + RThread().HandleCount(processhandles_mid, threadhandles_mid); + qDebug() << threadhandles_mid - threadhandles_start << "new thread owned handles"; + QTest::qWait(100); + QCOMPARE(timerHelper.count, timercount); + qDeleteAll(timers); + } + int processhandles_end; + int threadhandles_end; + RThread().HandleCount(processhandles_end, threadhandles_end); + QCOMPARE(threadhandles_end, threadhandles_start); //RTimer::CreateLocal creates a thread owned handle + //Can not verify process handles because QObject::connect may create up to 2 mutexes + //from a QMutexPool (4 process owned handles with open C imp.) + //QCOMPARE(processhandles_end, processhandles_start); +} +#endif + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" -- cgit v0.12 From d62e9f4a6fe199ae790b1561fd4ba9ea84bd4d1e Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 10 Jan 2011 13:22:15 +0200 Subject: Setting WA_TranslucentBackground after winid() is ineffective on Symbian. Currently Symbian doesn't support semi-transparent EGL surfaces. WA_TranslucentBackground attribute is ineffective if set after EGL surface creation. To enable translucency in this case we need to recreate backing store to get raster surface which supports translucency. Task-number: QT-4416 Reviewed-by: Jason Barron --- src/gui/kernel/qwidget_s60.cpp | 8 ++++++++ src/gui/painting/qgraphicssystem_runtime.cpp | 3 ++- src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index d6ad3c3..d55c21e 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -780,6 +780,14 @@ void QWidgetPrivate::s60UpdateIsOpaque() if (window->SetTransparencyAlphaChannel() == KErrNone) { window->SetBackgroundColor(TRgb(255, 255, 255, 0)); extra->topextra->nativeWindowTransparencyEnabled = 1; + + if (extra->topextra->backingStore.data() && + QApplicationPrivate::graphics_system_name == QLatin1String("openvg")) { + // Semi-transparent EGL surfaces aren't supported. We need to + // recreate backing store to get translucent surface (raster surface). + extra->topextra->backingStore.create(q); + extra->topextra->backingStore.registerWidget(q); + } } } else if (extra->topextra->nativeWindowTransparencyEnabled) { window->SetTransparentRegion(TRegionFix<1>()); diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp index a9fbbee..db3b0d8 100644 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -322,7 +322,6 @@ QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() : m_windowSurfaceDestroyPolicy(DestroyImmediately), m_graphicsSystem(0) { - QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); QApplicationPrivate::runtime_graphics_system = true; #ifdef QT_DEFAULT_RUNTIME_SYSTEM @@ -336,6 +335,8 @@ QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() #endif m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName); + + QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); } diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp index 9674233..5f4941f 100644 --- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp @@ -45,11 +45,13 @@ #if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE) #include #endif +#include QT_BEGIN_NAMESPACE QVGGraphicsSystem::QVGGraphicsSystem() { + QApplicationPrivate::graphics_system_name = QLatin1String("openvg"); } QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -- cgit v0.12