summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authormread <qt-info@nokia.com>2011-02-15 15:26:42 (GMT)
committermread <qt-info@nokia.com>2011-03-09 12:46:02 (GMT)
commit68517f9f7e96fa7c654898732f0ca9bd63d10723 (patch)
tree686dec6b769ba04b9db9abe3854edb235539d39e /src/corelib/thread
parentf3d22a9094dfcb9a8c7bd51b1872b05b7cf47139 (diff)
downloadQt-68517f9f7e96fa7c654898732f0ca9bd63d10723.zip
Qt-68517f9f7e96fa7c654898732f0ca9bd63d10723.tar.gz
Qt-68517f9f7e96fa7c654898732f0ca9bd63d10723.tar.bz2
Attempt to have one thread for all adopted thread monitoring
Compiles, not tested yet. Task-number: QTBUG-13990 Reviewed-by: Shane Kearns
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread_symbian.cpp150
1 files changed, 127 insertions, 23 deletions
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp
index 25027dd..811d7da 100644
--- a/src/corelib/thread/qthread_symbian.cpp
+++ b/src/corelib/thread/qthread_symbian.cpp
@@ -118,34 +118,138 @@ QThreadData *QThreadData::current()
return data;
}
-class AdoptedThreadLifetimeMonitor : public QThread
+QMutex adoptedThreadMonitorMutex;
+class QCAddAdoptedThread;
+QCAddAdoptedThread* adoptedThreadAdder = 0;
+QWaitCondition adoptedThreadAcceptWait;
+
+class QCAdoptedThreadMonitor : public CActive
+{
+public:
+ QCAdoptedThreadMonitor(QThreadData *data)
+ : CActive(EPriorityStandard), adoptedData(data)
{
+ CActiveScheduler::Add(this);
+ adoptedData->symbian_thread_handle.Logon(iStatus);
+ }
+ ~QCAdoptedThreadMonitor();
+ void DoCancel()
+ {
+ adoptedData->symbian_thread_handle.LogonCancel(iStatus);
+ }
+ void RunL()
+ {
+ adoptedData->deref();
+ delete this;
+ }
+private:
+ QThreadData *adoptedData;
+};
+
+class QCAddAdoptedThread : public CActive
+{
public:
- QMutex mutex;
- QThreadData* adoptedData;
- AdoptedThreadLifetimeMonitor(QThreadData* pData)
- : adoptedData(pData)
- {
- mutex.lock();
- }
- void run()
+ QCAddAdoptedThread()
+ : CActive(EPriorityStandard), count(0), dataToAdd(0)
+ {
+ CActiveScheduler::Add(this);
+ start();
+ }
+ ~QCAddAdoptedThread()
+ {
+ Cancel();
+ }
+ void RunL()
+ {
+ if (iStatus.Int() != KErrNone)
+ return;
+
+ // Create an active object to monitor the thread
+ new (ELeave) QCAdoptedThreadMonitor(dataToAdd);
+ count++;
+ dataToAdd = 0;
+ start();
+
+ adoptedThreadAcceptWait.wakeAll();
+ }
+ void add(QThreadData* data)
+ {
+ dataToAdd = data;
+ TRequestStatus *stat = &iStatus;
+ User::RequestComplete(stat, KErrNone);
+ }
+ void start()
+ {
+ iStatus = KRequestPending;
+ SetActive();
+ }
+ void DoCancel()
+ {
+ TRequestStatus *stat = &iStatus;
+ User::RequestComplete(stat, KErrCancel);
+ }
+ void adoptedTheadClosed()
+ {
+ QMutexLocker adoptedThreadMonitorMutexlock(&adoptedThreadMonitorMutex);
+ count--;
+ if (!count)
{
- mutex.unlock();
- TRequestStatus wait = KRequestPending;
- adoptedData->symbian_thread_handle.Logon(wait);
- User::WaitForRequest(wait);
- deleteLater();
- adoptedData->deref();
+ adoptedThreadAdder = 0;
+ CActiveScheduler::Stop();
}
- };
+ }
+private:
+ int count;
+ QThreadData* dataToAdd;
+};
+
+QCAdoptedThreadMonitor::~QCAdoptedThreadMonitor()
+{
+ Cancel();
+ adoptedThreadAdder->adoptedTheadClosed();
+}
-void createAdoptedThreadLifetimeMonitor(QThreadData* data)
+void monitorThreadFuncL()
+{
+ CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+ CleanupStack::PushL(scheduler);
+ CActiveScheduler::Install(scheduler);
+
+ adoptedThreadAdder = new(ELeave) QCAddAdoptedThread();
+ RThread::Rendezvous(KErrNone);
+ CActiveScheduler::Start();
+
+ CleanupStack::PopAndDestroy(scheduler);
+}
+
+int monitorThreadFunc(void *)
+{
+ _LIT(KMonitorThreadName, "adoptedMonitorThread");
+ RThread::RenameMe(KMonitorThreadName());
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ TRAPD(ret, monitorThreadFuncL());
+ delete cleanup;
+ return ret;
+}
+
+void monitorThreadLifetime(QThreadData* data)
{
- AdoptedThreadLifetimeMonitor* monitor = new AdoptedThreadLifetimeMonitor(data);
- monitor->start();
- monitor->mutex.lock();
- monitor->mutex.unlock();
- data->deref();
+ QMutexLocker adoptedThreadMonitorMutexlock(&adoptedThreadMonitorMutex);
+ if (!adoptedThreadAdder)
+ {
+ RThread monitorThread;
+ qt_symbian_throwIfError(monitorThread.Create(KNullDesC(), &monitorThreadFunc, 1024, &User::Allocator(), 0));
+ TRequestStatus started;
+ monitorThread.Rendezvous(started);
+ monitorThread.Resume();
+ User::WaitForRequest(started);
+ monitorThread.Close();
+ }
+ adoptedThreadAdder->add(data);
+ QMutex waitLock;
+ waitLock.lock();
+ adoptedThreadAcceptWait.wait(&waitLock);
+ waitLock.unlock();
}
void QAdoptedThread::init()
@@ -153,7 +257,7 @@ void QAdoptedThread::init()
Q_D(QThread);
d->thread_id = RThread().Id(); // type operator to TUint
init_symbian_thread_handle(d->data->symbian_thread_handle);
- createAdoptedThreadLifetimeMonitor(d->data);
+ monitorThreadLifetime(d->data);
}
/*