chalk

kis_thread_pool.cpp
1/*
2 * copyright (c) 2006 Boudewijn Rempt
3 *
4 * This program is free software; you can distribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#include "kis_thread_pool.h"
20#include <tdeglobal.h>
21#include <tdeconfig.h>
22#include <kdebug.h>
23
24KisThreadPool * KisThreadPool::m_singleton = 0;
25
26KisThreadPool::KisThreadPool()
27{
28 Q_ASSERT(KisThreadPool::m_singleton == 0);
29
30 KisThreadPool::m_singleton = this;
31
32 TDEConfig * cfg = TDEGlobal::config();
33 cfg->setGroup("");
34 m_maxThreads = cfg->readNumEntry("maxthreads", 10);
35 m_numberOfRunningThreads = 0;
36 m_numberOfQueuedThreads = 0;
37 m_wait = 200;
38
39 start();
40}
41
42
43KisThreadPool::~KisThreadPool()
44{
45 m_poolMutex.lock();
46
47 m_canceled = true;
48
49 m_runningThreads.setAutoDelete(true);
50 m_threads.setAutoDelete(true);
51 m_oldThreads.setAutoDelete(true);
52
53 KisThread * t;
54
55 for ( t = m_threads.first(); t; t = m_threads.next()) {
56 if (t) {
57 t->cancel();
58 t->wait();
59 m_threads.remove(t);
60 }
61 }
62
63 for ( t = m_runningThreads.first(); t; t = m_runningThreads.next()) {
64 if (t) {
65 t->cancel();
66 t->wait();
67 m_runningThreads.remove(t);
68 }
69 }
70
71 for ( t = m_oldThreads.first(); t; t = m_oldThreads.next()) {
72 if (t) {
73 t->cancel();
74 t->wait();
75 m_runningThreads.remove(t);
76 }
77 }
78 KisThreadPool::m_singleton = 0;
79 m_poolMutex.unlock();
80
81}
82
83
84KisThreadPool * KisThreadPool::instance()
85{
86 if(KisThreadPool::m_singleton == 0)
87 {
88 KisThreadPool::m_singleton = new KisThreadPool();
89 }
90 else {
91
92 if (KisThreadPool::m_singleton->finished()) {
93 delete KisThreadPool::m_singleton;
94 KisThreadPool::m_singleton = 0;
95 KisThreadPool::m_singleton = new KisThreadPool();
96 }
97 }
98
99 return KisThreadPool::m_singleton;
100}
101
102void KisThreadPool::enqueue(KisThread * thread)
103{
104 m_poolMutex.lock();
105 m_threads.append(thread);
106 m_numberOfQueuedThreads++;
107 m_poolMutex.unlock();
108 m_wait = 200;
109}
110
111
112void KisThreadPool::dequeue(KisThread * thread)
113{
114 KisThread * t = 0;
115
116 m_poolMutex.lock();
117
118 int i = m_threads.findRef(thread);
119 if (i >= 0) {
120 t = m_threads.take(i);
121 m_numberOfQueuedThreads--;
122 } else {
123 i = m_runningThreads.findRef(thread);
124 if (i >= 0) {
125 t = m_runningThreads.take(i);
126 m_numberOfRunningThreads--;
127 }
128 else {
129 i = m_oldThreads.findRef(thread);
130 if (i >= 0) {
131 t = m_oldThreads.take(i);
132 }
133 }
134 }
135
136 m_poolMutex.unlock();
137
138 if (t) {
139 t->cancel();
140 t->wait();
141 delete t;
142 }
143
144}
145
146void KisThreadPool::run()
147{
148 int sleeps = 10;
149
150 while(!m_canceled) {
151 if (m_numberOfQueuedThreads > 0 && m_numberOfRunningThreads < m_maxThreads) {
152 KisThread * thread = 0;
153 m_poolMutex.lock();
154 if (m_threads.count() > 0) {
155 thread = m_threads.take();
156 m_numberOfQueuedThreads--;
157 }
158 if (thread) {
159 thread->start();
160 m_runningThreads.append(thread);
161 m_numberOfRunningThreads++;
162 }
163 m_poolMutex.unlock();
164 }
165 else {
166 msleep(m_wait);
167 m_poolMutex.lock();
168 for ( KisThread * t = m_runningThreads.first(); t; t = m_runningThreads.next()) {
169 if (t) {
170 if (t->finished()) {
171 m_runningThreads.remove(t);
172 m_numberOfRunningThreads--;
173 m_oldThreads.append(t);
174 }
175 }
176 }
177 m_poolMutex.unlock();
178 m_poolMutex.lock();
179 if (m_numberOfQueuedThreads == 0 && m_numberOfRunningThreads == 0) {
180 sleeps--;
181 if (sleeps == 0) {
182 m_poolMutex.unlock();
183 return;
184 }
185 m_poolMutex.unlock();
186
187 }
188 m_poolMutex.unlock();
189
190 }
191 }
192}
A thread pool starts executing threads some time after they are added, running a maximum number of th...
A KisThread is a TQThread that can be set in the canceled state.
Definition kis_thread.h:30
virtual void cancel()
Request the thread to cancel at the first opportunity.
Definition kis_thread.h:45