summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-06-11 11:11:05 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2010-06-11 15:14:19 (GMT)
commit5471f3cc5f3b1ec9fbe15ba35ab23dfd9fcc42c9 (patch)
tree5207081b3e4dbab15ae3a2b14b622569549d384d /src/gui/kernel
parentda424a2e8a8570e24eac6272bb410a51381fcad7 (diff)
downloadQt-5471f3cc5f3b1ec9fbe15ba35ab23dfd9fcc42c9.zip
Qt-5471f3cc5f3b1ec9fbe15ba35ab23dfd9fcc42c9.tar.gz
Qt-5471f3cc5f3b1ec9fbe15ba35ab23dfd9fcc42c9.tar.bz2
Thread safety for QFontEngineS60
On symbian, creating fonts requires a connection to the window server. Window server sessions are not sharable across threads. To avoid QFont crashing when used outside the GUI thread, we construct a private session to the window server when the shared CONE session is not available. (CCoeEnv::Static() uses TLS, so it returns null outside of GUI thread) The private session and screen device are stored in QThreadStorage, so they are automatically deleted when the QThread exits. Task-number: QTBUG-8874 Reviewed-by: mread
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp25
-rw-r--r--src/gui/kernel/qt_s60_p.h26
2 files changed, 47 insertions, 4 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 78027b2..f39b462 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -2046,4 +2046,29 @@ void QApplication::restoreOverrideCursor()
#endif // QT_NO_CURSOR
+QS60ThreadLocalData::QS60ThreadLocalData()
+{
+ CCoeEnv *env = CCoeEnv::Static();
+ if (env) {
+ //if this is the UI thread, share objects owned by CONE
+ usingCONEinstances = true;
+ wsSession = env->WsSession();
+ screenDevice = env->ScreenDevice();
+ }
+ else {
+ usingCONEinstances = false;
+ qt_symbian_throwIfError(wsSession.Connect(qt_s60GetRFs()));
+ screenDevice = new CWsScreenDevice(wsSession);
+ screenDevice->Construct();
+ }
+}
+
+QS60ThreadLocalData::~QS60ThreadLocalData()
+{
+ if (!usingCONEinstances) {
+ delete screenDevice;
+ wsSession.Close();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 58da302..bec51b8 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -62,6 +62,7 @@
#include "QtGui/qevent.h"
#include "qpointer.h"
#include "qapplication.h"
+#include "QtCore/qthreadstorage.h"
#include <w32std.h>
#include <coecntrl.h>
#include <eikenv.h>
@@ -85,10 +86,21 @@ const TInt KInternalStatusPaneChange = 0x50000000;
//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13)
+class QS60ThreadLocalData
+{
+public:
+ QS60ThreadLocalData();
+ ~QS60ThreadLocalData();
+ bool usingCONEinstances;
+ RWsSession wsSession;
+ CWsScreenDevice *screenDevice;
+};
+
class QS60Data
{
public:
QS60Data();
+ QThreadStorage<QS60ThreadLocalData *> tls;
TUid uid;
int screenDepth;
QPoint lastCursorPos;
@@ -125,9 +137,9 @@ public:
int menuBeingConstructed : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
static inline void updateScreenSize();
- static inline RWsSession& wsSession();
+ inline RWsSession& wsSession();
static inline RWindowGroup& windowGroup();
- static inline CWsScreenDevice* screenDevice();
+ inline CWsScreenDevice* screenDevice();
static inline CCoeAppUi* appUi();
static inline CEikMenuBar* menuBar();
#ifdef Q_WS_S60
@@ -256,7 +268,10 @@ inline void QS60Data::updateScreenSize()
inline RWsSession& QS60Data::wsSession()
{
- return CCoeEnv::Static()->WsSession();
+ if(!tls.hasLocalData()) {
+ tls.setLocalData(new QS60ThreadLocalData);
+ }
+ return tls.localData()->wsSession;
}
inline RWindowGroup& QS60Data::windowGroup()
@@ -266,7 +281,10 @@ inline RWindowGroup& QS60Data::windowGroup()
inline CWsScreenDevice* QS60Data::screenDevice()
{
- return CCoeEnv::Static()->ScreenDevice();
+ if(!tls.hasLocalData()) {
+ tls.setLocalData(new QS60ThreadLocalData);
+ }
+ return tls.localData()->screenDevice;
}
inline CCoeAppUi* QS60Data::appUi()