ThreadWeaver
Thread.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "Thread.h"
00032 #include "Thread_p.h"
00033
00034 #include <QtCore/QMutex>
00035 #include <QtCore/QDebug>
00036
00037 #include "ThreadWeaver.h"
00038 #include "WeaverImpl.h"
00039 #include "Job.h"
00040 #include "DebuggingAids.h"
00041
00042 using namespace ThreadWeaver;
00043
00044 class Thread::Private
00045 {
00046 public:
00047 explicit Private ( WeaverImpl* theParent )
00048 : parent ( theParent )
00049 , runhelper ( 0 )
00050 , id ( makeId() )
00051 {}
00052
00053 WeaverImpl *parent;
00054
00055 ThreadRunHelper* runhelper;
00056
00057 const unsigned int id;
00058
00059 static unsigned int makeId()
00060 {
00061 static unsigned int s_id;
00062 static QMutex sm_mutex;
00063 QMutexLocker l (&sm_mutex);
00064 return ++s_id;
00065 }
00066 };
00067
00068
00069 ThreadWeaver::ThreadRunHelper::ThreadRunHelper()
00070 : QObject ( 0 )
00071 , m_job( 0 )
00072 {
00073 }
00074
00075 void ThreadWeaver::ThreadRunHelper::run ( WeaverImpl *parent, Thread* th )
00076 {
00077 Q_ASSERT ( thread() == th );
00078 emit ( started ( th) );
00079
00080 while (true)
00081 {
00082 debug ( 3, "Thread::run [%u]: trying to execute the next job.\n", th->id() );
00083
00084
00085 Job* tmp = m_job; m_job = 0;
00086
00087 Job* job = parent->applyForWork ( th, tmp );
00088
00089 if (job == 0)
00090 {
00091 break;
00092 } else {
00093 m_job = job;
00094 emit ( jobStarted ( th, m_job ) );
00095 m_job->execute (th);
00096 emit ( jobDone ( m_job ) );
00097 }
00098 }
00099 }
00100
00101 void ThreadWeaver::ThreadRunHelper::requestAbort()
00102 {
00103 Job* job = m_job;
00104 if ( job )
00105 {
00106 job->requestAbort();
00107 }
00108 }
00109
00110 Thread::Thread (WeaverImpl *parent)
00111 : QThread ()
00112
00113 , d ( new Private ( parent ) )
00114 {
00115 }
00116
00117 Thread::~Thread()
00118 {
00119 delete d;
00120 }
00121
00122 unsigned int Thread::id()
00123 {
00124 return d->id;
00125 }
00126
00127 void Thread::run()
00128 {
00129
00130
00131 debug ( 3, "Thread::run [%u]: running.\n", id() );
00132
00133 ThreadRunHelper helper;
00134 d->runhelper = &helper;
00135
00136 connect ( &helper, SIGNAL ( started ( ThreadWeaver::Thread* ) ),
00137 SIGNAL ( started ( ThreadWeaver::Thread* ) ) );
00138 connect ( &helper, SIGNAL ( jobStarted ( ThreadWeaver::Thread*, ThreadWeaver::Job* ) ),
00139 SIGNAL ( jobStarted ( ThreadWeaver::Thread*, ThreadWeaver::Job* ) ) );
00140 connect ( &helper, SIGNAL ( jobDone ( ThreadWeaver::Job* ) ),
00141 SIGNAL ( jobDone ( ThreadWeaver::Job* ) ) );
00142 helper.run( d->parent, this );
00143
00144 d->runhelper = 0;
00145 debug ( 3, "Thread::run [%u]: exiting.\n", id() );
00146 }
00147
00148 void Thread::msleep(unsigned long msec)
00149 {
00150 QThread::msleep(msec);
00151 }
00152
00153
00154 void Thread::requestAbort ()
00155 {
00156 if ( d->runhelper )
00157 {
00158 d->runhelper->requestAbort();
00159 } else {
00160 qDebug ( "Thread::requestAbort: not running." );
00161 }
00162 }
00163
00164 #include "Thread.moc"
00165 #include "Thread_p.moc"