Shadowrun: Awakened 29 September 2011 - Build 871
ThreadPool.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009-2010 Christopher A. Taylor.  All rights reserved.
00003 
00004     Redistribution and use in source and binary forms, with or without
00005     modification, are permitted provided that the following conditions are met:
00006 
00007     * Redistributions of source code must retain the above copyright notice,
00008       this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice,
00010       this list of conditions and the following disclaimer in the documentation
00011       and/or other materials provided with the distribution.
00012     * Neither the name of LibCat nor the names of its contributors may be used
00013       to endorse or promote products derived from this software without
00014       specific prior written permission.
00015 
00016     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026     POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 #ifndef CAT_THREAD_POOL_HPP
00030 #define CAT_THREAD_POOL_HPP
00031 
00032 #include <cat/Singleton.hpp>
00033 #include <cat/threads/Mutex.hpp>
00034 #include <cat/crypt/tunnel/KeyAgreement.hpp>
00035 #include <cat/threads/RegionAllocator.hpp>
00036 #include <cat/io/AsyncBuffer.hpp>
00037 #include <cat/threads/Thread.hpp>
00038 #include <cat/threads/WaitableFlag.hpp>
00039 
00040 #if defined(CAT_OS_WINDOWS)
00041 # include <cat/port/WindowsInclude.hpp>
00042 #endif
00043 
00044 namespace cat {
00045 
00046 
00047 // Reference Object priorities
00048 enum RefObjectPriorities
00049 {
00050     REFOBJ_PRIO_0,
00051     REFOBJ_PRIO_COUNT = 32,
00052 };
00053 
00054 
00055 /*
00056     class ThreadRefObject
00057 
00058     Base class for any thread-safe reference-counted thread pool object
00059 
00060     Designed this way so that all of these objects can be automatically deleted
00061 */
00062 class ThreadRefObject
00063 {
00064     friend class ThreadPool;
00065     ThreadRefObject *last, *next;
00066 
00067     int _priorityLevel;
00068     volatile u32 _refCount;
00069 
00070 public:
00071     ThreadRefObject(int priorityLevel);
00072     CAT_INLINE virtual ~ThreadRefObject() {}
00073 
00074 public:
00075     void AddRef();
00076     void ReleaseRef();
00077 
00078     // Safe release -- If not null, then releases and sets to null
00079     template<class T>
00080     static CAT_INLINE void SafeRelease(T * &object)
00081     {
00082         if (object)
00083         {
00084             object->ReleaseRef();
00085             object = 0;
00086         }
00087     }
00088 };
00089 
00090 
00091 // Auto release for ThreadRefObject references
00092 template<class T>
00093 class AutoRef
00094 {
00095     T *_ref;
00096 
00097 public:
00098     CAT_INLINE AutoRef(T *ref = 0) throw() { _ref = ref; }
00099     CAT_INLINE ~AutoRef() throw() { ThreadRefObject::SafeRelease(_ref); }
00100     CAT_INLINE AutoRef &operator=(T *ref) throw() { Reset(ref); return *this; }
00101 
00102     CAT_INLINE T *Get() throw() { return _ref; }
00103     CAT_INLINE T *operator->() throw() { return _ref; }
00104     CAT_INLINE T &operator*() throw() { return *_ref; }
00105     CAT_INLINE operator T*() { return _ref; }
00106 
00107     CAT_INLINE void Forget() throw() { _ref = 0; }
00108     CAT_INLINE void Reset(T *ref = 0) throw() { ThreadRefObject::SafeRelease(_ref); _ref = ref; }
00109 };
00110 
00111 
00113 
00114 class ThreadPoolLocalStorage
00115 {
00116 public:
00117     BigTwistedEdwards *math;
00118     FortunaOutput *csprng;
00119 
00120     ThreadPoolLocalStorage();
00121     ~ThreadPoolLocalStorage();
00122 
00123     bool Valid();
00124 };
00125 
00126 
00128 
00129 class ShutdownWait;
00130 class ShutdownObserver;
00131 
00132 class ShutdownWait
00133 {
00134     friend class ShutdownObserver;
00135 
00136     WaitableFlag _kill_flag;
00137     ShutdownObserver *_observer;
00138 
00139     void OnShutdownDone();
00140 
00141 public:
00142     // Priority number must be higher than users'
00143     ShutdownWait(int priorityLevel);
00144     /*virtual*/ ~ShutdownWait();
00145 
00146     CAT_INLINE ShutdownObserver *GetObserver() { return _observer; }
00147 
00148     bool WaitForShutdown(u32 milliseconds);
00149 };
00150 
00151 class ShutdownObserver : public ThreadRefObject
00152 {
00153     friend class ShutdownWait;
00154 
00155     ShutdownWait *_wait;
00156 
00157 private:
00158     ShutdownObserver(int priorityLevel, ShutdownWait *wait);
00159     ~ShutdownObserver();
00160 };
00161 
00162 
00164 
00165 class ThreadPoolWorker : public Thread
00166 {
00167 public:
00168     virtual bool ThreadFunction(void *port);
00169 };
00170 
00171 #if defined(CAT_OS_WINDOWS)
00172     typedef HANDLE ThreadPoolHandle;
00173 #else
00174     typedef int ThreadPoolHandle;
00175 #endif
00176 
00177 /*
00178     class ThreadPool
00179 
00180     Startup()  : Call to start up the thread pool
00181     Shutdown() : Call to destroy the thread pool and objects
00182 */
00183 class ThreadPool : public Singleton<ThreadPool>
00184 {
00185     friend class ThreadRefObject;
00186 
00187     CAT_SINGLETON(ThreadPool);
00188 
00189 #if defined(CAT_OS_WINDOWS)
00190     HANDLE _port;
00191 #endif
00192 
00193     int _processor_count, _active_thread_count;
00194 
00195     static const int MAX_THREADS = 256;
00196     ThreadPoolWorker _threads[MAX_THREADS];
00197 
00198     // Track sockets for graceful termination
00199     Mutex _objectRefLock[REFOBJ_PRIO_COUNT];
00200     ThreadRefObject *_objectRefHead[REFOBJ_PRIO_COUNT];
00201 
00202 protected:
00203     void TrackObject(ThreadRefObject *object);
00204     void UntrackObject(ThreadRefObject *object);
00205 
00206     bool SpawnThread();
00207     bool SpawnThreads();
00208 
00209 public:
00210     bool Startup();
00211     void Shutdown();
00212     bool Associate(ThreadPoolHandle h, ThreadRefObject *key);
00213 
00214     int GetProcessorCount() { return _processor_count; }
00215     int GetThreadCount() { return _active_thread_count; }
00216 };
00217 
00218 
00219 } // namespace cat
00220 
00221 #endif // CAT_THREAD_POOL_HPP

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net