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

E77779-01

coherence/lang/TimeoutBlock.hpp

00001 /*
00002 * TimeoutBlock.hpp
00003 *
00004 * Copyright (c) 2000, 2016, 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_TIMEOUT_BLOCK_HPP
00017 #define COH_TIMEOUT_BLOCK_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Thread.hpp"
00022 
00023 COH_OPEN_NAMESPACE2(coherence, lang)
00024 
00025 /**
00026  * TimeoutBlock provides a mechanism for allowing a thread to interrupt itself if it doesn't return
00027  * to a specific call site within a given timeout.  TimeoutBlock instances are intended to be
00028  * used only with the COH_TIMEOUT_AFTER helper macro.  Once constructed a TimeoutBlock attempts to ensure that
00029  * the corresponding block completes within the specified timeout and if it does not the thread will
00030  * self-interrupt.  Exiting the timeout block will automatically clear any interrupt present on the thread
00031  * and in such a case an InterruptedException will be thrown.
00032  *
00033  * <pre>
00034  * try
00035  *     {
00036  *     COH_TIMEOUT_AFTER(5000)
00037  *         {
00038  *         doSomething();
00039  *         }
00040  *     } // this thread will self-interrupt if it doesn't reach this line within 5 seconds
00041  * catch (InterruptedException::View vEx)
00042  *     {
00043  *     // thread timed out or was otherwise interrupted
00044  *     }
00045  * </pre>
00046  *
00047  * Note that when catching the InterruptedException the preferred form is to surround the COH_TIMEOUT block with a try/catch
00048  * rather then embed the try/catch within the block.  This allows handling of cases where the thread gets interrupted but
00049  * the doSomething() method does not choose to throw the InterruptedException, in which case the TimeoutBlock destructor will
00050  * throw it, but this happens as the block terminates and thus would not be catchable within the block.
00051  *
00052  * Note that TimeoutBlock can only self-interrupt at interruptible points, and does not defend against
00053  * CPU bound loops for example.
00054  *
00055  * @author  mf 2015.03.03
00056  */
00057 class COH_EXPORT TimeoutBlock
00058     {
00059     // ----- constructors ---------------------------------------------------
00060 
00061     public:
00062         /**
00063          * Specify a new timeout.
00064          *
00065          * This constructor variant allows the caller to override a parent timeout.  This is
00066          * rarely needed, and is roughly the equivalent of silently consuming a thread interrupt
00067          * without rethrowing the InterruptedException.
00068          *
00069          * @param cMillis         the new timeout.
00070          * @param fForceOverride  true if this timeout is allowed to extend a parent timeout.
00071          */
00072         TimeoutBlock(int64_t cMillis, bool fForceOverride = false);
00073 
00074         /**
00075         * Copy constructor for COH_TIMEOUT macros.
00076         */
00077         TimeoutBlock(const TimeoutBlock& that);
00078 
00079         /**
00080         * Destroy a TimeoutBlock object.
00081         *
00082         * This will automatically reset the timeout to any former value.
00083         */
00084         ~TimeoutBlock();
00085 
00086 
00087     // ----- operators ------------------------------------------------------
00088 
00089     public:
00090         /*
00091         * Boolean conversion for use in COH_TIMEOUT macros.
00092         *
00093         * @return false always
00094         */
00095         operator bool() const
00096             {
00097             return false;
00098             }
00099 
00100     private:
00101         /**
00102         * Blocked assignment operator.
00103         */
00104         const TimeoutBlock& operator=(const TimeoutBlock&);
00105 
00106         /**
00107         * Blocked dynamic allocation.
00108         */
00109         static void* operator new(size_t);
00110 
00111 
00112     // ----- data members ---------------------------------------------------
00113 
00114     protected:
00115         /**
00116          * This TimeoutBlock's timeout.
00117          */
00118         int64_t m_cMillisTimeout;
00119 
00120         /**
00121          * The original timeout before this instance changed it.
00122          */
00123         int64_t m_lTimeoutOrig;
00124 
00125         /**
00126          * The current thread, or NULL if this block is inactive.
00127          */
00128         mutable Thread::Handle m_hThread;
00129     };
00130 
00131 COH_CLOSE_NAMESPACE2
00132 
00133 /**
00134 * Macro for making more readable timeout code blocks See the
00135 * documentation of TimeoutBlock for a usage example.
00136 *
00137 * @see coherence::lang::TimeoutBlock
00138 */
00139 #define COH_TIMEOUT_AFTER(CMILLIS) \
00140     if (coherence::lang::TimeoutBlock COH_UNIQUE_IDENTIFIER(_coh_timeout_) \
00141         = coherence::lang::TimeoutBlock(CMILLIS)) \
00142         { \
00143         COH_THROW(coherence::lang::IllegalStateException::create()); \
00144         } \
00145     else
00146 
00147 /**
00148 * Macro for making more readable timeout code blocks which is allowed to
00149 * extend an already active timeout.
00150 *
00151 * This variant allows the caller to extend a parent timeout.  This is rarely
00152 * needed, and is roughly the equivalent of silently consuming a thread interrupt
00153 * without rethrowing the InterruptedException.  Use of this method should
00154 * be extremely limited.
00155 *
00156 * @see coherence::lang::TimeoutBlock
00157 */
00158 #define COH_TIMEOUT_OVERRIDE(CMILLIS) \
00159     if (coherence::lang::TimeoutBlock COH_UNIQUE_IDENTIFIER(_coh_timeout_) \
00160         = coherence::lang::TimeoutBlock(CMILLIS, /*fForceOverride*/ true)) \
00161         { \
00162         COH_THROW(coherence::lang::IllegalStateException::create()); \
00163         } \
00164     else
00165 
00166 #endif // COH_TIMEOUT_BLOCK_HPP
Copyright © 2000, 2016, Oracle and/or its affiliates. All rights reserved.