00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Semaphore.h 00006 * 00007 * Semaphore.h,v 4.4 2006/01/26 11:33:15 jwillemsen Exp 00008 * 00009 * Moved from Synch.h. 00010 * 00011 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00012 */ 00013 //========================================================================== 00014 00015 #ifndef ACE_SEMAPHORE_H 00016 #define ACE_SEMAPHORE_H 00017 #include /**/ "ace/pre.h" 00018 00019 #include "ace/ACE_export.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/OS_NS_Thread.h" 00026 00027 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00028 00029 class ACE_Time_Value; 00030 00031 /** 00032 * @class ACE_Semaphore 00033 * 00034 * @brief Wrapper for Dijkstra style general semaphores. 00035 */ 00036 class ACE_Export ACE_Semaphore 00037 { 00038 public: 00039 // = Initialization and termination. 00040 /// Initialize the semaphore, with initial value of "count". 00041 ACE_Semaphore (unsigned int count = 1, // By default make this unlocked. 00042 int type = USYNC_THREAD, 00043 const ACE_TCHAR *name = 0, 00044 void * = 0, 00045 int max = 0x7fffffff); 00046 00047 /// Implicitly destroy the semaphore. 00048 ~ACE_Semaphore (void); 00049 00050 /** 00051 * Explicitly destroy the semaphore. Note that only one thread 00052 * should call this method since it doesn't protect against race 00053 * conditions. 00054 */ 00055 int remove (void); 00056 00057 /// Block the thread until the semaphore count becomes 00058 /// greater than 0, then decrement it. 00059 int acquire (void); 00060 00061 /** 00062 * Block the thread until the semaphore count becomes greater than 0 00063 * (at which point it is decremented) or until <tv> times out (in 00064 * which case -1 is returned and <errno> == <ETIME>). Note that <tv> 00065 * is assumed to be in "absolute" rather than "relative" time. The 00066 * value of <tv> is updated upon return to show the actual 00067 * (absolute) acquisition time. 00068 * 00069 * @note Solaris threads do not support timed semaphores. 00070 * Therefore, if you're running on Solaris you might want to 00071 * consider using the ACE POSIX pthreads implementation instead, 00072 * which can be enabled by compiling ACE with 00073 * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or 00074 * -DACE_HAS_POSIX_SEM. */ 00075 int acquire (ACE_Time_Value &tv); 00076 00077 /** 00078 * If <tv> == 0 then call <acquire()> directly. Otherwise, Block 00079 * the thread until the semaphore count becomes greater than 0 00080 * (at which point it is decremented) or until <tv> times out (in 00081 * which case -1 is returned and <errno> == <ETIME>). Note that 00082 * <*tv> is assumed to be in "absolute" rather than "relative" time. 00083 * The value of <*tv> is updated upon return to show the actual 00084 * (absolute) acquisition time. 00085 * 00086 * @note Solaris threads do not support timed semaphores. 00087 * Therefore, if you're running on Solaris you might want to 00088 * consider using the ACE POSIX pthreads implementation instead, 00089 * which can be enabled by compiling ACE with 00090 * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or 00091 * -DACE_HAS_POSIX_SEM. */ 00092 int acquire (ACE_Time_Value *tv); 00093 00094 /** 00095 * Conditionally decrement the semaphore if count is greater than 0 00096 * (i.e., won't block). Returns -1 on failure. If we "failed" 00097 * because someone else already had the lock, <errno> is set to 00098 * <EBUSY>. 00099 */ 00100 int tryacquire (void); 00101 00102 /// Increment the semaphore by 1, potentially unblocking a waiting 00103 /// thread. 00104 int release (void); 00105 00106 /// Increment the semaphore by <release_count>, potentially 00107 /// unblocking waiting threads. 00108 int release (unsigned int release_count); 00109 00110 /** 00111 * Acquire semaphore ownership. This calls <acquire> and is only 00112 * here to make the <ACE_Semaphore> interface consistent with the 00113 * other synchronization APIs. 00114 */ 00115 int acquire_read (void); 00116 00117 /** 00118 * Acquire semaphore ownership. This calls <acquire> and is only 00119 * here to make the <ACE_Semaphore> interface consistent with the 00120 * other synchronization APIs. 00121 */ 00122 int acquire_write (void); 00123 00124 /** 00125 * Conditionally acquire semaphore (i.e., won't block). This calls 00126 * <tryacquire> and is only here to make the <ACE_Semaphore> 00127 * interface consistent with the other synchronization APIs. 00128 * Returns -1 on failure. If we "failed" because someone else 00129 * already had the lock, <errno> is set to <EBUSY>. 00130 */ 00131 int tryacquire_read (void); 00132 00133 /** 00134 * Conditionally acquire semaphore (i.e., won't block). This calls 00135 * <tryacquire> and is only here to make the <ACE_Semaphore> 00136 * interface consistent with the other synchronization APIs. 00137 * Returns -1 on failure. If we "failed" because someone else 00138 * already had the lock, <errno> is set to <EBUSY>. 00139 */ 00140 int tryacquire_write (void); 00141 00142 /** 00143 * This is only here to make the <ACE_Semaphore> 00144 * interface consistent with the other synchronization APIs. 00145 * Assumes the caller has already acquired the semaphore using one of 00146 * the above calls, and returns 0 (success) always. 00147 */ 00148 int tryacquire_write_upgrade (void); 00149 00150 /// Dump the state of an object. 00151 void dump (void) const; 00152 00153 /// Declare the dynamic allocation hooks. 00154 ACE_ALLOC_HOOK_DECLARE; 00155 00156 /// Return the underlying lock. 00157 const ACE_sema_t &lock (void) const; 00158 00159 protected: 00160 ACE_sema_t semaphore_; 00161 00162 /// Keeps track of whether <remove> has been called yet to avoid 00163 /// multiple <remove> calls, e.g., explicitly and implicitly in the 00164 /// destructor. This flag isn't protected by a lock, so make sure 00165 /// that you don't have multiple threads simultaneously calling 00166 /// <remove> on the same object, which is a bad idea anyway... 00167 int removed_; 00168 00169 private: 00170 // = Prevent assignment and initialization. 00171 void operator= (const ACE_Semaphore &); 00172 ACE_Semaphore (const ACE_Semaphore &); 00173 }; 00174 00175 ACE_END_VERSIONED_NAMESPACE_DECL 00176 00177 #if defined (__ACE_INLINE__) 00178 #include "ace/Semaphore.inl" 00179 #endif /* __ACE_INLINE__ */ 00180 00181 #include /**/ "ace/post.h" 00182 #endif /* ACE_SEMAPHORE_H */