00001 /* 00002 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. 00003 * 00004 * Licensed under the Universal Permissive License v 1.0 as shown at 00005 * http://oss.oracle.com/licenses/upl. 00006 */ 00007 #ifndef COH_OBJECT_HPP 00008 #define COH_OBJECT_HPP 00009 00010 #include "coherence/lang/compatibility.hpp" 00011 00012 #include "coherence/lang/cloneable_spec.hpp" 00013 #include "coherence/lang/LifeCycle.hpp" 00014 #include "coherence/lang/TypedHandle.hpp" 00015 #include "coherence/lang/TypedHolder.hpp" 00016 #include "coherence/native/NativeAtomic32.hpp" 00017 00018 #include <ostream> 00019 00020 COH_OPEN_NAMESPACE2(coherence,native) 00021 class NativeCondition; 00022 COH_CLOSE_NAMESPACE2 00023 00024 COH_OPEN_NAMESPACE2(coherence,lang) 00025 00026 class Object; 00027 class SmartMember; 00028 class String; 00029 class WeakReference; 00030 00031 using coherence::native::NativeAtomic32; 00032 using coherence::native::NativeCondition; 00033 00034 00035 /** 00036 * Object is the base class for all Coherence managed objects. 00037 * 00038 * The interface for Object provides support basic operations such as equality, 00039 * hashing, printing, cloning, synchronization, and notification. 00040 * 00041 * Objects have automatically managed memory, through built-in thread-safe 00042 * reference counting. The reference count is maintained through the use of 00043 * smart-pointers, known as handles. All references to an Object should be 00044 * maintained through a handle rather then a raw pointer, or C++ reference. 00045 * 00046 * Each managed class includes inner definitions of handles which can be used 00047 * to reference instance of that class, as well as derived class instances. 00048 * These definitions provide functionality corresponding to const and non-const 00049 * pointers. The names for these handles are Handle for the non-const, View for 00050 * the const pointer equivalent, and Holder for a hybrid. The Holder type acts 00051 * like a View but allows for a safe down-cast to a Handle, which will only 00052 * succeed if the Holder was assigned from a Handle, and will fail with a 00053 * ClassCastException if it had been assigned from a View. Note that in 00054 * documentation the term "handle" is used to describe any handle type 00055 * including Handle/View/Holder, while "Handle" refers to the specific 00056 * "Handle" type. 00057 * 00058 * The handles are aware of the inheritance hierarchy, allowing direct 00059 * assignment from a handle from a derived class to a handle of a base class. 00060 * These up-casts are automatic, and an explicit cast operation is rarely 00061 * needed, except to resolve compiler type ambiguities. Assignment from a View 00062 * to a Handle is also automatic as the const-interface of a class can 00063 * naturally be considered a base-class. Assignment of a handle to a derived 00064 * type is not automatic, and requires an explicit down-cast via the coherence 00065 * cast<H>(h) function. The template parameter is the desired handle type, while 00066 * the function parameter is the handle to cast. If the supplied handle is 00067 * non-NULL and is not an instance of the class associated with H, a 00068 * ClassCastException will be thrown. There is a corresponding instanceof<H>(h) 00069 * method which can be used to perform the type-check without the risk of 00070 * triggering an exception. The use of instanceof, is optional, and is only 00071 * needed if the type is actually in question. 00072 * 00073 * @code 00074 * Object::Handle hObject = ... 00075 * Foo::Handle hFoo; 00076 * 00077 * if (instanceof<Foo::Handle>(hObject)) 00078 * { 00079 * hFoo = cast<Foo::Handle>(hObject); 00080 * } 00081 * @endcode 00082 * 00083 * These convenience handles are not thread-safe, and should not be used in a 00084 * multi-threaded context. They should only be used as local variables, though 00085 * they are free to reference objects shared by many threads. The most common 00086 * place where thread-safe handles are needed is for data members of managed 00087 * objects. For these cases the Coherence API includes a variety of thread-safe 00088 * handles/views. It is necessary that any class which extends from Object use 00089 * thread-safe handles when referencing other managed Objects. 00090 * 00091 * By convention managed objects will also block direct external access to 00092 * their constructor and destructor. Constructors are accessed via public 00093 * static "create" factory methods. The copy constructor is accessed via the 00094 * public virtual "clone" method. Destructors are protected and destruction 00095 * is triggered automatically when the internal reference count reaches zero. 00096 * 00097 * @see class_spec for defining non-cloneable classes 00098 * @see cloneable_spec for defining cloneable classes 00099 * @see abstract_spec for defining abstract classes 00100 * @see interface_spec for defining interfaces 00101 * @see throwable_spec for defining exceptions 00102 * @see MemberHandle for thread-safe data member handles 00103 * @see MemberView for thread-safe data member views 00104 * @see MemberHolder for thread-safe data member holders 00105 * @see FinalHandle for thread-safe "const" data member handles 00106 * @see FinalView for thread-safe "const" data member views 00107 * @see FinalHolder for thread-safe "const" data member holders 00108 * @see WeakHandle for thread-safe weak data member handles 00109 * @see WeakView for thread-safe weak data member views 00110 * @see WeakHolder for thread-safe weak data member holders 00111 * 00112 * @author mf 2007.07.05 00113 */ 00114 class COH_EXPORT Object 00115 : public cloneable_spec<Object, 00116 extends<> > 00117 { 00118 friend class factory<Object>; 00119 00120 // ----- constructors --------------------------------------------------- 00121 00122 protected: 00123 /** 00124 * Construct a new Object. 00125 */ 00126 Object(); 00127 00128 /** 00129 * Copy constructor. 00130 */ 00131 Object(const Object& that); 00132 00133 private: 00134 /** 00135 * Blocked assignment operator. 00136 * 00137 * @internal 00138 */ 00139 Object& operator=(const Object&); 00140 00141 00142 // ----- Object interface ----------------------------------------------- 00143 00144 public: 00145 /** 00146 * Return true iff the specified Object is "equal" to this Object. 00147 * 00148 * This method implements an <i>equivalence relation</i> on Objects: 00149 * <ul> 00150 * <li>It is <i>reflexive</i>: for any non-null handle 00151 * <code>h</code>, <code>h->equals(h)</code> must return 00152 * <code>true</code>. 00153 * <li>It is <i>symmetric</i>: for any non-null handles 00154 * <code>h1</code> and <code>h2</code>, <code>h1->equals(h2)</code> 00155 * should return <code>true</code> if and only if 00156 * <code>h2->equals(h1)</code> returns <code>true</code>. 00157 * <li>It is <i>transitive</i>: for any non-null handles 00158 * <code>h1</code>, <code>h2</code>, and <code>h3</code>, if 00159 * <code>h1->equals(h2)</code> returns <code>true</code> and 00160 * <code>h2->equals(h3)</code> returns <code>true</code>, then 00161 * <code>h1->equals(h3)</code> should return <code>true</code>. 00162 * <li>It is <i>consistent</i>: for any non-null handles 00163 * <code>h1</code> and <code>h2</code>, multiple invocations of 00164 * <tt>h1->equals(h2)</tt> consistently return <code>true</code> 00165 * or consistently return <tt>false</tt>, provided no 00166 * information used in comparisons on the objects is modified. 00167 * <li>If the supplied handle is <tt>NULL</tt> then <tt>false</tt> 00168 * must be returned. 00169 * </ul> 00170 * 00171 * The default implementation is a reference equality comparison. 00172 * 00173 * @param v the Object::View to compare against, may be <tt>NULL</tt> 00174 * 00175 * @return <tt>true</tt> iff the given handle references an Object 00176 * that is "equal" to this Object 00177 * 00178 * @see #equals(Object::View v1, Object::View v2) 00179 */ 00180 virtual bool equals(Object::View v) const; 00181 00182 /** 00183 * Return a hash code value for the Object. This method is supported 00184 * for the benefit of hash-based containers. 00185 * 00186 * The general contract of <code>hashCode</code> is: 00187 * <ul> 00188 * <li>Whenever it is invoked on the same Object more than once 00189 * during an execution of an application, the <tt>hashCode</tt> 00190 * method must consistently return the same value, provided no 00191 * information used in <tt>equals</tt> comparisons on the object 00192 * is modified. This value need not remain consistent from one 00193 * execution of an application to another execution of the same 00194 * application. 00195 * <li>If two Objects are equal according to the <tt>equals</tt> 00196 * method, then calling the <code>hashCode</code> method on each 00197 * of the two Objects must produce the same value. 00198 * <li>It is <em>not</em> required that if two Objects are unequal 00199 * according to the <tt>equals</tt> method, then calling the 00200 * <tt>hashCode</tt> method on each of the two objects must 00201 * produce distinct results. However, the programmer should be 00202 * aware that producing distinct results for unequal objects may 00203 * improve the performance of hash-based containers. 00204 * </ul> 00205 * 00206 * The default implementation is identity based. 00207 * 00208 * @return a hash code value for this Object 00209 */ 00210 virtual size32_t hashCode() const; 00211 00212 /** 00213 * Return a handle to a deep copy of the original Object. 00214 * 00215 * The returned clone should be sufficient decoupled from the original 00216 * such that further modifications to the original Object will not be 00217 * visible within the cloned object. More specifically, the following 00218 * is expected to hold true. 00219 * 00220 * @code 00221 * h->clone() != h && 00222 * h->clone()->equals(h) && 00223 * typeid(*h) == typeid(*(h->clone())) 00224 * @endcode 00225 * 00226 * Note that this suggests that data members of a cloned object are 00227 * expected to cloned if they are tested for equality (via a call to 00228 * equals) within the cloned object's equals method. If a data member 00229 * is compared via reference equality, or not even considered within 00230 * equals, then it does not necessarily need to be deeply cloned. 00231 * 00232 * Object is cloneable, but it's derived classes are not automatically 00233 * cloneable, and CloneNotSupportedExceptions are thrown. To be made 00234 * cloneable the derived class should use the cloneable_spec<> helper 00235 * template in its declaration, and define a protected copy constructor. 00236 * The derived class does not need to override this method, as that is 00237 * done by the cloneable_spec<> template. 00238 * 00239 * @return a copy of the original Object 00240 * 00241 * @throws CloneNotSupportedException if the object cannot be deep 00242 * cloned 00243 * 00244 * @see isImmutable() 00245 */ 00246 virtual Object::Handle clone() const; 00247 00248 /** 00249 * Return <tt>true</tt> iff no further changes can be made to the 00250 * Object, that would effect the outcome of a call to its equals method. 00251 * Except for Objects which are naturally immutable (such as String), 00252 * being immutable generally implies that the Object is only referenced 00253 * via const pointers or views. Objects which hold references to child 00254 * Objects, may need to take the immutability of their children into 00255 * account when determining their own immutability. 00256 * 00257 * This extended check is not performed by the default implementation, 00258 * but can be integrated into the immutability checks by overriding 00259 * this method, as well as making use of MemberHandles to reference 00260 * child Objects. 00261 * 00262 * A typical derived implementation may look as follows: 00263 * 00264 * <pre> 00265 * bool isImmutable() const 00266 * { 00267 * if (m_fImmutable) // check recorded state 00268 * { 00269 * return true; // already marked as immutable, avoid calculation 00270 * } 00271 * else if (Object::isImmutable()) // ensure shallow immutability 00272 * { 00273 * // ensure deep immutability 00274 * if (m_child1->isImmutable() && m_child2->isImmutable() ... 00275 * && m_childN->isImmutable()) 00276 * { 00277 * // record and return immutability 00278 * return m_fImmutable = true; 00279 * } 00280 * // some Objects which comprise this Object are still mutable 00281 * } 00282 * return false; 00283 * } 00284 * </pre> 00285 * 00286 * The default implementation return true iff the Object is only 00287 * referenced via const pointers and or views. 00288 * 00289 * @return true iff the Object is immutable 00290 */ 00291 virtual bool isImmutable() const; 00292 00293 /** 00294 * Deprecated as of 12.2.1 00295 * 00296 * Output a human-readable description of this Object to the given stream. 00297 * 00298 * As of 12.2.1 this method is deprecated in favor of Object::toString() which includes 00299 * support for unicode output and is agnostic to differences between ostream library 00300 * versions. 00301 * 00302 * The default implementation of toStream will simply delegate to toString. 00303 * 00304 * @deprecated 12.2.1 00305 */ 00306 virtual void toStream(std::ostream& /*out*/) const 00307 { 00308 // because of the possibility of standard library changes it is unsafe for this 00309 // method to actually use the stream. All built-in implementations have been 00310 // moved to toString, see operator<< for Object for bridging code which provides 00311 // minimal support for non-built-in classes which may still implement this method. 00312 00313 // Note this method cannot be made safe via in-lining as it must also be virtual 00314 // which will almost always keep the method from being inlined. 00315 } 00316 00317 /** 00318 * Output a human-readable description of this Object to the given 00319 * stream. 00320 * 00321 * Note that when overriding this method the return type must be TypedHandle<const String> 00322 * rather then String::View. These two types are assignment compatible but not equivalent 00323 * and declaring the override with String::View will not be a compatible override. 00324 * 00325 * coherence::lang::operator<<(std::ostream, Object::View) is defined 00326 * and will call into the toString method, to output Objects. If a 00327 * managed String object is desired, the COH_TO_STRING macro can be used 00328 * to build up a String from streamable contents and is generally how 00329 * toString() will be implemented. 00330 * 00331 * @code 00332 * Object::View vKey = ... 00333 * Object::View vValue = ... 00334 * std::cout << vKey << " = " << vValue << std::endl; 00335 * 00336 * String::View vs = COH_TO_STRING(vKey << " = " << vValue); 00337 * @endcode 00338 * 00339 * The COH_TO_STRING macro is also the most common way to implement the toString method. 00340 * For example: 00341 * 00342 * @code 00343 * virtual TypedHandle<const String> Person::toString() const 00344 * { 00345 * return COH_TO_STRING("Name: " << f_sName << " SSN: " << f_nSSN); 00346 * } 00347 * @endcode 00348 * 00349 * @return a string representation of this object 00350 */ 00351 virtual TypedHandle<const String> toString() const; 00352 00353 /** 00354 * Return an estimate as to the byte size of the object. 00355 * 00356 * The shallow size should not include the cost of referenced managed 00357 * objects, or non-fixed dynamically allocated memory. That for a 00358 * given object it is assumed that a call to this method will always 00359 * return the same value when the shallow size is requested. 00360 * 00361 * The deep size should be the shallow size plus the size of any 00362 * referenced objects. Unlike the shallow size the deep size may change 00363 * over time. The default implementation provided by Object will 00364 * traverse the object graph of all managed objects which it references 00365 * and include their sizes in the computed deep size. In general it 00366 * is sufficient to simply delegate to super::sizeOf(true) for deep 00367 * calculations. 00368 * 00369 * For classes implemented via class_spec, a variant of this method 00370 * will be automatically produced which will utilize sizeof(*this) 00371 * to compute the shallow size, and super::sizeOf(true) to compute 00372 * the deep size. As such it is generally not necessary to provide 00373 * custom implmenetations of this method. 00374 * 00375 * @param fDeep true if the size should include the size of referenced 00376 * objects 00377 * 00378 * @return the approximate shallow byte size of the object 00379 */ 00380 virtual size64_t sizeOf(bool fDeep = false) const; 00381 00382 00383 // ----- synchronization and notification interface --------------------- 00384 00385 public: 00386 /** 00387 * Block the calling thread while waiting for notification. 00388 * 00389 * The caller must be synchronized on the Object's monitor when calling 00390 * this method. The monitor will be automatically released while the 00391 * thread awaits notification, and re-acquired before the call returns. 00392 * This method is subject to spurious wakeups, and the caller should 00393 * externally verify that the condition being waited for has been 00394 * reached. 00395 * 00396 * To synchronize on an object, the COH_SYNCHRONIZED macro is used. 00397 * The macro defines a block of code which is a critical section, 00398 * during which no other thread may acquire synchronization on the same 00399 * object. 00400 * 00401 * @code 00402 * Object::Handle hObject = ... 00403 * COH_SYNCHRONIZED (hObject) 00404 * { 00405 * while (testSomeCondition() == false) 00406 * { 00407 * hObject->wait(); 00408 * } 00409 * } 00410 * @endcode 00411 * 00412 * @see notify 00413 * @see notifyAll 00414 */ 00415 void wait() const; 00416 00417 /** 00418 * Block the calling thread while waiting for notification. 00419 * 00420 * The caller must be synchronized on the Object's monitor when calling 00421 * this method. The monitor will be automatically released while the 00422 * thread awaits notification, and re-acquired before the call returns. 00423 * This method is subject to spurious wakeups, and the caller should 00424 * externally verify that the condition being waited for has been 00425 * reached. 00426 * 00427 * @param cMillis the duration to wait to wait, a value of zero will 00428 * wait indefinitely for notification 00429 * 00430 * @see wait 00431 * @see notify 00432 * @see notifyAll 00433 */ 00434 void wait(int64_t cMillis) const; 00435 00436 /** 00437 * Notify a waiting thread. 00438 * 00439 * The caller must be synchronized on the Object's monitor when calling 00440 * this method. 00441 * 00442 * @code 00443 * Object::Handle hObject = ... 00444 * COH_SYNCHRONIZED (hObject) 00445 * { 00446 * setSomeCondition(true); 00447 * hObject->notify(); 00448 * } 00449 * @endcode 00450 * 00451 * @see wait 00452 * @see notifyAll 00453 */ 00454 void notify() const; 00455 00456 /** 00457 * Notify all waiting threads. 00458 * 00459 * The caller must be synchronized on the Object's monitor when calling 00460 * this method. 00461 * 00462 * @see wait 00463 * @see notify 00464 */ 00465 void notifyAll() const; 00466 00467 private: 00468 /** 00469 * Enter the Object's monitor, waiting as long as necessary. 00470 * <p/> 00471 * The monitor supports recursive entry, allowing the same thread to 00472 * reenter the same monitor. The thread must exit the monitor the 00473 * same number of times, by calling the exitMonitor, for the Monitor 00474 * to be released. 00475 * 00476 * It is recommended that the COH_SYNCHRONIZED macro be used in place 00477 * of direct calls to enterMonitor/exitMonitor. The use of this macro 00478 * only requires public level view access to the Object 00479 * <pre> 00480 * // outside of synchronized block 00481 * COH_SYNCHRONIZED (vObject) // monitor entered 00482 * { 00483 * // critical section goes here 00484 * // ... 00485 * // ... 00486 * } // monitor automatically exited 00487 * // outside of synchronized block 00488 * </pre> 00489 * 00490 * @see _exitMonitor 00491 */ 00492 void _enterMonitor() const 00493 { 00494 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00495 if (state.value.fEscaped || 00496 state.value.nMonitor != LifeCycle::flat) 00497 { 00498 _enterMonitorInternal(); 00499 } 00500 else 00501 { 00502 // pointer acts as a nested synchronization counter 00503 m_pCondition = reinterpret_cast<NativeCondition*>( 00504 reinterpret_cast<size_t>(m_pCondition) + 1); 00505 } 00506 } 00507 00508 /** 00509 * @internal 00510 */ 00511 void _enterMonitorInternal() const; 00512 00513 /** 00514 * Exit the Object's monitor. 00515 * 00516 * This must be called by the thread which locked the monitor. 00517 * 00518 * @see _enterMonitor 00519 */ 00520 void _exitMonitor() const 00521 { 00522 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00523 if (state.value.fEscaped || 00524 state.value.nMonitor != LifeCycle::flat) 00525 { 00526 _exitMonitorInternal(); 00527 } 00528 else if (m_pCondition == NULL) 00529 { 00530 coh_throw_illegal_state("Invalid monitor state"); 00531 } 00532 else 00533 { 00534 // pointer acts as a nested synchronization counter 00535 m_pCondition = reinterpret_cast<NativeCondition*>( 00536 reinterpret_cast<size_t>(m_pCondition) - 1); 00537 } 00538 } 00539 00540 /** 00541 * @internal 00542 */ 00543 void _exitMonitorInternal() const; 00544 00545 /** 00546 * Acquire the shared read lock for the Object's data members. 00547 * 00548 * The data member read/write lock is intended for protecting small 00549 * sections of non-blocking code, such as primitive data-member access 00550 * and assignment. The read lock does support limited recursion, 00551 * and each call to acquire must be matched by a corresponding 00552 * call to release. For more advanced read/write lock support the 00553 * ThreadGate class should be utilized. 00554 * 00555 * The member read lock may be acquired using the 00556 * COH_SYNCHRONIZED_MEMBER_READ macro. 00557 * 00558 * @see SynchronizedMemberReadBlock 00559 * @see coherence::util::ThreadGate 00560 */ 00561 void _acquireMemberReadLock() const 00562 { 00563 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00564 if (state.value.fEscaped) 00565 { 00566 _acquireMemberReadLockInternal(); 00567 } 00568 else if (state.value.nMemberWriteLockState == 00569 LifeCycle::gate_open && 00570 state.value.cMemberReadLock < LifeCycle::max_read_locks) 00571 { 00572 ++state.value.cMemberReadLock; 00573 m_atomicLifeCycleState.poke(state); 00574 } 00575 else 00576 { 00577 coh_throw_illegal_state("Invalid lock state"); 00578 } 00579 } 00580 00581 /** 00582 * Release the read lock for the Object's data members 00583 */ 00584 void _releaseMemberReadLock() const 00585 { 00586 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00587 if (state.value.fEscaped) 00588 { 00589 _releaseMemberReadLockInternal(); 00590 } 00591 else if (state.value.nMemberWriteLockState == 00592 LifeCycle::gate_open && 00593 state.value.cMemberReadLock > 0) 00594 { 00595 --state.value.cMemberReadLock; 00596 m_atomicLifeCycleState.poke(state); 00597 } 00598 else 00599 { 00600 coh_throw_illegal_state("Invalid lock state"); 00601 } 00602 } 00603 00604 /** 00605 * Cross the read barrier associated with the object's read write lock. 00606 */ 00607 void _readBarrier() const 00608 { 00609 m_atomicLifeCycleState.get(); 00610 } 00611 00612 /** 00613 * Acquire the write lock for the Object's data members. 00614 * 00615 * Unlike the member read lock, write locks do not support 00616 * recursion, nor do they support lock promotion from a read to a 00617 * write lock. Attempts to use them such a manor will result in 00618 * dead-lock. 00619 * 00620 * The member write lock may be acquired using the 00621 * COH_SYNCHRONIZED_MEMBER_WRITE macro. 00622 * 00623 * @see SynchronizedMemberWriteBlock 00624 */ 00625 void _acquireMemberWriteLock() const 00626 { 00627 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00628 if (state.value.fEscaped) 00629 { 00630 _acquireMemberWriteLockInternal(); 00631 } 00632 else if (state.value.nMemberWriteLockState == 00633 LifeCycle::gate_open && 00634 state.value.cMemberReadLock == 0) 00635 { 00636 state.value.nMemberWriteLockState = LifeCycle::gate_closed; 00637 m_atomicLifeCycleState.poke(state); 00638 } 00639 else 00640 { 00641 coh_throw_illegal_state("Invalid lock state"); 00642 } 00643 } 00644 00645 /** 00646 * Release the write lock for the Object's data members. 00647 */ 00648 void _releaseMemberWriteLock() const 00649 { 00650 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00651 if (state.value.fEscaped) 00652 { 00653 _releaseMemberWriteLockInternal(); 00654 } 00655 else if (state.value.nMemberWriteLockState == 00656 LifeCycle::gate_closed) 00657 { 00658 state.value.nMemberWriteLockState = LifeCycle::gate_open; 00659 m_atomicLifeCycleState.poke(state); 00660 } 00661 else 00662 { 00663 coh_throw_illegal_state("Invalid lock state"); 00664 } 00665 } 00666 00667 /** 00668 * Cross the write barrier associated with the object's read write lock. 00669 */ 00670 void _writeBarrier() const 00671 { 00672 m_atomicLifeCycleState.update(0, 0); 00673 } 00674 00675 // ----- reference counting interface ----------------------------------- 00676 00677 public: 00678 /** 00679 * @internal 00680 * 00681 * Increment the non-const reference count for this Object. 00682 * 00683 * NOTE: This method is intended for use by smart pointers such as 00684 * TypedHandle, and its usage should be limited. 00685 * 00686 * This operation must return <tt>NULL</tt> if the Object is 00687 * immutable. 00688 * 00689 * @param fEscaped true if the attaching reference is visible to 00690 * multiple threads 00691 * 00692 * @return a pointer to the Object or <tt>NULL</tt> if new non-const 00693 * attachments are disallowed 00694 * 00695 * @see _detach 00696 */ 00697 Object* _attach(bool fEscaped = true) 00698 { 00699 if (LifeCycle::State(m_atomicLifeCycleState.peek()).value.fEscaped) 00700 { 00701 return _attachEscaped(fEscaped); 00702 } 00703 00704 LifeCycle::Refs refs(m_atomicLifeCycleRefs.peek()); 00705 unsigned int cHandle = refs.value.cHandle; 00706 if (fEscaped || cHandle == 0 || 00707 cHandle >= LifeCycle::max_handles - LifeCycle::escaped_increment || (cHandle == 1 && 00708 refs.value.nWeakReference == LifeCycle::inflated)) 00709 { 00710 return _attachCaptured(fEscaped); 00711 } 00712 00713 // inlined non-escaped attach 00714 refs.value.cHandle = cHandle + 1; 00715 m_atomicLifeCycleRefs.poke(refs); 00716 return this; 00717 } 00718 00719 /** 00720 * @internal 00721 * 00722 * Increment the const reference count for this Object. 00723 * 00724 * NOTE: This method is intended for use by smart pointers such as 00725 * TypedHandle, and its usage should be limited. 00726 * 00727 * @param fEscaped true if the attaching reference is visible to 00728 * multiple threads 00729 * 00730 * @return a constant pointer to the Object, or <tt>NULL</tt> if new 00731 * const attachments are disallowed 00732 * 00733 * @see _detach 00734 */ 00735 const Object* _attach(bool fEscaped = true) const 00736 { 00737 if (LifeCycle::State(m_atomicLifeCycleState.peek()).value.fEscaped) 00738 { 00739 return _attachEscaped(fEscaped); 00740 } 00741 00742 LifeCycle::Refs refs(m_atomicLifeCycleRefs.peek()); 00743 unsigned int cView = refs.value.cView; 00744 unsigned int cTotal = refs.value.cHandle + cView; 00745 if (fEscaped || cView >= LifeCycle::max_views - LifeCycle::escaped_increment || cTotal == 0 || 00746 (cTotal == 1 && refs.value.nWeakReference == LifeCycle::inflated)) 00747 { 00748 return _attachCaptured(fEscaped); 00749 } 00750 00751 // inlined non-escaped attach 00752 refs.value.cView = cView + 1; 00753 m_atomicLifeCycleRefs.poke(refs); 00754 return this; 00755 } 00756 00757 /** 00758 * @internal 00759 * 00760 * Return a WeakReference to this Object. 00761 * 00762 * Unlike non-weak attachments, there is no corresponding _detachWeak, 00763 * as the return type is a handle. 00764 * 00765 * See the WeakHandle template class which will automatically manage 00766 * the weak attachment to the Object. 00767 * 00768 * NOTE: This method is intended for use by smart pointers such as 00769 * WeakHandle, and its usage should be limited. 00770 * 00771 * @see WeakReference 00772 * @see WeakHandle 00773 * 00774 * @return a WeakReference to this Object 00775 */ 00776 TypedHandle<WeakReference> _attachWeak(); 00777 00778 /** 00779 * @internal 00780 * 00781 * Return a WeakReference View to this Object. 00782 * 00783 * Unlike non-weak attachments, there is no corresponding _detachWeak, 00784 * as the return type is a handle. 00785 * 00786 * See the WeakView template class which will automatically manage the 00787 * weak attachment to the Object. 00788 * 00789 * NOTE: This method is intended for use by smart pointers such as 00790 * WeakHandle, and its usage should be limited. 00791 * 00792 * @see WeakReference 00793 * @see WeakView 00794 * 00795 * @return a WeakReference to this Object 00796 */ 00797 TypedHandle<const WeakReference> _attachWeak() const; 00798 00799 /** 00800 * @internal 00801 * 00802 * Decrement the non-const reference count for this Object and 00803 * automatically delete this Object if the total reference count drops 00804 * to zero. 00805 * 00806 * NOTE: This method is intended for use by smart pointers such as 00807 * TypedHandle, and its usage should be limited. 00808 * 00809 * @see _attach 00810 * 00811 * @param fEscaped true if the detaching reference had attached as 00812 * escaped 00813 */ 00814 void _detach(bool fEscaped = true) 00815 { 00816 if (fEscaped || LifeCycle::State(m_atomicLifeCycleState.peek()).value.fEscaped) 00817 { 00818 _detachEscaped(fEscaped); 00819 return; 00820 } 00821 00822 LifeCycle::Refs refs(m_atomicLifeCycleRefs.peek()); 00823 unsigned int cHandle = refs.value.cHandle; 00824 if (cHandle <= 1 || (cHandle == 2 && 00825 refs.value.nWeakReference == LifeCycle::inflated) || 00826 cHandle == LifeCycle::max_handles) 00827 { 00828 _detachCaptured(); 00829 } 00830 else 00831 { 00832 // inlined non-escaped detach 00833 refs.value.cHandle = cHandle - 1; 00834 m_atomicLifeCycleRefs.poke(refs); 00835 } 00836 } 00837 00838 /** 00839 * @internal 00840 * 00841 * Decrement the const reference count for this Object and 00842 * automatically delete this Object if the total reference count drops 00843 * to zero. 00844 * 00845 * NOTE: This method is intended for use by smart pointers such as 00846 * TypedHandle, and its usage should be limited. 00847 * 00848 * @see _attach 00849 * 00850 * @param fEscaped true if the detaching reference had attached as 00851 * escaped 00852 */ 00853 void _detach(bool fEscaped) const 00854 { 00855 if (fEscaped || LifeCycle::State(m_atomicLifeCycleState.peek()).value.fEscaped) 00856 { 00857 _detachEscaped(fEscaped); 00858 return; 00859 } 00860 00861 LifeCycle::Refs refs(m_atomicLifeCycleRefs.peek()); 00862 unsigned int cView = refs.value.cView; 00863 if (cView == 0 || cView == LifeCycle::max_views || 00864 (refs.value.cHandle == 0 && (cView == 1 || (cView == 2 && 00865 refs.value.nWeakReference == LifeCycle::inflated)))) 00866 { 00867 _detachCaptured(); 00868 } 00869 else 00870 { 00871 // inline non-escaped detach 00872 refs.value.cView = cView - 1; 00873 m_atomicLifeCycleRefs.poke(refs); 00874 } 00875 } 00876 00877 /** 00878 * Return if the Object is currently marked as escaped. 00879 * 00880 * An escaped object is one which is known to be reachable by multiple 00881 * threads. 00882 * 00883 * @param fAttemptCapture true if capture should be attempted 00884 * 00885 * @return true if the Object is currently marked as escaped 00886 */ 00887 bool _isEscaped(bool fAttemptCapture = true) const 00888 { 00889 LifeCycle::State state(m_atomicLifeCycleState.peek()); 00890 00891 if (fAttemptCapture && state.value.fEscaped) 00892 { 00893 LifeCycle::Refs refs(m_atomicLifeCycleRefs.get()); // must do a volatile read 00894 if (refs.value.cHandle + refs.value.cView == 1) 00895 { 00896 // there is only one ref to this object, and this thread has a ref 00897 // therefore it is safe to capture the object 00898 _capture(); 00899 return false; 00900 } 00901 } 00902 00903 return state.value.fEscaped; 00904 } 00905 00906 00907 // ----- life cycle events ---------------------------------------------- 00908 00909 protected: 00910 /** 00911 * Event called once the Object has finished being constructed. 00912 * Specifically when the first attachment is made. This provides a 00913 * safe point at which Handles/Views to "this" can be created. It is 00914 * not safe to create Handles/Views to an Object from within its 00915 * constructor, thus any operations which rely upon this should be 00916 * deferred until the onInit event is triggered. 00917 * 00918 * As with all event methods any derived implementation should 00919 * include a call to the super class's implementation. Specifically 00920 * delegation to Object::onInit() must eventually occur or an 00921 * IllegalStateException will result. 00922 * 00923 * The default implementation calls the onInit() method of each of the 00924 * Object's SmartMembers. 00925 */ 00926 virtual void onInit(); 00927 00928 /** 00929 * Event called when the Object becomes only referenced via const 00930 * pointers (Views). Assuming a const-correct class, once this method 00931 * returns no further visible changes can be made to the object. 00932 * 00933 * As with all event methods any derived implementation should include 00934 * a call to the super class's implementation. 00935 * 00936 * The default implementation calls the onConst() method of each of 00937 * the Object's SmartMembers. 00938 * 00939 * @see isImmutable 00940 */ 00941 virtual void onConst(); 00942 00943 /** 00944 * Event called when the guarding Object's escape state changes. 00945 * 00946 * As with all event methods any derived implementation should include 00947 * a call to the super class's implementation. Ultimately delegation 00948 * must reach Object::onEscape() which will perform the actual act of 00949 * preparing the object for multi/single-threaded access. 00950 * 00951 * Throughout the call it is guaranteed that the object remains visible 00952 * to only a single thread, and as such it is not allowable to perform 00953 * an action from within this method which would attempt to escape this 00954 * object. 00955 * 00956 * @param fEscaped true if the object is escaping, false if it is 00957 * being captured 00958 */ 00959 virtual void onEscape(bool fEscaped) const; 00960 00961 00962 // ----- helper methods ------------------------------------------------- 00963 00964 protected: 00965 /** 00966 * Return a reference to the constructed base Object. 00967 * 00968 * This reference is suitable for use in derived class constructors as 00969 * the Object class will have completed construction. 00970 * 00971 * @return the Object reference 00972 */ 00973 Object& self() 00974 { 00975 return *this; 00976 } 00977 00978 /** 00979 * Return a reference to the constructed base Object. 00980 * 00981 * @return the const Object reference 00982 */ 00983 const Object& self() const 00984 { 00985 return *this; 00986 } 00987 00988 private: 00989 /** 00990 * Destroy the object. 00991 */ 00992 void _destroy() const; 00993 00994 /** 00995 * Escape an Object 00996 */ 00997 void _escape() const; 00998 00999 /** 01000 * Capture an escaped object. 01001 * 01002 * Note it is up to the caller to ensure that it is safe to perform the capture. Specifically 01003 * the caller must have ensured that the object is currently marked as escaped, but that the 01004 * cumulative reference count is now only one, i.e. the only reference is held by the calling 01005 * thread. 01006 */ 01007 void _capture() const; 01008 01009 /** 01010 * Increment the Object's view reference count on a non-escaped object. 01011 * 01012 * @param fEscaped true if the view will be escaped 01013 * 01014 * @return NULL on failed attach otherwise return this 01015 */ 01016 const Object* _attachCaptured(bool fEscaped) const; 01017 01018 /** 01019 * Increment the Object's handle reference count on an non-escaped object. 01020 * 01021 * @param fEscaped true if the handle will be escaped 01022 * 01023 * @return NULL on failed attach otherwise return this 01024 */ 01025 Object* _attachCaptured(bool fEscaped); 01026 01027 /** 01028 * Increment the Object's view reference count on an escaped object. 01029 * 01030 * @param fEscaped true if the view will be escaped 01031 * 01032 * @return NULL on failed attach otherwise return this 01033 */ 01034 const Object* _attachEscaped(bool fEscaped) const; 01035 01036 /** 01037 * Increment the Object's handle reference count on an escaped object. 01038 * 01039 * @param fEscaped true if the view will be escaped 01040 * 01041 * @return NULL on failed attach otherwise return this 01042 */ 01043 Object* _attachEscaped(bool fEscaped); 01044 01045 /** 01046 * Decrement the Object's view reference count on a non-escaped object. 01047 */ 01048 void _detachCaptured() const; 01049 01050 /** 01051 * Decrement the Object's handle reference count on an non-escaped object. 01052 */ 01053 void _detachCaptured(); 01054 01055 /** 01056 * Decrement the Object's view reference count on an escaped object. 01057 * 01058 * @param fEscaped true if the view is escaped 01059 */ 01060 void _detachEscaped(bool fEscaped) const; 01061 01062 /** 01063 * Decrement the Object's handle reference count on an escaped object. 01064 * 01065 * @param fEscaped true if the view is escaped 01066 */ 01067 void _detachEscaped(bool fEscaped); 01068 01069 /** 01070 * Acquire the shared read lock for the Object's data members. 01071 * 01072 * The data member read/write lock is intended for protecting small 01073 * sections of non-blocking code, such as primitive data-member access 01074 * and assignment. The read lock does support limited recursion, 01075 * and each call to acquire must be matched by a corresponding 01076 * call to release. For more advanced read/write lock support the 01077 * ThreadGate class should be utilized. 01078 * 01079 * The member read lock may be acquired using the 01080 * COH_SYNCHRONIZED_MEMBER_READ macro. 01081 * 01082 * @see SynchronizedMemberReadBlock 01083 * @see coherence::util::ThreadGate 01084 */ 01085 void _acquireMemberReadLockInternal() const; 01086 01087 /** 01088 * Release the read lock for the Object's data members 01089 */ 01090 void _releaseMemberReadLockInternal() const; 01091 01092 /** 01093 * Acquire the write lock for the Object's data members. 01094 * 01095 * Unlike the member read lock, write locks do not support 01096 * recursion, nor do they support lock promotion from a read to a 01097 * write lock. Attempts to use them such a manor will result in 01098 * dead-lock. 01099 * 01100 * The member write lock may be acquired using the 01101 * COH_SYNCHRONIZED_MEMBER_WRITE macro. 01102 * 01103 * @see SynchronizedMemberWriteBlockm 01104 */ 01105 void _acquireMemberWriteLockInternal() const; 01106 01107 /** 01108 * Release the write lock for the Object's data members. 01109 */ 01110 void _releaseMemberWriteLockInternal() const; 01111 01112 /** 01113 * Return the WeakReference associated with this Object, creating one 01114 * if necessary. 01115 * 01116 * @return the WeakReference associated with this Object 01117 */ 01118 TypedHandle<WeakReference> _ensureWeakReference() const; 01119 01120 /** 01121 * Return the NativeCondition which backs the Object's monitor, 01122 * creating one if necessary. 01123 * 01124 * The life of the returned condition is bounded to the Object. 01125 * 01126 * @return the NativeCondition which backs the Object's monitor 01127 */ 01128 NativeCondition& _ensureMonitor() const; 01129 01130 01131 // ----- static methods ------------------------------------------------- 01132 01133 public: 01134 /** 01135 * Compare two Objects for equality. 01136 * 01137 * This method implements an <i>equivalence relation</i> for two 01138 * potentially <tt>NULL</tt> handles. 01139 * 01140 * @param v1 the first Object to compare 01141 * @param v2 the second Object to compare 01142 * 01143 * @return <tt>true</tt> iff v1 and v2 are <tt>NULL</tt> or 01144 * reference Objects which are equal 01145 */ 01146 static bool equals(Object::View v1, Object::View v2); 01147 01148 /** 01149 * Return the string form of the supplied Object 01150 * 01151 * If the handle is NULL then the string "NULL" will be written to the 01152 * stream. 01153 * 01154 * @param v the Object to output 01155 * 01156 * @return the object's toString 01157 */ 01158 static TypedHandle<const String> toString(Object::View v); 01159 01160 /** 01161 * Return a clone of the supplied Object. 01162 * 01163 * @param v the Object to clone 01164 * 01165 * @return a clone of the Object, or NULL if NULL was supplied 01166 */ 01167 static Object::Handle clone(Object::View v); 01168 01169 /** 01170 * Return the hashCode for the specified object or 0 if the object is 01171 * NULL. 01172 * 01173 * @param v the Object to hash 01174 * 01175 * @return the object's hash. 01176 */ 01177 static size32_t hashCode(Object::View v) 01178 { 01179 return NULL == get_pointer(v) ? 0 : v->hashCode(); 01180 } 01181 01182 01183 // ----- memory management ---------------------------------------------- 01184 01185 protected: 01186 /** 01187 * @internal 01188 * 01189 * Default allocator for Objects. 01190 * 01191 * @param cb the number of bytes to allocate 01192 * 01193 * @return the allocated memory 01194 * 01195 * @throws IllegalStateException if the allocation fails 01196 */ 01197 static void* operator new(size_t cb); 01198 01199 /** 01200 * @internal 01201 * 01202 * Default deallocator for Objects. 01203 * 01204 * @param po the memory to deallocate 01205 */ 01206 static void operator delete(void* po); 01207 01208 01209 // ----- data members --------------------------------------------------- 01210 01211 private: 01212 /** 01213 * 32bit atomic Object life-cycle state. 01214 */ 01215 mutable NativeAtomic32 m_atomicLifeCycleState; 01216 01217 /** 01218 * 32bit atomic Object life-cycle refs. 01219 */ 01220 mutable NativeAtomic32 m_atomicLifeCycleRefs; 01221 01222 /** 01223 * Pointer to the NativeCondition which is used to implement the 01224 * Object's monitor functionality. 01225 * 01226 * The validity of this pointer is governed by the Object's 01227 * life-cycle. A non-NULL pointer is not sufficient to ensure that 01228 * the condition is ready for use. 01229 */ 01230 mutable NativeCondition* m_pCondition; 01231 01232 /** 01233 * The WeakReference to this Object. 01234 * 01235 * The validity of this handle is governed by the Object's life-cycle. 01236 * A non-NULL handle is not sufficient to ensure that the reference is 01237 * ready for use. 01238 */ 01239 mutable WeakReference* m_pWeakThis; 01240 01241 /** 01242 * Pointer to the top of the stack of SmartMembers bound to this 01243 * Object, or NULL if none exist. 01244 */ 01245 mutable SmartMember* m_pSmartMemberStack; 01246 01247 01248 // ----- friends -------------------------------------------------------- 01249 01250 template<class> friend class Volatile; 01251 friend class SmartMember; 01252 friend class SynchronizedBlock; 01253 friend class SynchronizedMemberReadBlock; 01254 friend class SynchronizedMemberWriteBlock; 01255 friend class System; 01256 }; 01257 01258 01259 // ----- non-member operators and functions --------------------------------- 01260 01261 // Note: operator<< functions for Object are located in String.hpp as they need 01262 // full String definition for their implementation. They also need to be fully 01263 // inlineable and thus can't be split into the .cpp file either. 01264 01265 /** 01266 * Object reference equality operator. 01267 */ 01268 template<class T> 01269 inline bool operator==(const Object* cpo, const TypedHandle<T> &v) 01270 { 01271 return ((const Object*) get_pointer(v)) == cpo; 01272 } 01273 01274 /** 01275 * Object reference equality operator. 01276 */ 01277 template<class T> 01278 inline bool operator==(const TypedHandle<T> &v, const Object* cpo) 01279 { 01280 return ((const Object*) get_pointer(v)) == cpo; 01281 } 01282 01283 /** 01284 * Object reference equality operator. 01285 */ 01286 template<class T1, class T2> 01287 inline bool operator==(const TypedHandle<T1>& v1, const TypedHandle<T2>& v2) 01288 { 01289 return ((const Object*) get_pointer(v1)) == 01290 ((const Object*) get_pointer(v2)); 01291 } 01292 01293 /** 01294 * Object reference inequality operator. 01295 */ 01296 template<class T> 01297 inline bool operator!=(const Object* cpo, const TypedHandle<T>& v) 01298 { 01299 return ((const Object*) get_pointer(v)) != cpo; 01300 } 01301 01302 /** 01303 * Object reference inequality operator. 01304 */ 01305 template<class T> 01306 inline bool operator!=(const TypedHandle<T>& v, const Object* cpo) 01307 { 01308 return ((const Object*) get_pointer(v)) != cpo; 01309 } 01310 01311 /** 01312 * Object reference inequality operator. 01313 */ 01314 template<class T1, class T2> 01315 inline bool operator!=(const TypedHandle<T1>& v1, const TypedHandle<T2>& v2) 01316 { 01317 return ((const Object*) get_pointer(v1)) != 01318 ((const Object*) get_pointer(v2)); 01319 } 01320 01321 /** 01322 * Object reference equality operator. 01323 */ 01324 inline bool operator==(const Object::View& v1, const Object::View& v2) 01325 { 01326 return ((const Object*) get_pointer(v1)) == 01327 ((const Object*) get_pointer(v2)); 01328 } 01329 01330 /** 01331 * Object reference inequality operator. 01332 */ 01333 inline bool operator!=(const Object::View& v1, const Object::View& v2) 01334 { 01335 return ((const Object*) get_pointer(v1)) != 01336 ((const Object*) get_pointer(v2)); 01337 } 01338 01339 /** 01340 * @internal 01341 * 01342 * Specialized extends implementation for classes deriving directly from Object. 01343 * 01344 * This specialization bring Object in virtually (as interfaces derive from it 01345 * virtually as well. 01346 */ 01347 template<class A> class COH_EXPORT_SPEC extends<Object, A> 01348 : public virtual Object 01349 { 01350 public: 01351 typedef Void<Object> inherited; 01352 typedef A alias; 01353 typedef Object inherited_literal; 01354 }; 01355 01356 /** 01357 * @internal 01358 * 01359 * Specialized extends implementation for classes deriving directly from Object. 01360 * 01361 * This specialization bring Object in virtually (as interfaces derive from it 01362 * virtually as well. 01363 */ 01364 template<> class COH_EXPORT_SPEC extends<Object, Void<Object> > 01365 : public virtual Object 01366 { 01367 public: 01368 typedef Void<Object> inherited; 01369 typedef Void<Object> alias; 01370 typedef Object inherited_literal; 01371 }; 01372 01373 COH_CLOSE_NAMESPACE2 01374 01375 #endif // COH_OBJECT_HPP