00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Semaphore.h 00006 * 00007 * $Id: Semaphore.h 78513 2007-05-29 07:08:16Z johnnyw $ 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 @a tv times out (in 00064 * which case -1 is returned and @c errno == @c ETIME). Note that @a tv 00065 * is assumed to be in "absolute" rather than "relative" time. The 00066 * value of @a 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 */ 00076 int acquire (ACE_Time_Value &tv); 00077 00078 /** 00079 * If @a tv == 0 then call <acquire()> directly. Otherwise, Block 00080 * the thread until the semaphore count becomes greater than 0 00081 * (at which point it is decremented) or until @a tv times out (in 00082 * which case -1 is returned and @c errno == @c ETIME). Note that 00083 * <*tv> is assumed to be in "absolute" rather than "relative" time. 00084 * The value of <*tv> is updated upon return to show the actual 00085 * (absolute) acquisition time. 00086 * 00087 * @note Solaris threads do not support timed semaphores. 00088 * Therefore, if you're running on Solaris you might want to 00089 * consider using the ACE POSIX pthreads implementation instead, 00090 * which can be enabled by compiling ACE with 00091 * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or 00092 * -DACE_HAS_POSIX_SEM. */ 00093 int acquire (ACE_Time_Value *tv); 00094 00095 /** 00096 * Conditionally decrement the semaphore if count is greater than 0 00097 * (i.e., won't block). Returns -1 on failure. If we "failed" 00098 * because someone else already had the lock, @c errno is set to 00099 * @c EBUSY. 00100 */ 00101 int tryacquire (void); 00102 00103 /// Increment the semaphore by 1, potentially unblocking a waiting 00104 /// thread. 00105 int release (void); 00106 00107 /// Increment the semaphore by @a release_count, potentially 00108 /// unblocking waiting threads. 00109 int release (unsigned int release_count); 00110 00111 /** 00112 * Acquire semaphore ownership. This calls <acquire> and is only 00113 * here to make the ACE_Semaphore interface consistent with the 00114 * other synchronization APIs. 00115 */ 00116 int acquire_read (void); 00117 00118 /** 00119 * Acquire semaphore ownership. This calls <acquire> and is only 00120 * here to make the ACE_Semaphore interface consistent with the 00121 * other synchronization APIs. 00122 */ 00123 int acquire_write (void); 00124 00125 /** 00126 * Conditionally acquire semaphore (i.e., won't block). This calls 00127 * <tryacquire> and is only here to make the ACE_Semaphore 00128 * interface consistent with the other synchronization APIs. 00129 * Returns -1 on failure. If we "failed" because someone else 00130 * already had the lock, @c errno is set to @c EBUSY. 00131 */ 00132 int tryacquire_read (void); 00133 00134 /** 00135 * Conditionally acquire semaphore (i.e., won't block). This calls 00136 * <tryacquire> and is only here to make the ACE_Semaphore 00137 * interface consistent with the other synchronization APIs. 00138 * Returns -1 on failure. If we "failed" because someone else 00139 * already had the lock, @c errno is set to @c EBUSY. 00140 */ 00141 int tryacquire_write (void); 00142 00143 /** 00144 * This is only here to make the ACE_Semaphore 00145 * interface consistent with the other synchronization APIs. 00146 * Assumes the caller has already acquired the semaphore using one of 00147 * the above calls, and returns 0 (success) always. 00148 */ 00149 int tryacquire_write_upgrade (void); 00150 00151 /// Dump the state of an object. 00152 void dump (void) const; 00153 00154 /// Declare the dynamic allocation hooks. 00155 ACE_ALLOC_HOOK_DECLARE; 00156 00157 /// Return the underlying lock. 00158 const ACE_sema_t &lock (void) const; 00159 00160 protected: 00161 ACE_sema_t semaphore_; 00162 00163 /// Keeps track of whether <remove> has been called yet to avoid 00164 /// multiple <remove> calls, e.g., explicitly and implicitly in the 00165 /// destructor. This flag isn't protected by a lock, so make sure 00166 /// that you don't have multiple threads simultaneously calling 00167 /// <remove> on the same object, which is a bad idea anyway... 00168 bool removed_; 00169 00170 private: 00171 // = Prevent assignment and initialization. 00172 void operator= (const ACE_Semaphore &); 00173 ACE_Semaphore (const ACE_Semaphore &); 00174 }; 00175 00176 ACE_END_VERSIONED_NAMESPACE_DECL 00177 00178 #if defined (__ACE_INLINE__) 00179 #include "ace/Semaphore.inl" 00180 #endif /* __ACE_INLINE__ */ 00181 00182 #include /**/ "ace/post.h" 00183 #endif /* ACE_SEMAPHORE_H */