ThreadWeaver
Thread.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 00003 This file implements the Thread class. 00004 00005 Thread is not a part of the public interface of the ThreadWeaver library. 00006 00007 $ Author: Mirko Boehm $ 00008 $ Copyright: (C) 2004, 2005 Mirko Boehm $ 00009 $ Contact: mirko@kde.org 00010 http://www.kde.org 00011 http://www.hackerbuero.org $ 00012 00013 This library is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU Library General Public 00015 License as published by the Free Software Foundation; either 00016 version 2 of the License, or (at your option) any later version. 00017 00018 This library is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 Library General Public License for more details. 00022 00023 You should have received a copy of the GNU Library General Public License 00024 along with this library; see the file COPYING.LIB. If not, write to 00025 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00026 Boston, MA 02110-1301, USA. 00027 00028 $Id: Thread.cpp 25 2005-08-14 12:41:38Z mirko $ 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 // this is the *only* assignment to m_job in the Thread class! 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 () // no parent, because the QObject hierarchy of this thread 00112 // does not have a parent (see QObject::pushToThread) 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 // disabled while testing movetothread... 00130 // Q_ASSERT ( thread() != this ); // this is created and owned by the main thread 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"
KDE 4.6 API Reference