IlmThreadPool.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
  4. // Digital Ltd. LLC
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are
  10. // met:
  11. // * Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. // * Redistributions in binary form must reproduce the above
  14. // copyright notice, this list of conditions and the following disclaimer
  15. // in the documentation and/or other materials provided with the
  16. // distribution.
  17. // * Neither the name of Industrial Light & Magic nor the names of
  18. // its contributors may be used to endorse or promote products derived
  19. // from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. #ifndef INCLUDED_ILM_THREAD_POOL_H
  35. #define INCLUDED_ILM_THREAD_POOL_H
  36. //-----------------------------------------------------------------------------
  37. //
  38. // class Task, class ThreadPool, class TaskGroup
  39. //
  40. // Class ThreadPool manages a set of worker threads and accepts
  41. // tasks for processing. Tasks added to the thread pool are
  42. // executed concurrently by the worker threads.
  43. //
  44. // Class Task provides an abstract interface for a task which
  45. // a ThreadPool works on. Derived classes need to implement the
  46. // execute() function which performs the actual task.
  47. //
  48. // Class TaskGroup allows synchronization on the completion of a set
  49. // of tasks. Every task that is added to a ThreadPool belongs to a
  50. // single TaskGroup. The destructor of the TaskGroup waits for all
  51. // tasks in the group to finish.
  52. //
  53. // Note: if you plan to use the ThreadPool interface in your own
  54. // applications note that the implementation of the ThreadPool calls
  55. // operator delete on tasks as they complete. If you define a custom
  56. // operator new for your tasks, for instance to use a custom heap,
  57. // then you must also write an appropriate operator delete.
  58. //
  59. //-----------------------------------------------------------------------------
  60. #include "IlmThreadNamespace.h"
  61. #include "IlmThreadExport.h"
  62. ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
  63. class TaskGroup;
  64. class Task;
  65. //-------------------------------------------------------
  66. // ThreadPoolProvider -- this is a pure virtual interface
  67. // enabling custom overloading of the threads used and how
  68. // the implementation of the processing of tasks
  69. // is implemented
  70. //-------------------------------------------------------
  71. class ILMTHREAD_EXPORT ThreadPoolProvider
  72. {
  73. public:
  74. ThreadPoolProvider();
  75. virtual ~ThreadPoolProvider();
  76. // as in ThreadPool below
  77. virtual int numThreads () const = 0;
  78. // as in ThreadPool below
  79. virtual void setNumThreads (int count) = 0;
  80. // as in ThreadPool below
  81. virtual void addTask (Task* task) = 0;
  82. // Ensure that all tasks in this set are finished
  83. // and threads shutdown
  84. virtual void finish () = 0;
  85. // Make the provider non-copyable
  86. #if __cplusplus >= 201103L
  87. ThreadPoolProvider (const ThreadPoolProvider &) = delete;
  88. ThreadPoolProvider &operator= (const ThreadPoolProvider &) = delete;
  89. ThreadPoolProvider (ThreadPoolProvider &&) = delete;
  90. ThreadPoolProvider &operator= (ThreadPoolProvider &&) = delete;
  91. #else
  92. private:
  93. ThreadPoolProvider (const ThreadPoolProvider &);
  94. ThreadPoolProvider &operator= (const ThreadPoolProvider &);
  95. #endif
  96. };
  97. class ILMTHREAD_EXPORT ThreadPool
  98. {
  99. public:
  100. //-------------------------------------------------------
  101. // Constructor -- creates numThreads worker threads which
  102. // wait until a task is available,
  103. // using a default ThreadPoolProvider
  104. //-------------------------------------------------------
  105. ThreadPool (unsigned numThreads = 0);
  106. //-----------------------------------------------------------
  107. // Destructor -- waits for all tasks to complete, joins all
  108. // the threads to the calling thread, and then destroys them.
  109. //-----------------------------------------------------------
  110. virtual ~ThreadPool ();
  111. //--------------------------------------------------------
  112. // Query and set the number of worker threads in the pool.
  113. //
  114. // Warning: never call setNumThreads from within a worker
  115. // thread as this will almost certainly cause a deadlock
  116. // or crash.
  117. //--------------------------------------------------------
  118. int numThreads () const;
  119. void setNumThreads (int count);
  120. //--------------------------------------------------------
  121. // Set the thread provider for the pool.
  122. //
  123. // The ThreadPool takes ownership of the ThreadPoolProvider
  124. // and will call delete on it when it is finished or when
  125. // it is changed
  126. //
  127. // Warning: never call setThreadProvider from within a worker
  128. // thread as this will almost certainly cause a deadlock
  129. // or crash.
  130. //--------------------------------------------------------
  131. void setThreadProvider (ThreadPoolProvider *provider);
  132. //------------------------------------------------------------
  133. // Add a task for processing. The ThreadPool can handle any
  134. // number of tasks regardless of the number of worker threads.
  135. // The tasks are first added onto a queue, and are executed
  136. // by threads as they become available, in FIFO order.
  137. //------------------------------------------------------------
  138. void addTask (Task* task);
  139. //-------------------------------------------
  140. // Access functions for the global threadpool
  141. //-------------------------------------------
  142. static ThreadPool& globalThreadPool ();
  143. static void addGlobalTask (Task* task);
  144. struct Data;
  145. protected:
  146. Data * _data;
  147. };
  148. class ILMTHREAD_EXPORT Task
  149. {
  150. public:
  151. Task (TaskGroup* g);
  152. virtual ~Task ();
  153. virtual void execute () = 0;
  154. TaskGroup * group();
  155. protected:
  156. TaskGroup * _group;
  157. };
  158. class ILMTHREAD_EXPORT TaskGroup
  159. {
  160. public:
  161. TaskGroup();
  162. ~TaskGroup();
  163. // marks one task as finished
  164. // should be used by the thread pool provider to notify
  165. // as it finishes tasks
  166. void finishOneTask ();
  167. struct Data;
  168. Data* const _data;
  169. };
  170. ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
  171. #endif // INCLUDED_ILM_THREAD_POOL_H