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