00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Guard_T.h 00006 * 00007 * $Id: Guard_T.h 80826 2008-03-04 14:51:23Z wotte $ 00008 * 00009 * Moved from Synch.h. 00010 * 00011 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00012 */ 00013 //========================================================================== 00014 00015 #ifndef ACE_GUARD_T_H 00016 #define ACE_GUARD_T_H 00017 #include /**/ "ace/pre.h" 00018 00019 #include "ace/Lock.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/Global_Macros.h" 00026 #include "ace/OS_NS_Thread.h" 00027 00028 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00029 00030 /** 00031 * @class ACE_Guard 00032 * 00033 * @brief This data structure is meant to be used within a method or 00034 * function... It performs automatic aquisition and release of 00035 * a parameterized synchronization object <ACE_LOCK>. 00036 * 00037 * The <ACE_LOCK> class given as an actual parameter must provide at 00038 * the very least the <acquire>, <tryacquire>, <release>, and 00039 * <remove> methods. 00040 */ 00041 template <class ACE_LOCK> 00042 class ACE_Guard 00043 { 00044 public: 00045 00046 // = Initialization and termination methods. 00047 ACE_Guard (ACE_LOCK &l); 00048 00049 /// Implicitly and automatically acquire (or try to acquire) the 00050 /// lock. If @a block is non-0 then <acquire> the <ACE_LOCK>, else 00051 /// <tryacquire> it. 00052 ACE_Guard (ACE_LOCK &l, int block); 00053 00054 /// Initialise the guard without implicitly acquiring the lock. The 00055 /// <become_owner> parameter indicates whether the guard should release 00056 /// the lock implicitly on destruction. The <block> parameter is 00057 /// ignored and is used here to disambiguate with the preceding 00058 /// constructor. 00059 ACE_Guard (ACE_LOCK &l, int block, int become_owner); 00060 00061 /// Implicitly release the lock. 00062 ~ACE_Guard (void); 00063 00064 // = Lock accessors. 00065 00066 /// Explicitly acquire the lock. 00067 int acquire (void); 00068 00069 /// Conditionally acquire the lock (i.e., won't block). 00070 int tryacquire (void); 00071 00072 /// Explicitly release the lock, but only if it is held! 00073 int release (void); 00074 00075 /// Relinquish ownership of the lock so that it is not released 00076 /// implicitly in the destructor. 00077 void disown (void); 00078 00079 // = Utility methods. 00080 /// 1 if locked, 0 if couldn't acquire the lock 00081 /// (errno will contain the reason for this). 00082 int locked (void) const; 00083 00084 /// Explicitly remove the lock. 00085 int remove (void); 00086 00087 /// Dump the state of an object. 00088 void dump (void) const; 00089 00090 // ACE_ALLOC_HOOK_DECLARE; 00091 // Declare the dynamic allocation hooks. 00092 00093 protected: 00094 00095 /// Helper, meant for subclass only. 00096 ACE_Guard (ACE_LOCK *lock): lock_ (lock) {} 00097 00098 /// Pointer to the ACE_LOCK we're guarding. 00099 ACE_LOCK *lock_; 00100 00101 /// Keeps track of whether we acquired the lock or failed. 00102 int owner_; 00103 00104 private: 00105 // = Prevent assignment and initialization. 00106 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Guard<ACE_LOCK> &)) 00107 ACE_UNIMPLEMENTED_FUNC (ACE_Guard (const ACE_Guard<ACE_LOCK> &)) 00108 }; 00109 00110 /** 00111 * @class ACE_Write_Guard 00112 * 00113 * @brief This class is similar to class ACE_Guard, though it 00114 * acquires/releases a write lock automatically (naturally, the 00115 * <ACE_LOCK> it is instantiated with must support the appropriate 00116 * API). 00117 */ 00118 template <class ACE_LOCK> 00119 class ACE_Write_Guard : public ACE_Guard<ACE_LOCK> 00120 { 00121 public: 00122 // = Initialization method. 00123 00124 /// Implicitly and automatically acquire a write lock. 00125 ACE_Write_Guard (ACE_LOCK &m); 00126 00127 /// Implicitly and automatically acquire (or try to acquire) a write 00128 /// lock. 00129 ACE_Write_Guard (ACE_LOCK &m, int block); 00130 00131 // = Lock accessors. 00132 00133 /// Explicitly acquire the write lock. 00134 int acquire_write (void); 00135 00136 /// Explicitly acquire the write lock. 00137 int acquire (void); 00138 00139 /// Conditionally acquire the write lock (i.e., won't block). 00140 int tryacquire_write (void); 00141 00142 /// Conditionally acquire the write lock (i.e., won't block). 00143 int tryacquire (void); 00144 00145 // = Utility methods. 00146 00147 /// Dump the state of an object. 00148 void dump (void) const; 00149 00150 // ACE_ALLOC_HOOK_DECLARE; 00151 // Declare the dynamic allocation hooks. 00152 }; 00153 00154 /** 00155 * @class ACE_Read_Guard 00156 * 00157 * @brief This class is similar to class ACE_Guard, though it 00158 * acquires/releases a read lock automatically (naturally, the 00159 * <ACE_LOCK> it is instantiated with must support the appropriate 00160 * API). 00161 */ 00162 template <class ACE_LOCK> 00163 class ACE_Read_Guard : public ACE_Guard<ACE_LOCK> 00164 { 00165 public: 00166 // = Initialization methods. 00167 00168 /// Implicitly and automatically acquire a read lock. 00169 ACE_Read_Guard (ACE_LOCK& m); 00170 00171 /// Implicitly and automatically acquire (or try to acquire) a read 00172 /// lock. 00173 ACE_Read_Guard (ACE_LOCK &m, int block); 00174 00175 // = Lock accessors. 00176 00177 /// Explicitly acquire the read lock. 00178 int acquire_read (void); 00179 00180 /// Explicitly acquire the read lock. 00181 int acquire (void); 00182 00183 /// Conditionally acquire the read lock (i.e., won't block). 00184 int tryacquire_read (void); 00185 00186 /// Conditionally acquire the read lock (i.e., won't block). 00187 int tryacquire (void); 00188 00189 // = Utility methods. 00190 00191 /// Dump the state of an object. 00192 void dump (void) const; 00193 00194 // ACE_ALLOC_HOOK_DECLARE; 00195 // Declare the dynamic allocation hooks. 00196 }; 00197 00198 #if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) 00199 00200 #define ACE_TSS_Guard ACE_Guard 00201 #define ACE_TSS_Write_GUARD ACE_Write_Guard 00202 #define ACE_TSS_Read_GUARD ACE_Read_Guard 00203 00204 #else 00205 /* ACE platform supports some form of threading and 00206 thread-specific storage. */ 00207 00208 /** 00209 * @class ACE_TSS_Guard 00210 * 00211 * @brief This data structure is meant to be used within a method or 00212 * function... It performs automatic aquisition and release of 00213 * a synchronization object. Moreover, it ensures that the lock 00214 * is released even if a thread exits via <thr_exit>! 00215 */ 00216 template <class ACE_LOCK> 00217 class ACE_TSS_Guard 00218 { 00219 public: 00220 // = Initialization and termination methods. 00221 00222 /// Implicitly and automatically acquire the thread-specific lock. 00223 ACE_TSS_Guard (ACE_LOCK &lock, int block = 1); 00224 00225 /// Implicitly release the thread-specific lock. 00226 ~ACE_TSS_Guard (void); 00227 00228 // = Lock accessors. 00229 00230 /// Explicitly acquire the thread-specific lock. 00231 int acquire (void); 00232 00233 /// Conditionally acquire the thread-specific lock (i.e., won't 00234 /// block). 00235 int tryacquire (void); 00236 00237 /// Explicitly release the thread-specific lock. 00238 int release (void); 00239 00240 // = Utility methods. 00241 /// Explicitly release the thread-specific lock. 00242 int remove (void); 00243 00244 /// Dump the state of an object. 00245 void dump (void) const; 00246 00247 // ACE_ALLOC_HOOK_DECLARE; 00248 // Declare the dynamic allocation hooks. 00249 00250 protected: 00251 /// Helper, meant for subclass only. 00252 ACE_TSS_Guard (void); 00253 00254 /// Initialize the key. 00255 void init_key (void); 00256 00257 /// Called when thread exits to clean up the lock. 00258 static void cleanup (void *ptr); 00259 00260 /// Thread-specific key... 00261 ACE_thread_key_t key_; 00262 00263 private: 00264 // = Prevent assignment and initialization. 00265 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Guard<ACE_LOCK> &)) 00266 ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Guard (const ACE_TSS_Guard<ACE_LOCK> &)) 00267 }; 00268 00269 /** 00270 * @class ACE_TSS_Write_Guard 00271 * 00272 * @brief This class is similar to class ACE_TSS_Guard, though it 00273 * acquires/releases a write-lock automatically (naturally, the 00274 * ACE_LOCK it is instantiated with must support the appropriate 00275 * API). 00276 */ 00277 template <class ACE_LOCK> 00278 class ACE_TSS_Write_Guard : public ACE_TSS_Guard<ACE_LOCK> 00279 { 00280 public: 00281 // = Initialization method. 00282 00283 /// Implicitly and automatically acquire the thread-specific write lock. 00284 ACE_TSS_Write_Guard (ACE_LOCK &lock, int block = 1); 00285 00286 // = Lock accessors. 00287 00288 /// Explicitly acquire the thread-specific write lock. 00289 int acquire_write (void); 00290 00291 /// Explicitly acquire the thread-specific write lock. 00292 int acquire (void); 00293 00294 /// Conditionally acquire the thread-specific write lock (i.e., won't block). 00295 int tryacquire_write (void); 00296 00297 /// Conditionally acquire the thread-specific write lock (i.e., won't block). 00298 int tryacquire (void); 00299 00300 // = Utility methods. 00301 00302 /// Dump the state of an object. 00303 void dump (void) const; 00304 00305 // ACE_ALLOC_HOOK_DECLARE; 00306 // Declare the dynamic allocation hooks. 00307 }; 00308 00309 /** 00310 * @class ACE_TSS_Read_Guard 00311 * 00312 * @brief This class is similar to class <ACE_TSS_Guard>, though it 00313 * acquires/releases a read lock automatically (naturally, the 00314 * <ACE_LOCK> it is instantiated with must support the 00315 * appropriate API). 00316 */ 00317 template <class ACE_LOCK> 00318 class ACE_TSS_Read_Guard : public ACE_TSS_Guard<ACE_LOCK> 00319 { 00320 public: 00321 // = Initialization method. 00322 /// Implicitly and automatically acquire the thread-specific read lock. 00323 ACE_TSS_Read_Guard (ACE_LOCK &lock, int block = 1); 00324 00325 // = Lock accessors. 00326 /// Explicitly acquire the thread-specific read lock. 00327 int acquire_read (void); 00328 00329 /// Explicitly acquire the thread-specific read lock. 00330 int acquire (void); 00331 00332 /// Conditionally acquire the thread-specific read lock (i.e., won't 00333 /// block). 00334 int tryacquire_read (void); 00335 00336 /// Conditionally acquire the thread-specific read lock (i.e., won't 00337 /// block). 00338 int tryacquire (void); 00339 00340 // = Utility methods. 00341 /// Dump the state of an object. 00342 void dump (void) const; 00343 00344 // ACE_ALLOC_HOOK_DECLARE; 00345 // Declare the dynamic allocation hooks. 00346 }; 00347 00348 #endif /* !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ 00349 00350 ACE_END_VERSIONED_NAMESPACE_DECL 00351 00352 #if defined (__ACE_INLINE__) 00353 #include "ace/Guard_T.inl" 00354 #endif /* __ACE_INLINE__ */ 00355 00356 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00357 #include "ace/Guard_T.cpp" 00358 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00359 00360 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00361 #pragma implementation ("Guard_T.cpp") 00362 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00363 00364 #include /**/ "ace/post.h" 00365 #endif /* ACE_GUARD_T_H */