ThreadWeaver
DependencyPolicy.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 00003 This file implements the DependencyPolicy class. 00004 00005 $ Author: Mirko Boehm $ 00006 $ Copyright: (C) 2004, 2005, 2006 Mirko Boehm $ 00007 $ Contact: mirko@kde.org 00008 http://www.kde.org 00009 http://www.hackerbuero.org $ 00010 00011 This library is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU Library General Public 00013 License as published by the Free Software Foundation; either 00014 version 2 of the License, or (at your option) any later version. 00015 00016 This library is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 Library General Public License for more details. 00020 00021 You should have received a copy of the GNU Library General Public License 00022 along with this library; see the file COPYING.LIB. If not, write to 00023 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00024 Boston, MA 02110-1301, USA. 00025 00026 $Id: DebuggingAids.cpp 20 2005-08-08 21:02:51Z mirko $ 00027 */ 00028 00029 #include "DependencyPolicy.h" 00030 00031 #include <QtCore/QMutex> 00032 #include <QtCore/QDebug> 00033 00034 #include "Job.h" 00035 #include "DebuggingAids.h" 00036 00037 using namespace ThreadWeaver; 00038 00039 typedef QMultiMap<Job*, Job*> JobMultiMap; 00040 00041 class DependencyPolicy::Private 00042 { 00043 public: 00049 JobMultiMap& dependencies() 00050 { 00051 static JobMultiMap depMap; 00052 return depMap; 00053 } 00054 00055 QMutex& mutex() 00056 { 00057 static QMutex s_mutex; 00058 return s_mutex; 00059 } 00060 00061 }; 00062 00063 DependencyPolicy::DependencyPolicy() 00064 : QueuePolicy() 00065 , d ( new Private() ) 00066 { 00067 } 00068 00069 DependencyPolicy::~DependencyPolicy() 00070 { 00071 delete d; 00072 } 00073 00074 void DependencyPolicy::addDependency( Job* jobA, Job* jobB ) 00075 { 00076 // jobA depends on jobB 00077 REQUIRE ( jobA != 0 && jobB != 0 && jobA != jobB ); 00078 00079 jobA->assignQueuePolicy( this ); 00080 jobB->assignQueuePolicy( this ); 00081 QMutexLocker l( & d->mutex() ); 00082 d->dependencies().insert( jobA, jobB ); 00083 00084 ENSURE ( d->dependencies().contains (jobA)); 00085 } 00086 00087 bool DependencyPolicy::removeDependency( Job* jobA, Job* jobB ) 00088 { 00089 REQUIRE (jobA != 0 && jobB != 0); 00090 bool result = false; 00091 QMutexLocker l( & d->mutex() ); 00092 00093 // there may be only one (!) occurrence of [this, dep]: 00094 QMutableMapIterator<Job*, Job*> it( d->dependencies () ); 00095 while ( it.hasNext() ) 00096 { 00097 it.next(); 00098 if ( it.key()==jobA && it.value()==jobB ) 00099 { 00100 it.remove(); 00101 result = true; 00102 break; 00103 } 00104 } 00105 00106 ENSURE ( ! d->dependencies().keys(jobB).contains(jobA) ); 00107 return result; 00108 } 00109 00110 void DependencyPolicy::resolveDependencies( Job* job ) 00111 { 00112 if ( job->success() ) 00113 { 00114 QMutexLocker l( & d->mutex() ); 00115 QMutableMapIterator<Job*, Job*> it( d->dependencies() ); 00116 // there has to be a better way to do this: (?) 00117 while ( it.hasNext() ) 00118 { // we remove all entries where jobs depend on *this* : 00119 it.next(); 00120 if ( it.value()==job ) 00121 { 00122 it.remove(); 00123 } 00124 } 00125 } 00126 } 00127 00128 QList<Job*> DependencyPolicy::getDependencies( Job* job ) const 00129 { 00130 REQUIRE (job != 0); 00131 QList<Job*> result; 00132 JobMultiMap::const_iterator it; 00133 QMutexLocker l( & d->mutex() ); 00134 00135 for ( it = d->dependencies().constBegin(); it != d->dependencies().constEnd(); ++it ) 00136 { 00137 if ( it.key() == job ) 00138 { 00139 result.append( it.value() ); 00140 } 00141 } 00142 return result; 00143 } 00144 00145 bool DependencyPolicy::hasUnresolvedDependencies( Job* job ) const 00146 { 00147 REQUIRE (job != 0); 00148 QMutexLocker l( & d->mutex() ); 00149 return d->dependencies().contains( job ); 00150 } 00151 00152 DependencyPolicy& DependencyPolicy::instance () 00153 { 00154 static DependencyPolicy policy; 00155 return policy; 00156 } 00157 00158 bool DependencyPolicy::canRun( Job* job ) 00159 { 00160 REQUIRE (job != 0); 00161 return ! hasUnresolvedDependencies( job ); 00162 } 00163 00164 void DependencyPolicy::free( Job* job ) 00165 { 00166 REQUIRE (job != 0); 00167 if ( job->success() ) 00168 { 00169 resolveDependencies( job ); 00170 debug( 3, "DependencyPolicy::free: dependencies resolved for job %p.\n", (void*)job); 00171 } else { 00172 debug( 3, "DependencyPolicy::free: not resolving dependencies for %p (execution not successful).\n", 00173 (void*)job); 00174 } 00175 ENSURE ( ( ! hasUnresolvedDependencies( job ) && job->success() ) || ! job->success() ); 00176 } 00177 00178 void DependencyPolicy::release( Job* job ) 00179 { 00180 REQUIRE (job != 0); Q_UNUSED(job) 00181 } 00182 00183 void DependencyPolicy::destructed( Job* job ) 00184 { 00185 REQUIRE (job != 0); 00186 resolveDependencies ( job ); 00187 } 00188 00189 void DependencyPolicy::dumpJobDependencies() 00190 { 00191 QMutexLocker l( & d->mutex() ); 00192 00193 debug ( 0, "Job Dependencies (left depends on right side):\n" ); 00194 for ( JobMultiMap::const_iterator it = d->dependencies().constBegin(); it != d->dependencies().constEnd(); ++it ) 00195 { 00196 debug( 0, " : %p (%s%s) <-- %p (%s%s)\n", 00197 (void*)it.key(), 00198 it.key()->objectName().isEmpty() ? "" : qPrintable ( QString(it.key()->objectName() + QObject::tr ( " of type " )) ), 00199 it.key()->metaObject()->className(), 00200 (void*)it.value(), 00201 it.value()->objectName().isEmpty() ? "" : qPrintable ( QString(it.value()->objectName() + QObject::tr ( " of type " )) ), 00202 it.value()->metaObject()->className() ); 00203 } 00204 debug ( 0, "-----------------\n" ); 00205 } 00206
KDE 4.6 API Reference