1 /* 2 * Copyright (c) 2005, Eric Crahen 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is furnished 9 * to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in all 12 * copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 */ 22 23 #ifndef __ZTMONITOR_H__ 24 #define __ZTMONITOR_H__ 25 26 #include "../Status.h" 27 #include "../FastLock.h" 28 29 namespace ZThread { 30 31 /** 32 * @class Monitor 33 * @author Eric Crahen <http://www.code-foo.com> 34 * @date <2003-07-18T08:16:09-0400> 35 * @version 2.2.8 36 */ 37 class Monitor : public Status, private NonCopyable { 38 private: 39 40 //! Serialize access to external objects 41 FastLock _lock; 42 43 //! Condition variable used to block a thread. 44 pthread_cond_t _waitCond; 45 46 //! Serialize access to the internal state of the monitor 47 pthread_mutex_t _waitLock; 48 49 //! Owning thread 50 pthread_t _owner; 51 52 //! Waiting flag, to avoid uneccessary signals 53 volatile bool _waiting; 54 55 public: 56 57 typedef Status::STATE STATE; 58 59 //! Create a new monitor. 60 Monitor(); 61 62 //! Destroy the monitor. 63 ~Monitor(); 64 65 //! Acquire the lock for this monitor. acquire()66 inline void acquire() { 67 _lock.acquire(); 68 } 69 70 //! Acquire the lock for this monitor. tryAcquire()71 inline bool tryAcquire() { 72 return _lock.tryAcquire(); 73 } 74 75 //! Release the lock for this monitor release()76 inline void release() { 77 _lock.release(); 78 } 79 80 /** 81 * Wait for a state change and atomically unlock the external lock. 82 * Blocks for an indefinent amount of time. 83 * 84 * @return INTERRUPTED if the wait was ended by a interrupt() 85 * or SIGNALED if the wait was ended by a notify() 86 * 87 * @post the external lock is always acquired before this function returns 88 */ wait()89 inline STATE wait() { 90 return wait(0); 91 } 92 93 /** 94 * Wait for a state change and atomically unlock the external lock. 95 * May blocks for an indefinent amount of time. 96 * 97 * @param timeout - maximum time to block (milliseconds) or 0 to 98 * block indefinently 99 * 100 * @return INTERRUPTED if the wait was ended by a interrupt() 101 * or TIMEDOUT if the maximum wait time expired. 102 * or SIGNALED if the wait was ended by a notify() 103 * 104 * @post the external lock is always acquired before this function returns 105 */ 106 STATE wait(unsigned long timeout); 107 108 /** 109 * Interrupt this monitor. If there is a thread blocked on this monitor object 110 * it will be signaled and released. If there is no waiter, a flag is set and 111 * the next attempt to wait() will return INTERRUPTED w/o blocking. 112 * 113 * @return false if the thread was previously INTERRUPTED. 114 */ 115 bool interrupt(); 116 117 /** 118 * Notify this monitor. If there is a thread blocked on this monitor object 119 * it will be signaled and released. If there is no waiter, a flag is set and 120 * the next attempt to wait() will return SIGNALED w/o blocking, if no other 121 * flag is set. 122 * 123 * @return false if the thread was previously INTERRUPTED. 124 */ 125 bool notify(); 126 127 /** 128 * Check the state of this monitor, clearing the INTERRUPTED status if set. 129 * 130 * @return bool true if the monitor was INTERRUPTED. 131 * @post INTERRUPTED flag cleared if the calling thread owns the monitor. 132 */ 133 bool isInterrupted(); 134 135 /** 136 * Mark the Status CANCELED, and INTERRUPT the montor. 137 * 138 * @see interrupt() 139 */ 140 bool cancel(); 141 142 /** 143 * Test the CANCELED Status, clearing the INTERRUPTED status if set. 144 * 145 * @return bool 146 */ 147 bool isCanceled(); 148 149 }; 150 151 }; 152 153 #endif 154