krita
kis_thread_pool.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kis_thread_pool.h"
00020 #include <kglobal.h>
00021 #include <kconfig.h>
00022 #include <kdebug.h>
00023
00024 KisThreadPool * KisThreadPool::m_singleton = 0;
00025
00026 KisThreadPool::KisThreadPool()
00027 {
00028 Q_ASSERT(KisThreadPool::m_singleton == 0);
00029
00030 KisThreadPool::m_singleton = this;
00031
00032 KConfig * cfg = KGlobal::config();
00033 cfg->setGroup("");
00034 m_maxThreads = cfg->readNumEntry("maxthreads", 10);
00035 m_numberOfRunningThreads = 0;
00036 m_numberOfQueuedThreads = 0;
00037 m_wait = 200;
00038
00039 start();
00040 }
00041
00042
00043 KisThreadPool::~KisThreadPool()
00044 {
00045 m_poolMutex.lock();
00046
00047 m_canceled = true;
00048
00049 m_runningThreads.setAutoDelete(true);
00050 m_threads.setAutoDelete(true);
00051 m_oldThreads.setAutoDelete(true);
00052
00053 KisThread * t;
00054
00055 for ( t = m_threads.first(); t; t = m_threads.next()) {
00056 if (t) {
00057 t->cancel();
00058 t->wait();
00059 m_threads.remove(t);
00060 }
00061 }
00062
00063 for ( t = m_runningThreads.first(); t; t = m_runningThreads.next()) {
00064 if (t) {
00065 t->cancel();
00066 t->wait();
00067 m_runningThreads.remove(t);
00068 }
00069 }
00070
00071 for ( t = m_oldThreads.first(); t; t = m_oldThreads.next()) {
00072 if (t) {
00073 t->cancel();
00074 t->wait();
00075 m_runningThreads.remove(t);
00076 }
00077 }
00078 KisThreadPool::m_singleton = 0;
00079 m_poolMutex.unlock();
00080
00081 }
00082
00083
00084 KisThreadPool * KisThreadPool::instance()
00085 {
00086 if(KisThreadPool::m_singleton == 0)
00087 {
00088 KisThreadPool::m_singleton = new KisThreadPool();
00089 }
00090 else {
00091
00092 if (KisThreadPool::m_singleton->finished()) {
00093 delete KisThreadPool::m_singleton;
00094 KisThreadPool::m_singleton = 0;
00095 KisThreadPool::m_singleton = new KisThreadPool();
00096 }
00097 }
00098
00099 return KisThreadPool::m_singleton;
00100 }
00101
00102 void KisThreadPool::enqueue(KisThread * thread)
00103 {
00104 m_poolMutex.lock();
00105 m_threads.append(thread);
00106 m_numberOfQueuedThreads++;
00107 m_poolMutex.unlock();
00108 m_wait = 200;
00109 }
00110
00111
00112 void KisThreadPool::dequeue(KisThread * thread)
00113 {
00114 KisThread * t = 0;
00115
00116 m_poolMutex.lock();
00117
00118 int i = m_threads.findRef(thread);
00119 if (i >= 0) {
00120 t = m_threads.take(i);
00121 m_numberOfQueuedThreads--;
00122 } else {
00123 i = m_runningThreads.findRef(thread);
00124 if (i >= 0) {
00125 t = m_runningThreads.take(i);
00126 m_numberOfRunningThreads--;
00127 }
00128 else {
00129 i = m_oldThreads.findRef(thread);
00130 if (i >= 0) {
00131 t = m_oldThreads.take(i);
00132 }
00133 }
00134 }
00135
00136 m_poolMutex.unlock();
00137
00138 if (t) {
00139 t->cancel();
00140 t->wait();
00141 delete t;
00142 }
00143
00144 }
00145
00146 void KisThreadPool::run()
00147 {
00148 int sleeps = 10;
00149
00150 while(!m_canceled) {
00151 if (m_numberOfQueuedThreads > 0 && m_numberOfRunningThreads < m_maxThreads) {
00152 KisThread * thread = 0;
00153 m_poolMutex.lock();
00154 if (m_threads.count() > 0) {
00155 thread = m_threads.take();
00156 m_numberOfQueuedThreads--;
00157 }
00158 if (thread) {
00159 thread->start();
00160 m_runningThreads.append(thread);
00161 m_numberOfRunningThreads++;
00162 }
00163 m_poolMutex.unlock();
00164 }
00165 else {
00166 msleep(m_wait);
00167 m_poolMutex.lock();
00168 for ( KisThread * t = m_runningThreads.first(); t; t = m_runningThreads.next()) {
00169 if (t) {
00170 if (t->finished()) {
00171 m_runningThreads.remove(t);
00172 m_numberOfRunningThreads--;
00173 m_oldThreads.append(t);
00174 }
00175 }
00176 }
00177 m_poolMutex.unlock();
00178 m_poolMutex.lock();
00179 if (m_numberOfQueuedThreads == 0 && m_numberOfRunningThreads == 0) {
00180 sleeps--;
00181 if (sleeps == 0) {
00182 m_poolMutex.unlock();
00183 return;
00184 }
00185 m_poolMutex.unlock();
00186
00187 }
00188 m_poolMutex.unlock();
00189
00190 }
00191 }
00192 }
|