00001 /* 00002 * ConcurrentMap.hpp 00003 * 00004 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Oracle is a registered trademarks of Oracle Corporation and/or its 00007 * affiliates. 00008 * 00009 * This software is the confidential and proprietary information of Oracle 00010 * Corporation. You shall not disclose such confidential and proprietary 00011 * information and shall use it only in accordance with the terms of the 00012 * license agreement you entered into with Oracle. 00013 * 00014 * This notice may not be removed or altered. 00015 */ 00016 #ifndef COH_CONCURRENT_MAP_HPP 00017 #define COH_CONCURRENT_MAP_HPP 00018 00019 #include "coherence/lang.ns" 00020 00021 #include "coherence/util/Map.hpp" 00022 00023 COH_OPEN_NAMESPACE2(coherence,util) 00024 00025 00026 /** 00027 * Map with additional concurrency features. 00028 * 00029 * @author jh 2008.03.05 00030 */ 00031 class COH_EXPORT ConcurrentMap 00032 : public interface_spec<ConcurrentMap, 00033 implements<Map> > 00034 { 00035 // ----- handle definitions (needed for nested classes) ----------------- 00036 00037 public: 00038 typedef this_spec::Handle Handle; 00039 typedef this_spec::View View; 00040 typedef this_spec::Holder Holder; 00041 00042 00043 // ----- ConcurrentMap interface ---------------------------------------- 00044 00045 public: 00046 /** 00047 * Attempt to lock the specified item within the specified period of 00048 * time. 00049 * 00050 * The item doesn't have to exist to be <i>locked</i>. While the item 00051 * is locked there is known to be a <i>lock holder</i> which has an 00052 * exclusive right to modify (calling put and remove methods) that 00053 * item. 00054 * 00055 * Lock holder is an abstract concept that depends on the 00056 * ConcurrentMap implementation. For example, holder could be a 00057 * process or a thread (or both). 00058 * 00059 * Locking strategy may vary for concrete implementations as well. 00060 * Lock could have an expiration time (this lock is sometimes called a 00061 * "lease") or be held indefinitely (until the lock holder 00062 * terminates). 00063 * 00064 * Some implementations may allow the entire map to be locked. If the 00065 * map is locked in such a way, then only a lock holder is allowed to 00066 * perform any of the "put" or "remove" operations. Pass the special 00067 * constant {@link #getLockAll()} as the <i>vKey</i> parameter to 00068 * indicate the map lock. 00069 * 00070 * @param vKey key being locked 00071 * @param cWait the number of milliseconds to continue trying to 00072 * obtain a lock; pass zero to return immediately; pass 00073 * -1 to block the calling thread until the lock could be 00074 * obtained 00075 * 00076 * @return true if the item was successfully locked within the 00077 * specified time; false otherwise 00078 */ 00079 virtual bool lock(Object::View vKey, int64_t cWait) const = 0; 00080 00081 /** 00082 * Attempt to lock the specified item and return immediately. 00083 * 00084 * This method behaves exactly as if it simply performs the call 00085 * <tt>lock(vKey, 0)</tt>. 00086 * 00087 * @param vKey key being locked 00088 * 00089 * @return true if the item was successfully locked; false otherwise 00090 */ 00091 virtual bool lock(Object::View vKey) const = 0; 00092 00093 /** 00094 * Unlock the specified item. The item doesn't have to exist to be 00095 * <i>unlocked</i>. If the item is currently locked, only the 00096 * <i>holder</i> of the lock could successfully unlock it. 00097 * 00098 * @param vKey key being unlocked 00099 * 00100 * @return true if the item was successfully unlocked; false otherwise 00101 */ 00102 virtual bool unlock(Object::View vKey) const = 0; 00103 00104 00105 // ----- inner class: LockBlock ----------------------------------------- 00106 00107 public: 00108 /** 00109 * The LockBlock allows for easy creation of ConcurrentMap::lock code. 00110 * It's used on conjunction with the COH_CACHE_LOCK macros. 00111 */ 00112 class LockBlock 00113 { 00114 // ----- constructors --------------------------------------- 00115 00116 public: 00117 /** 00118 * Construct a LockBlock that will lock the supplied map. 00119 * 00120 * @param hMap the map to lock 00121 * @param vKey the Key to lock int he map 00122 * @param cWait the number of milliseconds to continue trying 00123 * to obtain a lock; pass zero to return 00124 * immediately; pass -1 to block the calling 00125 * thread until the lock could be obtained 00126 */ 00127 LockBlock(ConcurrentMap::Handle hMap, Object::View vKey, 00128 bool fTryLock, int64_t cWait = -1L); 00129 00130 /** 00131 * Copy constructor used by the COH_CACHE_LOCK macros 00132 */ 00133 LockBlock(const LockBlock& that); 00134 00135 /** 00136 * Destroy an LockBlock object, exiting the associated map 00137 */ 00138 ~LockBlock(); 00139 00140 // ----- LockBlock interface --------------------------------- 00141 00142 public: 00143 /** 00144 * Boolean conversion for the COH_CACHE_LOCK macros 00145 * 00146 * @return true if it's a time based lock and false if no 00147 */ 00148 operator bool() const; 00149 00150 private: 00151 /** 00152 * Blocked assignment operator 00153 */ 00154 const LockBlock& operator=(const LockBlock&); 00155 00156 /** 00157 * Blocked dynamic allocation. 00158 */ 00159 static void* operator new(size_t); 00160 00161 // ----- data members --------------------------------------- 00162 00163 protected: 00164 /** 00165 * Map to lock and unlock 00166 */ 00167 mutable ConcurrentMap::Handle m_hMap; // on stack 00168 00169 /** 00170 * Key to lock and unlock in the associated Map 00171 */ 00172 const Object::View m_vKey; // on stack 00173 00174 /** 00175 * Flag describing the type of lock being used 00176 */ 00177 const bool m_fTryLock; 00178 }; 00179 00180 00181 // ----- constants ------------------------------------------------------ 00182 00183 public: 00184 /** 00185 * Special key value indicating an intent to lock the entire map. 00186 */ 00187 static Object::View getLockAll(); 00188 }; 00189 00190 00191 // ----- non-member operators and functions --------------------------------- 00192 00193 00194 /** 00195 * Macro for more readable cache locking blocks. See the ConcurrentMap docs 00196 * for more details. 00197 */ 00198 #define COH_CACHE_LOCK(MAP, KEY) \ 00199 if (coherence::util::ConcurrentMap::LockBlock COH_UNIQUE_IDENTIFIER(_coh_cache_lock_) \ 00200 = coherence::util::ConcurrentMap::LockBlock(MAP, KEY, false, -1L)) \ 00201 { \ 00202 COH_THROW(coherence::lang::IllegalStateException::create()); \ 00203 } \ 00204 else 00205 00206 00207 #define COH_CACHE_TRYLOCK(MAP, KEY, TIME) \ 00208 if (coherence::util::ConcurrentMap::LockBlock COH_UNIQUE_IDENTIFIER(_coh_cache_trylock_) \ 00209 = coherence::util::ConcurrentMap::LockBlock( \ 00210 coherence::util::ConcurrentMap::LockBlock(MAP, KEY, true, TIME))) 00211 00212 COH_CLOSE_NAMESPACE2 00213 00214 #endif // COH_CONCURRENT_MAP_HPP