diff options
author | mread <qt-info@nokia.com> | 2011-02-15 15:26:42 (GMT) |
---|---|---|
committer | mread <qt-info@nokia.com> | 2011-03-09 12:46:02 (GMT) |
commit | 68517f9f7e96fa7c654898732f0ca9bd63d10723 (patch) | |
tree | 686dec6b769ba04b9db9abe3854edb235539d39e /src/corelib/thread | |
parent | f3d22a9094dfcb9a8c7bd51b1872b05b7cf47139 (diff) | |
download | Qt-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.cpp | 150 |
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); } /* |