ThreadWeaver
DependencyPolicy.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 #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
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
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
00117 while ( it.hasNext() )
00118 {
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);
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 ( it.key()->objectName() + QObject::tr ( " of type " ) ),
00199 it.key()->metaObject()->className(),
00200 (void*)it.value(),
00201 it.value()->objectName().isEmpty() ? "" : qPrintable ( it.value()->objectName() + QObject::tr ( " of type " ) ),
00202 it.value()->metaObject()->className() );
00203 }
00204 debug ( 0, "-----------------\n" );
00205 }
00206