00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Atomic_Op_T.h 00006 * 00007 * $Id: Atomic_Op_T.h 76182 2006-12-27 12:42:24Z johnnyw $ 00008 * 00009 * @author Douglas C. Schmidt <schmidt@uci.edu> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_ATOMIC_OP_T_H 00014 #define ACE_ATOMIC_OP_T_H 00015 #include /**/ "ace/pre.h" 00016 00017 #include /**/ "ace/config-all.h" 00018 00019 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00020 # pragma once 00021 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00022 00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00024 00025 /** 00026 * @class ACE_Atomic_Op_Ex 00027 * 00028 * @brief Transparently parameterizes synchronization into basic 00029 * arithmetic operations. 00030 * 00031 * This class is described in an article in the July/August 1994 00032 * issue of the C++ Report magazine. It implements a 00033 * templatized version of the Decorator pattern from the GoF book. 00034 * 00035 * ACE_Atomic_Op_Ex objects must be constructed with a reference 00036 * to an existing lock. A single lock can be shared between 00037 * multiple ACE_Atomic_Op_Ex objects. If you do not require this 00038 * ability consider using the ACE_Atomic_Op class instead, which 00039 * may be able to take advantage of platform-specific 00040 * optimisations to provide atomic operations without requiring a 00041 * lock. 00042 */ 00043 template <class ACE_LOCK, class TYPE> 00044 class ACE_Atomic_Op_Ex 00045 { 00046 public: 00047 // = Initialization methods. 00048 00049 /// Initialize @c value_ to 0. 00050 ACE_Atomic_Op_Ex (ACE_LOCK &mtx); 00051 00052 /// Initialize @c value_ to c. 00053 ACE_Atomic_Op_Ex (ACE_LOCK &mtx, const TYPE &c); 00054 00055 // = Accessors. 00056 00057 /// Atomically pre-increment @c value_. 00058 TYPE operator++ (void); 00059 00060 /// Atomically post-increment @c value_. 00061 TYPE operator++ (int); 00062 00063 /// Atomically increment @c value_ by rhs. 00064 TYPE operator+= (const TYPE &rhs); 00065 00066 /// Atomically pre-decrement @c value_. 00067 TYPE operator-- (void); 00068 00069 /// Atomically post-decrement @c value_. 00070 TYPE operator-- (int); 00071 00072 /// Atomically decrement @c value_ by rhs. 00073 TYPE operator-= (const TYPE &rhs); 00074 00075 /// Atomically compare @c value_ with rhs. 00076 bool operator== (const TYPE &rhs) const; 00077 00078 /// Atomically compare @c value_ with rhs. 00079 bool operator!= (const TYPE &rhs) const; 00080 00081 /// Atomically check if @c value_ greater than or equal to rhs. 00082 bool operator>= (const TYPE &rhs) const; 00083 00084 /// Atomically check if @c value_ greater than rhs. 00085 bool operator> (const TYPE &rhs) const; 00086 00087 /// Atomically check if @c value_ less than or equal to rhs. 00088 bool operator<= (const TYPE &rhs) const; 00089 00090 /// Atomically check if @c value_ less than rhs. 00091 bool operator< (const TYPE &rhs) const; 00092 00093 /// Atomically assign rhs to @c value_. 00094 ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &operator= (const TYPE &rhs); 00095 00096 /// Atomically assign <rhs> to @c value_. 00097 ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &operator= (const ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &rhs); 00098 00099 /// Explicitly return @c value_. 00100 TYPE value (void) const; 00101 00102 /// Dump the state of an object. 00103 void dump (void) const; 00104 00105 // ACE_ALLOC_HOOK_DECLARE; 00106 // Declare the dynamic allocation hooks. 00107 00108 /// Manage copying... 00109 ACE_Atomic_Op_Ex (const ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &); 00110 00111 /** 00112 * Returns a reference to the underlying <ACE_LOCK>. This makes it 00113 * possible to acquire the lock explicitly, which can be useful in 00114 * some cases if you instantiate the <ACE_Atomic_Op_Ex> with an 00115 * ACE_Recursive_Mutex or ACE_Process_Mutex. @note the right 00116 * name would be lock_, but HP/C++ will choke on that! 00117 */ 00118 ACE_LOCK &mutex (void); 00119 00120 /** 00121 * Explicitly return @c value_ (by reference). This gives the user 00122 * full, unrestricted access to the underlying value. This method 00123 * will usually be used in conjunction with explicit access to the 00124 * lock. Use with care ;-) 00125 */ 00126 TYPE &value_i (void); 00127 00128 private: 00129 /// Type of synchronization mechanism. 00130 ACE_LOCK &mutex_; 00131 00132 /// Current object decorated by the atomic op. 00133 TYPE value_; 00134 }; 00135 00136 /** 00137 * @class ACE_Atomic_Op 00138 * 00139 * @brief Transparently parameterizes synchronization into basic 00140 * arithmetic operations. 00141 * 00142 * This class is described in an article in the July/August 1994 00143 * issue of the C++ Report magazine. It implements a 00144 * templatized version of the Decorator pattern from the GoF book. 00145 * 00146 * Certain platforms may provide a template specialization for 00147 * ACE_Atomic_Op <ACE_Thread_Mutex, long> that provides optimized 00148 * atomic integer operations without actually requiring a mutex. 00149 */ 00150 template <class ACE_LOCK, class TYPE> 00151 class ACE_Atomic_Op 00152 { 00153 public: 00154 /// Initialize @c value_ to 0. 00155 ACE_Atomic_Op (void); 00156 00157 /// Initialize @c value_ to c. 00158 ACE_Atomic_Op (const TYPE &c); 00159 00160 /// Manage copying... 00161 ACE_Atomic_Op (const ACE_Atomic_Op<ACE_LOCK, TYPE> &c); 00162 00163 /// Atomically assign rhs to @c value_. 00164 ACE_Atomic_Op<ACE_LOCK, TYPE> &operator= (const TYPE &rhs); 00165 00166 /// Atomically assign <rhs> to @c value_. 00167 ACE_Atomic_Op<ACE_LOCK, TYPE> &operator= (const ACE_Atomic_Op<ACE_LOCK, TYPE> &rhs); 00168 00169 /// Atomically pre-increment @c value_. 00170 TYPE operator++ (void); 00171 00172 /// Atomically post-increment @c value_. 00173 TYPE operator++ (int); 00174 00175 /// Atomically increment @c value_ by rhs. 00176 TYPE operator+= (const TYPE &rhs); 00177 00178 /// Atomically pre-decrement @c value_. 00179 TYPE operator-- (void); 00180 00181 /// Atomically post-decrement @c value_. 00182 TYPE operator-- (int); 00183 00184 /// Atomically decrement @c value_ by rhs. 00185 TYPE operator-= (const TYPE &rhs); 00186 00187 /// Atomically compare @c value_ with rhs. 00188 bool operator== (const TYPE &rhs) const; 00189 00190 /// Atomically compare @c value_ with rhs. 00191 bool operator!= (const TYPE &rhs) const; 00192 00193 /// Atomically check if @c value_ greater than or equal to rhs. 00194 bool operator>= (const TYPE &rhs) const; 00195 00196 /// Atomically check if @c value_ greater than rhs. 00197 bool operator> (const TYPE &rhs) const; 00198 00199 /// Atomically check if @c value_ less than or equal to rhs. 00200 bool operator<= (const TYPE &rhs) const; 00201 00202 /// Atomically check if @c value_ less than rhs. 00203 bool operator< (const TYPE &rhs) const; 00204 00205 /// Explicitly return @c value_. 00206 TYPE value (void) const; 00207 00208 /// Dump the state of an object. 00209 void dump (void) const; 00210 00211 /** 00212 * Returns a reference to the underlying <ACE_LOCK>. This makes it 00213 * possible to acquire the lock explicitly, which can be useful in 00214 * some cases if you instantiate the ACE_Atomic_Op with an 00215 * ACE_Recursive_Mutex or ACE_Process_Mutex. 00216 * 00217 * @deprecated This member function is deprecated and so may go away in 00218 * the future. If you need access to the underlying mutex, consider 00219 * using the ACE_Atomic_Op_Ex template instead. 00220 */ 00221 ACE_LOCK &mutex (void); 00222 00223 /** 00224 * Explicitly return @c value_ (by reference). This gives the user 00225 * full, unrestricted access to the underlying value. This method 00226 * will usually be used in conjunction with explicit access to the 00227 * lock. Use with care ;-) 00228 */ 00229 TYPE &value_i (void); 00230 00231 private: 00232 /// Type of synchronization mechanism. 00233 ACE_LOCK own_mutex_; 00234 00235 /// Underlying atomic op implementation. 00236 ACE_Atomic_Op_Ex <ACE_LOCK, TYPE> impl_; 00237 }; 00238 00239 ACE_END_VERSIONED_NAMESPACE_DECL 00240 00241 #if defined (__ACE_INLINE__) 00242 #include "ace/Atomic_Op_T.inl" 00243 #endif /* __ACE_INLINE__ */ 00244 00245 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00246 #include "ace/Atomic_Op_T.cpp" 00247 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00248 00249 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00250 #pragma implementation ("Atomic_Op_T.cpp") 00251 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00252 00253 #include /**/ "ace/post.h" 00254 #endif /*ACE_ATOMIC_OP_T_H*/