Home | History | Annotate | Download | only in IlmThread
      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