00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Lock.h 00006 * 00007 * Lock.h,v 4.2 2005/10/28 16:14:53 ossama Exp 00008 * 00009 * Moved from Synch.h. 00010 * 00011 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00012 */ 00013 //========================================================================== 00014 00015 #ifndef ACE_LOCK_H 00016 #define ACE_LOCK_H 00017 #include /**/ "ace/pre.h" 00018 00019 #include "ace/ACE_export.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00026 00027 /** 00028 * @class ACE_Lock 00029 * 00030 * @brief This is the abstract base class that contains the uniform 00031 * locking API that is supported by all the ACE synchronization 00032 * mechanisms. 00033 * 00034 * This class is typically used in conjunction with the 00035 * <ACE_Lock_Adapter> in order to provide a polymorphic 00036 * interface to the ACE synchronization mechanisms (e.g., 00037 * <ACE_Mutex>, <ACE_Semaphore>, <ACE_RW_Mutex>, etc). Note that 00038 * the reason that all of ACE doesn't use polymorphic locks is 00039 * that (1) they add ~20% extra overhead for virtual function 00040 * calls and (2) objects with virtual functions can't be placed 00041 * into shared memory. 00042 */ 00043 class ACE_Export ACE_Lock 00044 { 00045 public: 00046 /// CE needs a default ctor here. 00047 ACE_Lock (void); 00048 00049 /// Noop virtual destructor 00050 virtual ~ACE_Lock (void); 00051 00052 /** 00053 * Explicitly destroy the lock. Note that only one thread should 00054 * call this method since it doesn't protect against race 00055 * conditions. 00056 */ 00057 virtual int remove (void) = 0; 00058 00059 /// Block the thread until the lock is acquired. Returns -1 on 00060 /// failure. 00061 virtual int acquire (void) = 0; 00062 00063 /** 00064 * Conditionally acquire the lock (i.e., won't block). Returns -1 00065 * on failure. If we "failed" because someone else already had the 00066 * lock, <errno> is set to <EBUSY>. 00067 */ 00068 virtual int tryacquire (void) = 0; 00069 00070 /// Release the lock. Returns -1 on failure. 00071 virtual int release (void) = 0; 00072 00073 /** 00074 * Block until the thread acquires a read lock. If the locking 00075 * mechanism doesn't support read locks then this just calls 00076 * <acquire>. Returns -1 on failure. 00077 */ 00078 virtual int acquire_read (void) = 0; 00079 00080 /** 00081 * Block until the thread acquires a write lock. If the locking 00082 * mechanism doesn't support read locks then this just calls 00083 * <acquire>. Returns -1 on failure. 00084 */ 00085 virtual int acquire_write (void) = 0; 00086 00087 /** 00088 * Conditionally acquire a read lock. If the locking mechanism 00089 * doesn't support read locks then this just calls <acquire>. 00090 * Returns -1 on failure. If we "failed" because someone else 00091 * already had the lock, <errno> is set to <EBUSY>. 00092 */ 00093 virtual int tryacquire_read (void) = 0; 00094 00095 /** 00096 * Conditionally acquire a write lock. If the locking mechanism 00097 * doesn't support read locks then this just calls <acquire>. 00098 * Returns -1 on failure. If we "failed" because someone else 00099 * already had the lock, <errno> is set to <EBUSY>. 00100 */ 00101 virtual int tryacquire_write (void) = 0; 00102 00103 /** 00104 * Conditionally try to upgrade a lock held for read to a write lock. 00105 * If the locking mechanism doesn't support read locks then this just 00106 * calls <acquire>. Returns 0 on success, -1 on failure. 00107 */ 00108 virtual int tryacquire_write_upgrade (void) = 0; 00109 }; 00110 00111 /** 00112 * @class ACE_Adaptive_Lock 00113 * 00114 * @brief An adaptive general locking class that defers the decision of 00115 * lock type to run time. 00116 * 00117 * This class, as ACE_Lock, provide a set of general locking APIs. 00118 * However, it defers our decision of what kind of lock to use 00119 * to the run time and delegates all locking operations to the actual 00120 * lock. Users must define a constructor in their subclass to 00121 * initialize <lock_>. 00122 */ 00123 class ACE_Export ACE_Adaptive_Lock : public ACE_Lock 00124 { 00125 public: 00126 /// You must also override the destructor function to match with how 00127 /// you construct the underneath <lock_>. 00128 virtual ~ACE_Adaptive_Lock (void); 00129 00130 // = Lock/unlock operations. 00131 00132 virtual int remove (void); 00133 virtual int acquire (void); 00134 virtual int tryacquire (void); 00135 virtual int release (void); 00136 virtual int acquire_read (void); 00137 virtual int acquire_write (void); 00138 virtual int tryacquire_read (void); 00139 virtual int tryacquire_write (void); 00140 virtual int tryacquire_write_upgrade (void); 00141 void dump (void) const; 00142 00143 protected: 00144 /** 00145 * Create and initialize create the actual lcok used in the class. 00146 * The default constructor simply set the <lock_> to 0 (null). You 00147 * must overwrite this method for this class to work. 00148 */ 00149 ACE_Adaptive_Lock (void); 00150 00151 ACE_Lock *lock_; 00152 }; 00153 00154 ACE_END_VERSIONED_NAMESPACE_DECL 00155 00156 #if defined (__ACE_INLINE__) 00157 #include "ace/Lock.inl" 00158 #endif /* __ACE_INLINE__ */ 00159 00160 #include /**/ "ace/post.h" 00161 #endif /* ACE_LOCK_H */