00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Process_Mutex.h 00006 * 00007 * $Id: Process_Mutex.h 80826 2008-03-04 14:51:23Z wotte $ 00008 * 00009 * A wrapper for mutexes that can be used across processes on the 00010 * same host machine, as well as within a process, of course. 00011 * 00012 * @author Douglas C. Schmidt <schmidt@uci.edu> 00013 */ 00014 //============================================================================= 00015 00016 #ifndef ACE_PROCESS_MUTEX_H 00017 #define ACE_PROCESS_MUTEX_H 00018 00019 #include /**/ "ace/pre.h" 00020 00021 #include /**/ "ace/config-all.h" 00022 00023 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00024 # pragma once 00025 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00026 00027 // To make it easier to carry the setting though this file as well as 00028 // Process_Mutex.{cpp inl}, set a private macro here. 00029 #ifdef _ACE_USE_SV_SEM 00030 # undef _ACE_USE_SV_SEM 00031 #endif /* _ACE_USE_SV_SEM */ 00032 00033 #if defined (ACE_HAS_SYSV_IPC) && !defined (ACE_USES_MUTEX_FOR_PROCESS_MUTEX) 00034 # include "ace/SV_Semaphore_Complex.h" 00035 # define _ACE_USE_SV_SEM 00036 #else 00037 # include "ace/Mutex.h" 00038 #endif /* ACE_HAS_SYSV_IPC && !ACE_USES_MUTEX_FOR_PROCESS_MUTEX */ 00039 00040 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00041 00042 // Forward declarations 00043 class ACE_Time_Value; 00044 00045 /** 00046 * @class ACE_Process_Mutex 00047 * 00048 * @brief A wrapper for mutexes that can be used across processes on 00049 * the same host machine, as well as within a process, of 00050 * course. 00051 * 00052 * @attention The mechanism upon which @c ACE_Process_Mutex is based 00053 * can be configured at build time to be either @c ACE_SV_Semaphore_Complex 00054 * (on platforms that support it) or @c ACE_Mutex. On platforms that 00055 * require interprocess mutexes be allocated from shared memory (Pthreads 00056 * and UI Threads are examples), @c ACE_SV_Semaphore_Complex provides a 00057 * more reliable mechanism for implementing inter-process mutex than 00058 * @c ACE_Mutex. However, at least on some platforms, 00059 * @c ACE_SV_Semaphore_Complex is limited to a small number of 00060 * objects by the underlying System V IPC kernel parameters. If you 00061 * want to force use of @c ACE_Mutex as the underlying mechanism, set 00062 * @c ACE_USES_MUTEX_FOR_PROCESS_MUTEX in your @c config.h file. 00063 * Also, if you require the ability to do a timed @c acquire(), you must 00064 * set @c ACE_USES_MUTEX_FOR_PROCESS_MUTEX, as timed acquire does not 00065 * work with System V semaphores. 00066 * @attention Currently there is also the operational difference between 00067 * pthreads and semaphores based @c. For semaphore base @c the semaphore 00068 * is destroyed after the last instance of @c in OS. In contrary, pthread based 00069 * @c is destroyed when the owner, namely the process which created the 00070 * first instance of @c destroys the mutex. For protable applications it is better 00071 * to always ensure that the owner of the mutex destroys it after the 00072 * other processes. 00073 */ 00074 class ACE_Export ACE_Process_Mutex 00075 { 00076 public: 00077 /** 00078 * Create a Process_Mutex, passing in the optional @c name. 00079 * 00080 * @param name optional, null-terminated string containing the name of 00081 * the object. Multiple users of the same @c ACE_Process_Mutex must use 00082 * the same name to access the same object. If not specified, a name 00083 * is generated. 00084 * @param arg optional, attributes to be used to initialize the mutex. 00085 * If using @c ACE_SV_Semaphore_Complex as the underlying mechanism, 00086 * this argument is ignored. 00087 * @param mode optional, the protection mode for either the backing store 00088 * file (for ACE_Mutex use) or the ACE_SV_Semaphore_Complex that's created. 00089 */ 00090 ACE_Process_Mutex (const char *name = 0, 00091 void *arg = 0, 00092 mode_t mode = ACE_DEFAULT_FILE_PERMS); 00093 00094 #if defined (ACE_HAS_WCHAR) 00095 /** 00096 * Create a Process_Mutex, passing in the optional @c name. (@c wchar_t 00097 * version) 00098 * 00099 * @param name optional, null-terminated string containing the name of 00100 * the object. Multiple users of the same @c ACE_Process_Mutex must use 00101 * the same name to access the same object. If not specified, a name 00102 * is generated. 00103 * @param arg optional, attributes to be used to initialize the mutex. 00104 * If using @c ACE_SV_Semaphore_Complex as the underlying mechanism, 00105 * this argument is ignored. 00106 * @param mode optional, the protection mode for either the backing store 00107 * file (for ACE_Mutex use) or the ACE_SV_Semaphore_Complex that's created. 00108 */ 00109 ACE_Process_Mutex (const wchar_t *name, 00110 void *arg = 0, 00111 mode_t mode = ACE_DEFAULT_FILE_PERMS); 00112 #endif /* ACE_HAS_WCHAR */ 00113 00114 ~ACE_Process_Mutex (void); 00115 00116 /** 00117 * Explicitly destroy the mutex. Note that only one thread should 00118 * call this method since it doesn't protect against race 00119 * conditions. 00120 * 00121 * @return 0 on success; -1 on failure. 00122 */ 00123 int remove (void); 00124 00125 /** 00126 * Acquire lock ownership (wait on queue if necessary). 00127 * 00128 * @return 0 on success; -1 on failure. 00129 */ 00130 int acquire (void); 00131 00132 /** 00133 * Acquire lock ownership, but timeout if lock if hasn't been 00134 * acquired by given time. 00135 * 00136 * @param tv the absolute time until which the caller is willing to 00137 * wait to acquire the lock. 00138 * 00139 * @return 0 on success; -1 on failure. 00140 */ 00141 int acquire (ACE_Time_Value &tv); 00142 00143 /** 00144 * Conditionally acquire lock (i.e., don't wait on queue). 00145 * 00146 * @return 0 on success; -1 on failure. If the lock could not be acquired 00147 * because someone else already had the lock, @c errno is set to @c EBUSY. 00148 */ 00149 int tryacquire (void); 00150 00151 /// Release lock and unblock a thread at head of queue. 00152 int release (void); 00153 00154 /// Acquire lock ownership (wait on queue if necessary). 00155 int acquire_read (void); 00156 00157 /// Acquire lock ownership (wait on queue if necessary). 00158 int acquire_write (void); 00159 00160 /** 00161 * Conditionally acquire a lock (i.e., won't block). Returns -1 on 00162 * failure. If we "failed" because someone else already had the 00163 * lock, @c errno is set to @c EBUSY. 00164 */ 00165 int tryacquire_read (void); 00166 00167 /** 00168 * Conditionally acquire a lock (i.e., won't block). Returns -1 on 00169 * failure. If we "failed" because someone else already had the 00170 * lock, @c errno is set to @c EBUSY. 00171 */ 00172 int tryacquire_write (void); 00173 00174 /** 00175 * This is only here for consistency with the other synchronization 00176 * APIs and usability with Lock adapters. Assumes the caller already has 00177 * acquired the mutex and returns 0 in all cases. 00178 */ 00179 int tryacquire_write_upgrade (void); 00180 00181 #if !defined (_ACE_USE_SV_SEM) 00182 /// Return the underlying mutex. 00183 const ACE_mutex_t &lock (void) const; 00184 #endif /* !_ACE_USE_SV_SEM */ 00185 00186 /// Dump the state of an object. 00187 void dump (void) const; 00188 00189 /// Declare the dynamic allocation hooks. 00190 ACE_ALLOC_HOOK_DECLARE; 00191 00192 private: 00193 /// If the user does not provide a name we generate a unique name in 00194 /// this buffer. 00195 ACE_TCHAR name_[ACE_UNIQUE_NAME_LEN]; 00196 00197 /// Create and return the unique name. 00198 const ACE_TCHAR *unique_name (void); 00199 00200 #if defined (_ACE_USE_SV_SEM) 00201 /// We need this to get the right semantics... 00202 ACE_SV_Semaphore_Complex lock_; 00203 #else 00204 ACE_Mutex lock_; 00205 #endif /* _ACE_USE_SV_SEM */ 00206 }; 00207 00208 ACE_END_VERSIONED_NAMESPACE_DECL 00209 00210 #if defined (__ACE_INLINE__) 00211 #include "ace/Process_Mutex.inl" 00212 #endif /* __ACE_INLINE__ */ 00213 00214 #include /**/ "ace/post.h" 00215 00216 #endif /* ACE_PROCESS_MUTEX_H */