1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2005, 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 35 #ifndef INCLUDED_ILM_THREAD_POOL_H 36 #define INCLUDED_ILM_THREAD_POOL_H 37 38 //----------------------------------------------------------------------------- 39 // 40 // class Task, class ThreadPool, class TaskGroup 41 // 42 // Class ThreadPool manages a set of worker threads and accepts 43 // tasks for processing. Tasks added to the thread pool are 44 // executed concurrently by the worker threads. 45 // 46 // Class Thread provides an abstract interface for a task which 47 // a ThreadPool works on. Derived classes need to implement the 48 // execute() function which performs the actual task. 49 // 50 // Class TaskTroup allows synchronization on the completion of a set 51 // of tasks. Every task that is added to a ThreadPool belongs to a 52 // single TaskGroup. The destructor of the TaskGroup waits for all 53 // tasks in the group to finish. 54 // 55 // Note: if you plan to use the ThreadPool interface in your own 56 // applications note that the implementation of the ThreadPool calls 57 // operator delete on tasks as they complete. If you define a custom 58 // operator new for your tasks, for instance to use a custom heap, 59 // then you must also write an appropriate operator delete. 60 // 61 //----------------------------------------------------------------------------- 62 63 namespace IlmThread { 64 65 class TaskGroup; 66 class Task; 67 68 69 class ThreadPool 70 { 71 public: 72 73 //------------------------------------------------------- 74 // Constructor -- creates numThreads worker threads which 75 // wait until a task is available. 76 //------------------------------------------------------- 77 78 ThreadPool (unsigned numThreads = 0); 79 80 81 //----------------------------------------------------------- 82 // Destructor -- waits for all tasks to complete, joins all 83 // the threads to the calling thread, and then destroys them. 84 //----------------------------------------------------------- 85 86 virtual ~ThreadPool (); 87 88 89 //-------------------------------------------------------- 90 // Query and set the number of worker threads in the pool. 91 // 92 // Warning: never call setNumThreads from within a worker 93 // thread as this will almost certainly cause a deadlock 94 // or crash. 95 //-------------------------------------------------------- 96 97 int numThreads () const; 98 void setNumThreads (int count); 99 100 101 //------------------------------------------------------------ 102 // Add a task for processing. The ThreadPool can handle any 103 // number of tasks regardless of the number of worker threads. 104 // The tasks are first added onto a queue, and are executed 105 // by threads as they become available, in FIFO order. 106 //------------------------------------------------------------ 107 108 void addTask (Task* task); 109 110 111 //------------------------------------------- 112 // Access functions for the global threadpool 113 //------------------------------------------- 114 115 static ThreadPool& globalThreadPool (); 116 static void addGlobalTask (Task* task); 117 118 struct Data; 119 120 protected: 121 122 Data * _data; 123 }; 124 125 126 class Task 127 { 128 public: 129 130 Task (TaskGroup* g); 131 virtual ~Task (); 132 133 virtual void execute () = 0; 134 TaskGroup * group(); 135 136 protected: 137 138 TaskGroup * _group; 139 }; 140 141 142 class TaskGroup 143 { 144 public: 145 146 TaskGroup(); 147 ~TaskGroup(); 148 149 struct Data; 150 Data* const _data; 151 }; 152 153 154 } // namespace IlmThread 155 156 #endif 157