Oracle Coherence for C++ API
Release 3.6.0.0
E15728-01

- Main Page
- Namespaces
- Classes
- Files

# coherence/lang/SynchronizedMemberWriteBlock.hpp

    00001 /*
    00002 * SynchronizedMemberWriteBlock.hpp
    00003 *
    00004 * Copyright (c) 2000, 2010, 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_SYNCHRONIZED_MEMBER_WRITE_BLOCK_HPP
    00017 #define COH_SYNCHRONIZED_MEMBER_WRITE_BLOCK_HPP
    00018
    00019 #include "coherence/lang/compatibility.hpp"
    00020
    00021 #include "coherence/lang/SynchronizedMemberReadBlock.hpp"
    00022
    00023 COH_OPEN_NAMESPACE2(coherence,lang)
    00024
    00025
    00026 /**
    00027 * The SynchronizedMemberBlock class allows for easy creation of synchronized
    00028 * code blocks based on an Object's member level read/write lock. The
    00029 * SynchronizedMemberBlock object will ensure that the locks are acquired and
    00030 * released as part of starting and ending the code block.
    00031 *
    00032 * Member read/write locks are not a general purpose feature, and should not
    00033 * be used to protect blocking calls. They are intended to protect reads and
    00034 * writes to data member primitives, and other short non-blocking code
    00035 * blocks.
    00036 *
    00037 * Example usage:
    00038 *
    00039 * // outside of sync block
    00040 *     {
    00041 *     SynchronizedMemberWriteBlock syncWrite(self()); // write lock
    00042 *     acquired // critical section goes here
    00043 *     // ...
    00044 *     } // write lock released
    00045 * // outside of sync block
    00046 *
    00047 * A more friendly form is to use the COH_SYNCHRONIZED_MEMBER_WRITE
    00048 * macros. Example usage:
    00049 *
    00050 * // outside of sync block
    00051 * COH_SYNCHRONIZED_MEMBER_WRITE // write lock acquired
    00052 *   {
    00053 *   // critical section goes here
    00054 *   // ...
    00055 *   // ...
    00056 *   } // write lock released
    00057 * // outside of sync block
    00058 *
    00059 * The SynchronizedMemberWriteBlock class relies on its creator to ensure that
    00060 * the associated Object outlives the scope of the block. The helper macro
    00061 * ensures this by only allowing you to create a block for the encompassing
    00062 * Object, i.e. "this". If the blocks are manually created then the caller
    00063 * must ensure that the associated Object outlives the block.
    00064 *
    00065 * Note: This class indirectly derives from FinalizableBlock, allowing custom
    00066 * finalizers to be registered. The finalizers will execute after the lock has
    00067 * been released.
    00068
    00069 * @author mf 2008.01.29
    00070 */
    00071 class COH_EXPORT SynchronizedMemberWriteBlock
    00072         : public SynchronizedMemberReadBlock
    00073     {
    00074     // ----- constructors ---------------------------------------------------
    00075
    00076     public:
    00077         /**
    00078         * Construct a synchronized SynchronizedMemberWriteBlock, acquiring the
    00079         * Object's member write lock.
    00080         *
    00081         * @param o          the Object to lock
    00082         * @param pDelegate  SynchronizedMemberWriteBlock to delegate to, or
    00083         *                   NULL for no delegate
    00084         *
    00085         * @throws IllegalArgumentException if pSyncDelegate is non-NULL and
    00086         *         references a different Object.
    00087         */
    00088         SynchronizedMemberWriteBlock(const Object& o,
    00089                 SynchronizedMemberWriteBlock* pDelegate = NULL)
    00090             : SynchronizedMemberReadBlock()
    00091             {
    00092             initialize(o, pDelegate);
    00093             if (isTerminal())
    00094                 {
    00095                 o._acquireMemberWriteLock();
    00096                 }
    00097             m_cpObject = &o;
    00098             }
    00099
    00100         /**
    00101         * Destroy a SynchronizedMemberWriteBlock.
    00102         *
    00103         * This is a no-op for a delegating block, otherwise the write lock is
    00104         * released.
    00105         */
    00106         ~SynchronizedMemberWriteBlock()
    00107             {
    00108             const Object* cpObject = m_cpObject;
    00109             if (NULL != cpObject && isTerminal())
    00110                 {
    00111                 m_cpObject = NULL; // record that the lock has been released
    00112                 try
    00113                     {
    00114                     cpObject->_releaseMemberWriteLock();
    00115                     }
    00116                 catch (const std::exception& e)
    00117                     {
    00118                     std::cerr << "Error releasing MemberWriteLock: " <<
    00119                         e.what() << std::endl;
    00120                     }
    00121                 }
    00122             }
    00123
    00124
    00125     // ----- SynchronizedMemberWriteBlock interface -------------------------
    00126
    00127     public:
    00128         /**
    00129         * Set the specified member to the specified value, without
    00130         * obtaining additional synchronization.
    00131         *
    00132         * This helper function is only supported on "members" which
    00133         * supply a custom two-parameter "set" method utilizing the
    00134         * SynchronizedMemberWriteBlock facility.
    00135         *
    00136         * @param member  the member to set
    00137         * @param value   the value to set the member to
    00138         */
    00139         template<class M, class V> void setMember(M& member, V value)
    00140             {
    00141             member.set(value, this);
    00142             }
    00143
    00144         /**
    00145         * Set the specified member to the specified value so long as
    00146         * the current value is equal to the assumed value.
    00147         *
    00148         * This helper function is only supported on "members" which
    00149         * supply a custom parameterized "set" and "get" methods utilizing the
    00150         * SynchronizedMemberWriteBlock facility.
    00151         *
    00152         * @param member        the member to set
    00153         * @param valueAssumed  the assumed current value of the member
    00154         * @param valueNew      the value to set the member to
    00155         *
    00156         * @return the actual value prior to the update attempt
    00157         */
    00158         template<class M, class V> typename M::GetType updateMember(
    00159                     M& member, V valueAssumed, V valueNew)
    00160             {
    00161             V valueActual = member.get(this);
    00162             if (valueAssumed == valueActual)
    00163                 {
    00164                 member.set(valueNew, this);
    00165                 }
    00166             return valueActual;
    00167             }
    00168
    00169         /**
    00170         * Set the specified member to the specified value and return the
    00171         * previous value.
    00172         *
    00173         * This helper function is only supported on "members" which
    00174         * supply a custom parameterized "set" and "get" methods utilizing the
    00175         * SynchronizedMemberWriteBlock facility.
    00176         *
    00177         * @param member        the member to set
    00178         * @param valueNew      the value to set the member to
    00179         *
    00180         * @return the prior value
    00181         */
    00182         template<class M, class V> typename M::GetType exchangeMember(
    00183                     M& member, V valueNew)
    00184             {
    00185             V valuePre = member.get(this);
    00186             member.set(valueNew, this);
    00187             return valuePre;
    00188             }
    00189
    00190
    00191     // ----- nested class: Guard --------------------------------------------
    00192
    00193     public:
    00194         /**
    00195         * Simple write lock structure for use in inlining.
    00196         */
    00197         class COH_EXPORT Guard
    00198             {
    00199             public:
    00200                 Guard(const Object& o)
    00201                     : m_o(o)
    00202                     {
    00203                     acquireMemberWriteLock(o);
    00204                     }
    00205
    00206                 ~Guard()
    00207                     {
    00208                     releaseMemberWriteLock(m_o);
    00209                     }
    00210
    00211             private:
    00212                 const Object& m_o;
    00213             };
    00214
    00215
    00216     // ----- helper methods -------------------------------------------------
    00217
    00218     protected:
    00219         /*
    00220         * Acquire an Object's write lock
    00221         */
    00222         static void acquireMemberWriteLock(const Object& o)
    00223             {
    00224             o._acquireMemberWriteLock();
    00225             }
    00226
    00227         /*
    00228         * Release an Object's write lock
    00229         */
    00230         static void releaseMemberWriteLock(const Object& o)
    00231             {
    00232             o._releaseMemberWriteLock();
    00233             }
    00234     };
    00235
    00236 COH_CLOSE_NAMESPACE2
    00237
    00238
    00239 /**
    00240 * Macro for making more readable synchronized member write code blocks See the
    00241 * documentation of SynchronizedMemberWriteBlock for a usage example.
    00242 *
    00243 * @see coherence::lang::SynchronizedMemberWriteBlock
    00244 */
    00245 #define COH_SYNCHRONIZED_MEMBER_WRITE \
    00246     if (coherence::lang::SynchronizedMemberWriteBlock coh_synchronized_member_write \
    00247         = coherence::lang::SynchronizedMemberWriteBlock(Object::self())) \
    00248         { \
    00249         COH_THROW(coherence::lang::IllegalStateException::create()); \
    00250         } \
    00251     else
    00252
    00253 #endif // COH_SYNCHRONIZED_MEMBER_WRITE_BLOCK_HPP

Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.