00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Process_Semaphore.h 00006 * 00007 * Process_Semaphore.h,v 4.16 2006/05/30 13:15:25 schmidt Exp 00008 * 00009 * Wrapper for Dijkstra style general semaphores that work 00010 * across processes. 00011 * 00012 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00013 */ 00014 //============================================================================= 00015 00016 #ifndef ACE_PROCESS_SEMAPHORE_H 00017 #define ACE_PROCESS_SEMAPHORE_H 00018 00019 #include /**/ "ace/pre.h" 00020 00021 #include "ace/ACE_export.h" 00022 00023 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00024 # pragma once 00025 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00026 00027 #if !(defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM)) 00028 # include "ace/SV_Semaphore_Complex.h" 00029 #else 00030 # include "ace/Semaphore.h" 00031 #endif /* !(ACE_WIN32 || ACE_HAS_POSIX_SEM) */ 00032 00033 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00034 00035 /** 00036 * @class ACE_Process_Semaphore 00037 * 00038 * @brief Wrapper for Dijkstra style general semaphores that work 00039 * across processes. 00040 */ 00041 class ACE_Export ACE_Process_Semaphore 00042 { 00043 public: 00044 /// Initialize the semaphore, with an initial value of @a count and a 00045 /// maximum value of @a max. 00046 ACE_Process_Semaphore (u_int count = 1, // By default make this unlocked. 00047 const ACE_TCHAR *name = 0, 00048 void * = 0, 00049 int max = 0x7FFFFFFF); 00050 00051 /** 00052 * This method is a no-op, i.e., it doesn't remove the semaphore. 00053 * If you want to remove the semaphore, you must call the <remove> 00054 * method explicitly. 00055 */ 00056 // ~ACE_Process_Semaphore (void); 00057 00058 /** 00059 * Explicitly destroy the semaphore. Note that only one thread 00060 * should call this method since it doesn't protect against race 00061 * conditions. 00062 */ 00063 int remove (void); 00064 00065 /// Block the thread until the semaphore count becomes greater than 00066 /// 0, then decrement it. 00067 int acquire (void); 00068 00069 /** 00070 * Conditionally decrement the semaphore if count is greater than 0 00071 * (i.e., won't block). Returns -1 on failure. If we "failed" 00072 * because someone else already had the lock, @c errno is set to 00073 * @c EBUSY. 00074 */ 00075 int tryacquire (void); 00076 00077 /// Increment the semaphore, potentially unblocking a waiting thread. 00078 int release (void); 00079 00080 /** 00081 * Acquire semaphore ownership. This calls <acquire> and is only 00082 * here to make the <ACE_Process_Semaphore> interface consistent 00083 * with the other synchronization APIs. 00084 */ 00085 int acquire_read (void); 00086 00087 /** 00088 * Acquire semaphore ownership. This calls <acquire> and is only 00089 * here to make the <ACE_Process_Semaphore> interface consistent 00090 * with the other synchronization APIs. 00091 */ 00092 int acquire_write (void); 00093 00094 /** 00095 * Conditionally acquire semaphore (i.e., won't block). This calls 00096 * <tryacquire> and is only here to make the <ACE_Process_Semaphore> 00097 * interface consistent with the other synchronization APIs. 00098 * Returns -1 on failure. If we "failed" because someone else 00099 * already had the lock, <errno> is set to <EBUSY>. 00100 */ 00101 int tryacquire_read (void); 00102 00103 /** 00104 * Conditionally acquire semaphore (i.e., won't block). This calls 00105 * <tryacquire> and is only here to make the ACE_Process_Semaphore 00106 * interface consistent with the other synchronization APIs. 00107 * Returns -1 on failure. If we "failed" because someone else 00108 * already had the lock, <errno> is set to <EBUSY>. 00109 */ 00110 int tryacquire_write (void); 00111 00112 /** 00113 * This is only here to make the ACE_Process_Semaphore 00114 * interface consistent with the other synchronization APIs. 00115 * Assumes the caller has already acquired the semaphore using one of 00116 * the above calls, and returns 0 (success) always. 00117 */ 00118 int tryacquire_write_upgrade (void); 00119 00120 #if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) 00121 /// Return the underlying lock. 00122 const ACE_sema_t &lock (void) const; 00123 #endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */ 00124 00125 /// Dump the state of an object. 00126 void dump (void) const; 00127 00128 /// Declare the dynamic allocation hooks. 00129 ACE_ALLOC_HOOK_DECLARE; 00130 00131 protected: 00132 #if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) 00133 ACE_Semaphore lock_; 00134 #else 00135 /// We need this to get the right semantics... 00136 ACE_SV_Semaphore_Complex lock_; 00137 #endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */ 00138 }; 00139 00140 /*****************************************************************************/ 00141 00142 template <class T> class ACE_Malloc_Lock_Adapter_T; 00143 00144 /** 00145 * @class ACE_Malloc_Lock_Adapter_T<ACE_Process_Semaphore> 00146 * 00147 * @brief Template specialization of ACE_Malloc_Lock_Adapter_T for 00148 * ACE_Process_Semaphore. 00149 * 00150 * This is needed since the ctor for ACE_Process_Semaphore doesn't match 00151 * the standard form used by other lock strategy classes. 00152 */ 00153 template<> 00154 class ACE_Export ACE_Malloc_Lock_Adapter_T<ACE_Process_Semaphore> 00155 { 00156 public: 00157 ACE_Process_Semaphore * operator () (const ACE_TCHAR *name); 00158 }; 00159 00160 ACE_END_VERSIONED_NAMESPACE_DECL 00161 00162 00163 #if defined (__ACE_INLINE__) 00164 #include "ace/Process_Semaphore.inl" 00165 #endif /* __ACE_INLINE__ */ 00166 00167 #include /**/ "ace/post.h" 00168 #endif /* ACE_PROCESS_SEMAPHORE_H */