coherence/lang/Object.hpp

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