KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.7KB

  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. #include "kis_thread_pool.h"
  19. #include <kglobal.h>
  20. #include <tdeconfig.h>
  21. #include <kdebug.h>
  22. KisThreadPool * KisThreadPool::m_singleton = 0;
  23. KisThreadPool::KisThreadPool()
  24. {
  25. Q_ASSERT(KisThreadPool::m_singleton == 0);
  26. KisThreadPool::m_singleton = this;
  27. TDEConfig * cfg = TDEGlobal::config();
  28. cfg->setGroup("");
  29. m_maxThreads = cfg->readNumEntry("maxthreads", 10);
  30. m_numberOfRunningThreads = 0;
  31. m_numberOfQueuedThreads = 0;
  32. m_wait = 200;
  33. start();
  34. }
  35. KisThreadPool::~KisThreadPool()
  36. {
  37. m_poolMutex.lock();
  38. m_canceled = true;
  39. m_runningThreads.setAutoDelete(true);
  40. m_threads.setAutoDelete(true);
  41. m_oldThreads.setAutoDelete(true);
  42. KisThread * t;
  43. for ( t = m_threads.first(); t; t = m_threads.next()) {
  44. if (t) {
  45. t->cancel();
  46. t->wait();
  47. m_threads.remove(t);
  48. }
  49. }
  50. for ( t = m_runningThreads.first(); t; t = m_runningThreads.next()) {
  51. if (t) {
  52. t->cancel();
  53. t->wait();
  54. m_runningThreads.remove(t);
  55. }
  56. }
  57. for ( t = m_oldThreads.first(); t; t = m_oldThreads.next()) {
  58. if (t) {
  59. t->cancel();
  60. t->wait();
  61. m_runningThreads.remove(t);
  62. }
  63. }
  64. KisThreadPool::m_singleton = 0;
  65. m_poolMutex.unlock();
  66. }
  67. KisThreadPool * KisThreadPool::instance()
  68. {
  69. if(KisThreadPool::m_singleton == 0)
  70. {
  71. KisThreadPool::m_singleton = new KisThreadPool();
  72. }
  73. else {
  74. if (KisThreadPool::m_singleton->finished()) {
  75. delete KisThreadPool::m_singleton;
  76. KisThreadPool::m_singleton = 0;
  77. KisThreadPool::m_singleton = new KisThreadPool();
  78. }
  79. }
  80. return KisThreadPool::m_singleton;
  81. }
  82. void KisThreadPool::enqueue(KisThread * thread)
  83. {
  84. m_poolMutex.lock();
  85. m_threads.append(thread);
  86. m_numberOfQueuedThreads++;
  87. m_poolMutex.unlock();
  88. m_wait = 200;
  89. }
  90. void KisThreadPool::dequeue(KisThread * thread)
  91. {
  92. KisThread * t = 0;
  93. m_poolMutex.lock();
  94. int i = m_threads.findRef(thread);
  95. if (i >= 0) {
  96. t = m_threads.take(i);
  97. m_numberOfQueuedThreads--;
  98. } else {
  99. i = m_runningThreads.findRef(thread);
  100. if (i >= 0) {
  101. t = m_runningThreads.take(i);
  102. m_numberOfRunningThreads--;
  103. }
  104. else {
  105. i = m_oldThreads.findRef(thread);
  106. if (i >= 0) {
  107. t = m_oldThreads.take(i);
  108. }
  109. }
  110. }
  111. m_poolMutex.unlock();
  112. if (t) {
  113. t->cancel();
  114. t->wait();
  115. delete t;
  116. }
  117. }
  118. void KisThreadPool::run()
  119. {
  120. int sleeps = 10;
  121. while(!m_canceled) {
  122. if (m_numberOfQueuedThreads > 0 && m_numberOfRunningThreads < m_maxThreads) {
  123. KisThread * thread = 0;
  124. m_poolMutex.lock();
  125. if (m_threads.count() > 0) {
  126. thread = m_threads.take();
  127. m_numberOfQueuedThreads--;
  128. }
  129. if (thread) {
  130. thread->start();
  131. m_runningThreads.append(thread);
  132. m_numberOfRunningThreads++;
  133. }
  134. m_poolMutex.unlock();
  135. }
  136. else {
  137. msleep(m_wait);
  138. m_poolMutex.lock();
  139. for ( KisThread * t = m_runningThreads.first(); t; t = m_runningThreads.next()) {
  140. if (t) {
  141. if (t->finished()) {
  142. m_runningThreads.remove(t);
  143. m_numberOfRunningThreads--;
  144. m_oldThreads.append(t);
  145. }
  146. }
  147. }
  148. m_poolMutex.unlock();
  149. m_poolMutex.lock();
  150. if (m_numberOfQueuedThreads == 0 && m_numberOfRunningThreads == 0) {
  151. sleeps--;
  152. if (sleeps == 0) {
  153. m_poolMutex.unlock();
  154. return;
  155. }
  156. m_poolMutex.unlock();
  157. }
  158. m_poolMutex.unlock();
  159. }
  160. }
  161. }