Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.2.1.4.0)

E90870-01

coherence/lang/Object.hpp

00001 /*
00002 * Object.hpp
00003 *
00004 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_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
Copyright © 2000, 2019, Oracle and/or its affiliates. All rights reserved.