summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authormread <qt-info@nokia.com>2011-02-16 14:17:36 (GMT)
committermread <qt-info@nokia.com>2011-03-09 12:46:13 (GMT)
commit586ba876034f46be1fe1c916f84f51392e60f3ef (patch)
tree24a31acacd70cf11549219d6695f6b81be70e06b /src/corelib/thread
parent68517f9f7e96fa7c654898732f0ca9bd63d10723 (diff)
downloadQt-586ba876034f46be1fe1c916f84f51392e60f3ef.zip
Qt-586ba876034f46be1fe1c916f84f51392e60f3ef.tar.gz
Qt-586ba876034f46be1fe1c916f84f51392e60f3ef.tar.bz2
Using a single monitor thread to monitor all adopted threads
This reduces the number of extra threads required when native threads are adopted. In practice, the main thread is native and the montitor thread itself, so the monitor thread always ends up monitoring both. Task-number: QTBUG-13990 Reviewed-by: Shane Kearns
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread_symbian.cpp162
1 files changed, 76 insertions, 86 deletions
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp
index 811d7da..bb1a4a7 100644
--- a/src/corelib/thread/qthread_symbian.cpp
+++ b/src/corelib/thread/qthread_symbian.cpp
@@ -118,146 +118,136 @@ QThreadData *QThreadData::current()
return data;
}
-QMutex adoptedThreadMonitorMutex;
-class QCAddAdoptedThread;
-QCAddAdoptedThread* adoptedThreadAdder = 0;
-QWaitCondition adoptedThreadAcceptWait;
class QCAdoptedThreadMonitor : public CActive
{
public:
- QCAdoptedThreadMonitor(QThreadData *data)
- : CActive(EPriorityStandard), adoptedData(data)
+ QCAdoptedThreadMonitor(QThread *thread)
+ : CActive(EPriorityStandard), data(QThreadData::get2(thread))
{
CActiveScheduler::Add(this);
- adoptedData->symbian_thread_handle.Logon(iStatus);
+ data->symbian_thread_handle.Logon(iStatus);
+ SetActive();
+ }
+ ~QCAdoptedThreadMonitor()
+ {
+ Cancel();
}
- ~QCAdoptedThreadMonitor();
void DoCancel()
{
- adoptedData->symbian_thread_handle.LogonCancel(iStatus);
+ data->symbian_thread_handle.LogonCancel(iStatus);
}
void RunL()
{
- adoptedData->deref();
+ data->deref();
delete this;
}
private:
- QThreadData *adoptedData;
+ QThreadData* data;
};
class QCAddAdoptedThread : public CActive
{
public:
QCAddAdoptedThread()
- : CActive(EPriorityStandard), count(0), dataToAdd(0)
+ : CActive(EPriorityStandard)
{
CActiveScheduler::Add(this);
+ }
+ void ConstructL()
+ {
+ User::LeaveIfError(monitorThread.Open(RThread().Id()));
start();
}
~QCAddAdoptedThread()
{
Cancel();
+ monitorThread.Close();
}
- 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)
+ void DoCancel()
{
- dataToAdd = data;
TRequestStatus *stat = &iStatus;
- User::RequestComplete(stat, KErrNone);
+ User::RequestComplete(stat, KErrCancel);
}
void start()
{
iStatus = KRequestPending;
SetActive();
}
- void DoCancel()
+ void RunL()
{
- TRequestStatus *stat = &iStatus;
- User::RequestComplete(stat, KErrCancel);
+ if (iStatus.Int() != KErrNone)
+ return;
+
+ QMutexLocker adoptedThreadMonitorMutexlock(&adoptedThreadMonitorMutex);
+ for (int i=threadsToAdd.size()-1; i>=0; i--) {
+ // Create an active object to monitor the thread
+ new (ELeave) QCAdoptedThreadMonitor(threadsToAdd[i]);
+ threadsToAdd.pop_back();
+ }
+ start();
}
- void adoptedTheadClosed()
+ static void add(QThread* thread)
{
QMutexLocker adoptedThreadMonitorMutexlock(&adoptedThreadMonitorMutex);
- count--;
- if (!count)
- {
- adoptedThreadAdder = 0;
- CActiveScheduler::Stop();
+ 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->threadsToAdd.push_back(thread);
+ if (adoptedThreadAdder->IsActive()) {
+ TRequestStatus *stat = &adoptedThreadAdder->iStatus;
+ adoptedThreadAdder->monitorThread.RequestComplete(stat, KErrNone);
}
}
-private:
- int count;
- QThreadData* dataToAdd;
-};
-
-QCAdoptedThreadMonitor::~QCAdoptedThreadMonitor()
-{
- Cancel();
- adoptedThreadAdder->adoptedTheadClosed();
-}
-
-void monitorThreadFuncL()
-{
- CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
- CleanupStack::PushL(scheduler);
- CActiveScheduler::Install(scheduler);
-
- adoptedThreadAdder = new(ELeave) QCAddAdoptedThread();
- RThread::Rendezvous(KErrNone);
- CActiveScheduler::Start();
+ static void monitorThreadFuncL()
+ {
+ CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+ CleanupStack::PushL(scheduler);
+ CActiveScheduler::Install(scheduler);
- CleanupStack::PopAndDestroy(scheduler);
-}
+ adoptedThreadAdder = new(ELeave) QCAddAdoptedThread();
+ CleanupStack::PushL(adoptedThreadAdder);
+ adoptedThreadAdder->ConstructL();
-int monitorThreadFunc(void *)
-{
- _LIT(KMonitorThreadName, "adoptedMonitorThread");
- RThread::RenameMe(KMonitorThreadName());
- CTrapCleanup* cleanup = CTrapCleanup::New();
- TRAPD(ret, monitorThreadFuncL());
- delete cleanup;
- return ret;
-}
+ RThread::Rendezvous(KErrNone);
+ CActiveScheduler::Start();
-void monitorThreadLifetime(QThreadData* data)
- {
- 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();
+ CleanupStack::PopAndDestroy(adoptedThreadAdder);
+ adoptedThreadAdder = 0;
+ CleanupStack::PopAndDestroy(scheduler);
}
- adoptedThreadAdder->add(data);
- QMutex waitLock;
- waitLock.lock();
- adoptedThreadAcceptWait.wait(&waitLock);
- waitLock.unlock();
+ static int monitorThreadFunc(void *)
+ {
+ _LIT(KMonitorThreadName, "adoptedMonitorThread");
+ RThread::RenameMe(KMonitorThreadName());
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ TRAPD(ret, monitorThreadFuncL());
+ delete cleanup;
+ return ret;
}
+private:
+ QVector<QThread*> threadsToAdd;
+ RThread monitorThread;
+ static QMutex adoptedThreadMonitorMutex;
+ static QCAddAdoptedThread* adoptedThreadAdder;
+};
+
+QMutex QCAddAdoptedThread::adoptedThreadMonitorMutex;
+QCAddAdoptedThread* QCAddAdoptedThread::adoptedThreadAdder = 0;
+
void QAdoptedThread::init()
{
Q_D(QThread);
d->thread_id = RThread().Id(); // type operator to TUint
init_symbian_thread_handle(d->data->symbian_thread_handle);
- monitorThreadLifetime(d->data);
+ QCAddAdoptedThread::add(this);
}
/*