![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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.