00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Process_Semaphore.h 00006 * 00007 * $Id: Process_Semaphore.h 80826 2008-03-04 14:51:23Z wotte $ 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 * Explicitly destroy the semaphore. Note that only one thread 00053 * should call this method since it doesn't protect against race 00054 * conditions. 00055 */ 00056 int remove (void); 00057 00058 /// Block the thread until the semaphore count becomes greater than 00059 /// 0, then decrement it. 00060 int acquire (void); 00061 00062 /** 00063 * Conditionally decrement the semaphore if count is greater than 0 00064 * (i.e., won't block). Returns -1 on failure. If we "failed" 00065 * because someone else already had the lock, @c errno is set to 00066 * @c EBUSY. 00067 */ 00068 int tryacquire (void); 00069 00070 /// Increment the semaphore, potentially unblocking a waiting thread. 00071 int release (void); 00072 00073 /** 00074 * Acquire semaphore ownership. This calls <acquire> and is only 00075 * here to make the ACE_Process_Semaphore interface consistent 00076 * with the other synchronization APIs. 00077 */ 00078 int acquire_read (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_write (void); 00086 00087 /** 00088 * Conditionally acquire semaphore (i.e., won't block). This calls 00089 * <tryacquire> and is only here to make the ACE_Process_Semaphore 00090 * interface consistent with the other synchronization APIs. 00091 * Returns -1 on failure. If we "failed" because someone else 00092 * already had the lock, @c errno is set to @c EBUSY. 00093 */ 00094 int tryacquire_read (void); 00095 00096 /** 00097 * Conditionally acquire semaphore (i.e., won't block). This calls 00098 * <tryacquire> and is only here to make the ACE_Process_Semaphore 00099 * interface consistent with the other synchronization APIs. 00100 * Returns -1 on failure. If we "failed" because someone else 00101 * already had the lock, @c errno is set to @c EBUSY. 00102 */ 00103 int tryacquire_write (void); 00104 00105 /** 00106 * This is only here to make the ACE_Process_Semaphore 00107 * interface consistent with the other synchronization APIs. 00108 * Assumes the caller has already acquired the semaphore using one of 00109 * the above calls, and returns 0 (success) always. 00110 */ 00111 int tryacquire_write_upgrade (void); 00112 00113 #if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) 00114 /// Return the underlying lock. 00115 const ACE_sema_t &lock (void) const; 00116 #endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */ 00117 00118 /// Dump the state of an object. 00119 void dump (void) const; 00120 00121 /// Declare the dynamic allocation hooks. 00122 ACE_ALLOC_HOOK_DECLARE; 00123 00124 protected: 00125 #if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) 00126 ACE_Semaphore lock_; 00127 #else 00128 /// We need this to get the right semantics... 00129 ACE_SV_Semaphore_Complex lock_; 00130 #endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */ 00131 }; 00132 00133 /*****************************************************************************/ 00134 00135 template <class T> class ACE_Malloc_Lock_Adapter_T; 00136 00137 /** 00138 * @class ACE_Malloc_Lock_Adapter_T<ACE_Process_Semaphore> 00139 * 00140 * @brief Template specialization of ACE_Malloc_Lock_Adapter_T for 00141 * ACE_Process_Semaphore. 00142 * 00143 * This is needed since the ctor for ACE_Process_Semaphore doesn't match 00144 * the standard form used by other lock strategy classes. 00145 */ 00146 template<> 00147 class ACE_Export ACE_Malloc_Lock_Adapter_T<ACE_Process_Semaphore> 00148 { 00149 public: 00150 ACE_Process_Semaphore * operator () (const ACE_TCHAR *name); 00151 }; 00152 00153 ACE_END_VERSIONED_NAMESPACE_DECL 00154 00155 00156 #if defined (__ACE_INLINE__) 00157 #include "ace/Process_Semaphore.inl" 00158 #endif /* __ACE_INLINE__ */ 00159 00160 #include /**/ "ace/post.h" 00161 #endif /* ACE_PROCESS_SEMAPHORE_H */