Home / Open source / Terimber 2.0
00001 /* 00002 * The Software License 00003 * ================================================================================= 00004 * Copyright (c) 2003-.The Terimber Corporation. All rights reserved. 00005 * ================================================================================= 00006 * Redistributions of source code must retain the above copyright notice, 00007 * this list of conditions and the following disclaimer. 00008 * Redistributions in binary form must reproduce the above copyright notice, 00009 * this list of conditions and the following disclaimer in the documentation 00010 * and/or other materials provided with the distribution. 00011 * The end-user documentation included with the redistribution, if any, 00012 * must include the following acknowledgment: 00013 * "This product includes software developed by the Terimber Corporation." 00014 * ================================================================================= 00015 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00016 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00017 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00018 * IN NO EVENT SHALL THE TERIMBER CORPORATION OR ITS CONTRIBUTORS BE LIABLE FOR 00019 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00022 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00024 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 * ================================================================================ 00026 */ 00027 00028 #ifndef _terimber_primitives_h_ 00029 #define _terimber_primitives_h_ 00030 00031 #include "allinc.h" 00032 #include "base/proto.h" 00033 00034 BEGIN_TERIMBER_NAMESPACE 00035 #pragma pack(4) 00036 00040 class mutex 00041 { 00042 // prevents copy objects 00044 mutex(const mutex& x); 00046 mutex& operator=(const mutex& x); 00047 00048 public: 00050 #if OS_TYPE == OS_WIN32 00051 typedef CRITICAL_SECTION _HANDLE_; 00052 #else 00053 typedef pthread_mutex_t _HANDLE_; 00054 #endif 00055 00057 mutex(); 00059 ~mutex(); 00062 bool 00063 lock() const; 00066 void 00067 unlock() const; 00070 bool 00071 trylock() const; 00072 operator _HANDLE_*() 00073 { 00074 return &_handle; 00075 } 00077 operator const _HANDLE_*() const 00078 { 00079 return &_handle; 00080 } 00081 private: 00082 mutable _HANDLE_ _handle; 00083 }; 00084 00087 class mutex_keeper 00088 { 00089 public: 00091 mutex_keeper( const mutex& mtx, 00092 bool use_try = false 00093 ) : _mtx(mtx) 00094 { 00095 _locked = use_try ? _mtx.trylock() : _mtx.lock(); 00096 } 00098 ~mutex_keeper() 00099 { 00100 if (_locked) 00101 _mtx.unlock(); 00102 } 00104 inline 00105 void 00106 unlock() const 00107 { 00108 if (_locked) 00109 { 00110 _mtx.unlock(); 00111 _locked = false; 00112 } 00113 } 00115 inline 00116 void 00117 lock() const 00118 { 00119 if (!_locked) 00120 { 00121 _mtx.lock(); 00122 _locked = true; 00123 } 00124 } 00126 inline 00127 operator bool() const 00128 { 00129 return _locked; 00130 } 00132 inline 00133 bool 00134 operator!() const 00135 { 00136 return !_locked; 00137 } 00138 private: 00139 const mutex& _mtx; 00140 mutable bool _locked; 00141 }; 00142 00144 00147 class event 00148 { 00151 event(const event& x); 00153 event& operator=(const event& x); 00154 public: 00155 00157 #if OS_TYPE == OS_WIN32 00158 typedef HANDLE _HANDLE_; 00159 #else 00160 typedef class HANDLE { 00161 public: 00162 mutex _mtx; 00163 pthread_cond_t* _cond; 00164 bool _manual_reset; 00165 bool _signaled; 00166 } *_HANDLE_; 00167 #endif 00168 00170 event( bool manual_reset = false, 00171 bool init_state = false 00172 ); 00174 ~event(); 00177 void 00178 signal() const; 00181 void 00182 nonsignal() const; 00184 operator _HANDLE_() const 00185 { 00186 return 00187 #if OS_TYPE == OS_WIN32 00188 _handle; 00189 #else 00190 &_handle; 00191 #endif 00192 } 00193 00196 size_t 00197 wait( size_t timeout = INFINITE 00198 ) const; 00199 private: 00200 mutable HANDLE _handle; 00201 }; 00202 00205 class semaphore 00206 { 00209 semaphore(const semaphore& x); 00211 semaphore& operator=(const semaphore& x); 00212 00213 public: 00215 #if OS_TYPE == OS_WIN32 00216 typedef HANDLE _HANDLE_; 00217 #else 00218 typedef class HANDLE { 00219 public: 00220 mutex _mtx; 00221 pthread_cond_t* _cond; 00222 size_t _init_count; 00223 size_t _max_count; 00224 } *_HANDLE_; 00225 #endif 00226 00228 semaphore( size_t initial_count = 1, 00229 size_t max_count = 1 00230 ); 00232 ~semaphore(); 00235 bool 00236 release( size_t count = 1 00237 ) const; 00240 size_t 00241 wait( size_t timeout = INFINITE 00242 ) const; 00243 private: 00244 mutable HANDLE _handle; 00245 }; 00246 00249 class semaphore_keeper 00250 { 00251 public: 00253 semaphore_keeper( const semaphore& sema, 00254 size_t timeout = INFINITE 00255 ) : _sema(sema) 00256 { 00257 _approved = (WAIT_OBJECT_0 == _sema.wait(timeout)); 00258 } 00260 ~semaphore_keeper() 00261 { 00262 if (_approved) 00263 _sema.release(); 00264 } 00266 inline 00267 operator bool() const 00268 { 00269 return _approved; 00270 } 00272 inline 00273 bool 00274 operator!() const 00275 { 00276 return !_approved; 00277 } 00278 00279 private: 00280 const semaphore& _sema; 00281 bool _approved; 00282 }; 00283 00284 #pragma pack() 00285 END_TERIMBER_NAMESPACE 00286 00287 #endif