You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2008/11/07 23:41:03 UTC

svn commit: r712296 - in /activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent: Delayed.h locks/ locks/Condition.h locks/Lock.h locks/ReadWriteLock.h

Author: tabish
Date: Fri Nov  7 14:41:02 2008
New Revision: 712296

URL: http://svn.apache.org/viewvc?rev=712296&view=rev
Log:
Add some additional interfaces to Decaf

Added:
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Delayed.h
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Condition.h
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Lock.h
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/ReadWriteLock.h

Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Delayed.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Delayed.h?rev=712296&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Delayed.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Delayed.h Fri Nov  7 14:41:02 2008
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_UTIL_CONCURRENT_DELAYED_H_
+#define _DECAF_UTIL_CONCURRENT_DELAYED_H_
+
+#include <decaf/util/Config.h>
+
+#include <decaf/lang/Comparable.h>
+#include <decaf/util/concurrent/TimeUnit.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+
+    /**
+     * A mix-in style interface for marking objects that should be acted upon after a
+     * given delay.
+     * <p>
+     * An implementation of this interface must define a Comparable methods that provides an
+     * ordering consistent with its getDelay method.
+     */
+    class DECAF_API Delayed : public decaf::lang::Comparable<Delayed> {
+    public:
+
+        virtual ~Delayed() {}
+
+        /**
+         * Returns the remaining delay associated with this object, in the given time unit.
+         *
+         * @param unit
+         *        The time unit
+         *
+         * @returns the remaining delay; zero or negative values indicate that the delay
+         *          has already elapsed
+         */
+        virtual long long getDelay( const TimeUnit& unit ) = 0;
+
+    };
+
+}}}
+
+#endif /* _DECAF_UTIL_CONCURRENT_DELAYED_H_ */

Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Condition.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Condition.h?rev=712296&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Condition.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Condition.h Fri Nov  7 14:41:02 2008
@@ -0,0 +1,411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_UTIL_CONCURRENT_LOCKS_CONDITION_H_
+#define _DECAF_UTIL_CONCURRENT_LOCKS_CONDITION_H_
+
+#include <decaf/util/Config.h>
+
+#include <decaf/lang/exceptions/InterruptedException.h>
+#include <decaf/lang/exceptions/IllegalMonitorStateException.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+    /**
+     * Condition factors out the Mutex monitor methods (wait, notify  and notifyAll) into
+     * distinct objects to give the effect of having multiple wait-sets per object, by
+     * combining them with the use of arbitrary Lock implementations. Where a Lock replaces
+     * the use of synchronized statements, a Condition replaces the use of the Object monitor
+     * methods.
+     *
+     * Conditions (also known as condition queues or condition variables) provide a means for
+     * one thread to suspend execution (to "wait") until notified by another thread that some
+     * state condition may now be true. Because access to this shared state information occurs
+     * in different threads, it must be protected, so a lock of some form is associated with
+     * the condition. The key property that waiting for a condition provides is that it
+     * atomically releases the associated lock and suspends the current thread.
+     *
+     * A Condition instance is intrinsically bound to a lock. To obtain a Condition instance
+     * for a particular Lock instance use its newCondition() method.
+     *
+     * As an example, suppose we have a bounded buffer which supports put and take methods.
+     * If a take is attempted on an empty buffer, then the thread will block until an item
+     * becomes available; if a put is attempted on a full buffer, then the thread will block
+     * until a space becomes available. We would like to keep waiting put threads and take
+     * threads in separate wait-sets so that we can use the optimization of only notifying a
+     * single thread at a time when items or spaces become available in the buffer. This can
+     * be achieved using two Condition instances.
+     *
+     *   class BoundedBuffer {
+     *      Lock* lock = new ReentrantLock();
+     *      Condition* notFull  = lock->newCondition();
+     *      Condition* notEmpty = lock->newCondition();
+     *
+     *      Object* items = new Object[100];
+     *      int putptr, takeptr, count;
+     *
+     *      public void put( Object* x ) throw( InterruptedException ) {
+     *        lock->lock();
+     *        try {
+     *          while( count == 100 )
+     *            notFull->await();
+     *          items[putptr] = x;
+     *          if (++putptr == 100) putptr = 0;
+     *          ++count;
+     *          notEmpty->signal();
+     *        } catch(...) {
+     *          lock->unlock();
+     *        }
+     *      }
+     *
+     *      public Object take() throw( InterruptedException ) {
+     *        lock->lock();
+     *        try {
+     *          while(count == 0)
+     *            notEmpty->await();
+     *          Object x = items[takeptr];
+     *          if (++takeptr == 100) takeptr = 0;
+     *          --count;
+     *          notFull->signal();
+     *          return x;
+     *        } catch(...) {
+     *          lock->unlock();
+     *        }
+     *      }
+     *    }
+     *
+     * (The ArrayBlockingQueue class provides this functionality, so there is no reason to
+     * implement this sample usage class.)
+     *
+     * Implementation Considerations
+     *
+     * When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general,
+     * as a concession to the underlying platform semantics. This has little practical impact
+     * on most application programs as a Condition should always be waited upon in a loop,
+     * testing the state predicate that is being waited for. An implementation is free to
+     * remove the possibility of spurious wakeups but it is recommended that applications
+     * programmers always assume that they can occur and so always wait in a loop.
+     *
+     * The three forms of condition waiting (interruptible, non-interruptible, and timed)
+     * may differ in their ease of implementation on some platforms and in their performance
+     * characteristics. In particular, it may be difficult to provide these features and
+     * maintain specific semantics such as ordering guarantees. Further, the ability to
+     * interrupt the actual suspension of the thread may not always be feasible to
+     * implement on all platforms.
+     *
+     * Consequently, an implementation is not required to define exactly the same guarantees
+     * or semantics for all three forms of waiting, nor is it required to support interruption
+     * of the actual suspension of the thread.
+     *
+     * An implementation is required to clearly document the semantics and guarantees provided
+     * by each of the waiting methods, and when an implementation does support interruption
+     * of thread suspension then it must obey the interruption semantics as defined in this
+     * interface.
+     *
+     * As interruption generally implies cancellation, and checks for interruption are often
+     * infrequent, an implementation can favor responding to an interrupt over normal method
+     * return. This is true even if it can be shown that the interrupt occurred after another
+     * action may have unblocked the thread. An implementation should document this behavior.
+     *
+     * @since 1.0
+     */
+    class DECAF_API Condition {
+    public:
+
+        virtual ~Condition() {}
+
+        /**
+         * Causes the current thread to wait until it is signalled or interrupted.
+         * <p>
+         * The lock associated with this Condition is atomically released and the current
+         * thread becomes disabled for thread scheduling purposes and lies dormant until one
+         * of four things happens:
+         *
+         *   * Some other thread invokes the signal() method for this Condition and the
+         *     current thread happens to be chosen as the thread to be awakened; or
+         *   * Some other thread invokes the signalAll() method for this Condition; or
+         *   * Some other thread interrupts the current thread, and interruption of thread
+         *     suspension is supported; or
+         *   * A "spurious wakeup" occurs.
+         *
+         * In all cases, before this method can return the current thread must re-acquire the
+         * lock associated with this condition. When the thread returns it is guaranteed to
+         * hold this lock.
+         *
+         * If the current thread:
+         *
+         *   * has its interrupted status set on entry to this method; or
+         *   * is interrupted while waiting and interruption of thread suspension is supported,
+         *
+         * then InterruptedException is thrown and the current thread's interrupted status is
+         * cleared. It is not specified, in the first case, whether or not the test for
+         * interruption occurs before the lock is released.
+         *
+         * Implementation Considerations
+         *
+         * The current thread is assumed to hold the lock associated with this Condition when
+         * this method is called. It is up to the implementation to determine if this is the
+         * case and if not, how to respond. Typically, an exception will be thrown (such as
+         * IllegalMonitorStateException) and the implementation must document that fact.
+         *
+         * An implementation can favor responding to an interrupt over normal method return
+         * in response to a signal. In that case the implementation must ensure that the
+         * signal is redirected to another waiting thread, if there is one.
+         *
+         * @throws InterruptedException
+         *         if the current thread is interrupted (and interruption of thread
+         *         suspension is supported)
+         *
+         * @throws IllegalMonitorStateException
+         *         if the caller is not the lock owner.
+         */
+        virtual void await()
+            throw( decaf::lang::exceptions::InterruptedException,
+                   decaf::lang::exceptions::IllegalMonitorStateException ) = 0;
+
+        /**
+         * Causes the current thread to wait until it is signalled.
+         * <p>
+         * The lock associated with this condition is atomically released and the current
+         * thread becomes disabled for thread scheduling purposes and lies dormant until
+         * one of three things happens:
+         *
+         *   * Some other thread invokes the signal() method for this Condition and the
+         *     current thread happens to be chosen as the thread to be awakened; or
+         *   * Some other thread invokes the signalAll() method for this Condition; or
+         *   * A "spurious wakeup" occurs.
+         *
+         * In all cases, before this method can return the current thread must re-acquire
+         * the lock associated with this condition. When the thread returns it is guaranteed
+         * to hold this lock.
+         *
+         * If the current thread's interrupted status is set when it enters this method, or
+         * it is interrupted while waiting, it will continue to wait until signalled. When
+         * it finally returns from this method its interrupted status will still be set.
+         *
+         * Implementation Considerations
+         *
+         * The current thread is assumed to hold the lock associated with this Condition
+         * when this method is called. It is up to the implementation to determine if this
+         * is the case and if not, how to respond. Typically, an exception will be thrown
+         * (such as IllegalMonitorStateException) and the implementation must document
+         * that fact.
+         *
+         * @throws IllegalMonitorStateException
+         *         if the caller is not the lock owner.
+         */
+        virtual void awaitUninterruptibly()
+            throw( decaf::lang::exceptions::IllegalMonitorStateException ) = 0;
+
+        /**
+         * Causes the current thread to wait until it is signalled or interrupted, or
+         * the specified waiting time elapses.
+         * <p>
+         * The lock associated with this condition is atomically released and the current
+         * thread becomes disabled for thread scheduling purposes and lies dormant until
+         * one of five things happens:
+         *
+         *   * Some other thread invokes the signal() method for this Condition and the
+         *     current thread happens to be chosen as the thread to be awakened; or
+         *   * Some other thread invokes the signalAll() method for this Condition; or
+         *   * Some other thread interrupts the current thread, and interruption of thread
+         *     suspension is supported; or
+         *   * The specified waiting time elapses; or
+         *   * A "spurious wakeup" occurs.
+         *
+         * In all cases, before this method can return the current thread must re-acquire
+         * the lock associated with this condition. When the thread returns it is guaranteed
+         * to hold this lock.
+         *
+         * If the current thread:
+         *
+         *   * has its interrupted status set on entry to this method; or
+         *   * is interrupted while waiting and interruption of thread suspension is supported,
+         *
+         * then InterruptedException is thrown and the current thread's interrupted status is
+         * cleared. It is not specified, in the first case, whether or not the test for
+         * interruption occurs before the lock is released.
+         *
+         * The method returns an estimate of the number of nanoseconds remaining to wait given
+         * the supplied nanosTimeout value upon return, or a value less than or equal to zero
+         * if it timed out. This value can be used to determine whether and how long to re-wait
+         * in cases where the wait returns but an awaited condition still does not hold.
+         * Typical uses of this method take the following form:
+         *
+         *    synchronized boolean aMethod( long timeout, const TimeUnit& unit ) {
+         *      long nanosTimeout = unit.toNanos(timeout);
+         *      while (!conditionBeingWaitedFor) {
+         *        if (nanosTimeout > 0)
+         *            nanosTimeout = theCondition->awaitNanos(nanosTimeout);
+         *        else
+         *           return false;
+         *      }
+         *      // ...
+         *    }
+         *
+         * Design note: This method requires a nanosecond argument so as to avoid truncation
+         * errors in reporting remaining times. Such precision loss would make it difficult
+         * for programmers to ensure that total waiting times are not systematically shorter
+         * than specified when re-waits occur.
+         *
+         * Implementation Considerations
+         *
+         * The current thread is assumed to hold the lock associated with this Condition when
+         * this method is called. It is up to the implementation to determine if this is the
+         * case and if not, how to respond. Typically, an exception will be thrown (such as
+         * IllegalMonitorStateException) and the implementation must document that fact.
+         *
+         * An implementation can favor responding to an interrupt over normal method return in
+         * response to a signal, or over indicating the elapse of the specified waiting time.
+         * In either case the implementation must ensure that the signal is redirected to
+         * another waiting thread, if there is one.
+         *
+         * @param nanosTimeout - the maximum time to wait, in nanoseconds
+         *
+         * @returns an estimate of the nanosTimeout value minus the time spent waiting upon
+         *          return from this method. A positive value may be used as the argument to
+         *          a subsequent call to this method to finish waiting out the desired time.
+         *          A value less than or equal to zero indicates that no time remains.
+         *
+         * @throws InterruptedException
+         *         if the current thread is interrupted (and interruption of thread suspension
+         *         is supported)
+         *
+         * @throws IllegalMonitorStateException
+         *         if the caller is not the lock owner.
+         */
+        virtual long long awaitNanos( long long nanosTimeout )
+            throw( decaf::lang::exceptions::InterruptedException,
+                   decaf::lang::exceptions::IllegalMonitorStateException ) = 0;
+
+        /**
+         * Causes the current thread to wait until it is signalled or interrupted, or the
+         * specified waiting time elapses. This method is behaviorally equivalent to:
+         *
+         *      awaitNanos(unit.toNanos(time)) > 0
+         *
+         * @param time - the maximum time to wait
+         * @param unit - the time unit of the time argument
+         *
+         * @returns false if the waiting time detectably elapsed before return from the
+         *          method, else true
+         *
+         * @throws InterruptedException
+         *         if the current thread is interrupted (and interruption of thread suspension
+         *         is supported)
+         *
+         * @throws IllegalMonitorStateException
+         *         if the caller is not the lock owner.
+         */
+        virtual bool await( long long time, const TimeUnit& unit )
+            throw( decaf::lang::exceptions::InterruptedException,
+                   decaf::lang::exceptions::IllegalMonitorStateException ) = 0;
+
+        /**
+         * Causes the current thread to wait until it is signalled or interrupted, or the
+         * specified deadline elapses.
+         * <p>
+         * The lock associated with this condition is atomically released and the current
+         * thread becomes disabled for thread scheduling purposes and lies dormant until one
+         * of five things happens:
+         *
+         *   * Some other thread invokes the signal() method for this Condition and the
+         *     current thread happens to be chosen as the thread to be awakened; or
+         *   * Some other thread invokes the signalAll() method for this Condition; or
+         *   * Some other thread interrupts the current thread, and interruption of thread
+         *     suspension is supported; or
+         *   * The specified deadline elapses; or
+         *   * A "spurious wakeup" occurs.
+         *
+         * In all cases, before this method can return the current thread must re-acquire the
+         * lock associated with this condition. When the thread returns it is guaranteed to
+         * hold this lock.
+         *
+         * If the current thread:
+         *
+         *   * has its interrupted status set on entry to this method; or
+         *   * is interrupted while waiting and interruption of thread suspension is supported,
+         *
+         * then InterruptedException is thrown and the current thread's interrupted status is
+         * cleared. It is not specified, in the first case, whether or not the test for
+         * interruption occurs before the lock is released.
+         *
+         * The return value indicates whether the deadline has elapsed, which can be used as
+         * follows:
+         *
+         *   bool aMethod( const Date& deadline ) {
+         *      bool stillWaiting = true;
+         *      while (!conditionBeingWaitedFor) {
+         *        if (stillWaiting)
+         *            stillWaiting = theCondition->awaitUntil(deadline);
+         *         else
+         *           return false;
+         *      }
+         *      // ...
+         *   }
+         *
+         * Implementation Considerations
+         *
+         * The current thread is assumed to hold the lock associated with this Condition when
+         * this method is called. It is up to the implementation to determine if this is the
+         * case and if not, how to respond. Typically, an exception will be thrown (such as
+         * IllegalMonitorStateException) and the implementation must document that fact.
+         *
+         * An implementation can favor responding to an interrupt over normal method return
+         * in response to a signal, or over indicating the passing of the specified deadline.
+         * In either case the implementation must ensure that the signal is redirected to
+         * another waiting thread, if there is one.
+         *
+         * @param deadline - the absolute time to wait until
+         *
+         * @returns false if the deadline has elapsed upon return, else true
+         *
+         * @throws InterruptedException
+         *         if the current thread is interrupted (and interruption of thread suspension
+         *         is supported)
+         *
+         * @throws IllegalMonitorStateException
+         *         if the caller is not the lock owner.
+         */
+//        virtual bool awaitUntil( Date deadline )
+//            throw( decaf::lang::exceptions::InterruptedException,
+//                   decaf::lang::exceptions::IllegalMonitorStateException ) = 0;
+
+        /**
+         * Wakes up one waiting thread.
+         * <p>
+         * If any threads are waiting on this condition then one is selected for waking up.
+         * That thread must then re-acquire the lock before returning from await.
+         */
+        virtual void signal() = 0;
+
+        /**
+         * Wakes up all waiting threads.
+         * <p>
+         * If any threads are waiting on this condition then they are all woken up. Each
+         * thread must re-acquire the lock before it can return from await.
+         */
+        virtual void signalAll() = 0;
+
+    };
+
+}}}}
+
+#endif /*_DECAF_UTIL_CONCURRENT_LOCKS_CONDITION_H_*/

Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Lock.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Lock.h?rev=712296&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Lock.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/Lock.h Fri Nov  7 14:41:02 2008
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_UTIL_CONCURRENT_LOCKS_LOCK_H_
+#define _DECAF_UTIL_CONCURRENT_LOCKS_LOCK_H_
+
+#include <decaf/util/Config.h>
+
+#include <decaf/lang/exceptions/InterruptedException.h>
+#include <decaf/lang/exceptions/UnsupportedOperationException.h>
+#include <decaf/util/concurrent/locks/Condition.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+    /**
+     * Lock implementations provide more extensive locking operations than can be
+     * obtained using synchronized statements. They allow more flexible structuring,
+     * may have quite different properties, and may support multiple associated
+     * Condition objects.
+     *
+     * A lock is a tool for controlling access to a shared resource by multiple
+     * threads. Commonly, a lock provides exclusive access to a shared resource:
+     * only one thread at a time can acquire the lock and all access to the shared
+     * resource requires that the lock be acquired first. However, some locks may
+     * allow concurrent access to a shared resource, such as the read lock of a
+     * ReadWriteLock.
+     *
+     * While the scoping mechanism for synchronized statements makes it much easier
+     * easier to program with monitor locks, and helps avoid many common programming
+     * errors involving locks, there are occasions where you need to work with locks
+     * in a more flexible way. For example, some algorithms for traversing concurrently
+     * accessed data structures require the use of "hand-over-hand" or
+     * "chain locking": you acquire the lock of node A, then node B, then release A
+     * and acquire C, then release B and acquire D and so on. Implementations of the
+     * Lock interface enable the use of such techniques by allowing a lock to be
+     * acquired and released in different scopes, and allowing multiple locks to be
+     * acquired and released in any order.
+     *
+     * With this increased flexibility comes additional responsibility. The absence of
+     * block-structured locking removes the automatic release of locks that occurs with
+     * synchronized statements. In most cases, the following idiom should be used:
+     *
+     *    Lock l = ...;
+     *    l.lock();
+     *    try {
+     *        // access the resource protected by this lock
+     *    } catch(...) {
+     *        l.unlock();
+     *    }
+     *
+     * When locking and unlocking occur in different scopes, care must be taken to ensure
+     * that all code that is executed while the lock is held is protected by try-catch
+     * ensure that the lock is released when necessary.
+     *
+     * Lock implementations provide additional functionality over the use of synchronized
+     * methods and statements by providing a non-blocking attempt to acquire a lock
+     * (tryLock()), an attempt to acquire the lock that can be interrupted (lockInterruptibly(),
+     * and an attempt to acquire the lock that can timeout (tryLock(long, TimeUnit)).
+     *
+     * Note that Lock instances are just normal objects and can themselves be used as the
+     * target in a synchronized statement.
+     *
+     * The three forms of lock acquisition (interruptible, non-interruptible, and timed)
+     * may differ in their performance characteristics, ordering guarantees, or other
+     * implementation qualities. Further, the ability to interrupt the ongoing acquisition
+     * of a lock may not be available in a given Lock class. Consequently, an implementation
+     * is not required to define exactly the same guarantees or semantics for all three forms
+     * of lock acquisition, nor is it required to support interruption of an ongoing lock
+     * acquisition. An implementation is required to clearly document the semantics and
+     * guarantees provided by each of the locking methods. It must also obey the interruption
+     * semantics as defined in this interface, to the extent that interruption of lock
+     * acquisition is supported: which is either totally, or only on method entry.
+     *
+     * As interruption generally implies cancellation, and checks for interruption are
+     * often infrequent, an implementation can favor responding to an interrupt over normal
+     * method return. This is true even if it can be shown that the interrupt occurred after
+     * another action may have unblocked the thread. An implementation should document this
+     * behavior.
+     *
+     * @since 1.0
+     */
+    class DECAF_API Lock {
+    public:
+
+        virtual ~Lock() {}
+
+        /**
+         * Acquires the lock.
+         * <p>
+         * If the lock is not available then the current thread becomes disabled for thread
+         * scheduling purposes and lies dormant until the lock has been acquired.
+         * <p>
+         * Implementation Considerations
+         * <p>
+         * A Lock implementation may be able to detect erroneous use of the lock, such as an
+         * invocation that would cause deadlock, and may throw an (unchecked) exception in
+         * such circumstances. The circumstances and the exception type must be documented
+         * by that Lock implementation.
+         */
+        virtual void lock() = 0;
+
+        /**
+         * Acquires the lock unless the current thread is interrupted.
+         * <p>
+         * Acquires the lock if it is available and returns immediately.
+         * <p>
+         * If the lock is not available then the current thread becomes disabled for thread
+         * scheduling purposes and lies dormant until one of two things happens:
+         *
+         *  * The lock is acquired by the current thread; or
+         *  * Some other thread interrupts the current thread, and interruption of lock
+         *    acquisition is supported.
+         *
+         * If the current thread:
+         *
+         *  * has its interrupted status set on entry to this method; or
+         *  * is interrupted while acquiring the lock, and interruption of lock acquisition
+         *    is supported,
+         *
+         * then InterruptedException is thrown and the current thread's interrupted status
+         * is cleared.
+         *
+         * Implementation Considerations
+         *
+         * The ability to interrupt a lock acquisition in some implementations may not be
+         * possible, and if possible may be an expensive operation. The programmer should
+         * be aware that this may be the case. An implementation should document when this
+         * is the case.
+         *
+         * An implementation can favor responding to an interrupt over normal method return.
+         *
+         * A Lock implementation may be able to detect erroneous use of the lock, such as an
+         * invocation that would cause deadlock, and may throw an (unchecked) exception in
+         * such circumstances. The circumstances and the exception type must be documented
+         * by that Lock implementation.
+         *
+         * @throws InterruptedException
+         *         if the current thread is interrupted while acquiring the lock (and
+         *         interruption of lock acquisition is supported).
+         */
+        virtual void lockInterruptibly() throw ( decaf::lang::exceptions::InterruptedException ) = 0;
+
+        /**
+         * Acquires the lock only if it is free at the time of invocation.
+         * <p>
+         * Acquires the lock if it is available and returns immediately with the value true.
+         * If the lock is not available then this method will return immediately with the
+         * value false.
+         * <p>
+         * A typical usage idiom for this method would be:
+         *
+         *   Lock lock = ...;
+         *   if (lock.tryLock()) {
+         *       try {
+         *            // manipulate protected state
+         *       } catch(...) {
+         *            lock.unlock();
+         *       }
+         *   } else {
+         *       // perform alternative actions
+         *   }
+         *
+         * This usage ensures that the lock is unlocked if it was acquired, and doesn't
+         * try to unlock if the lock was not acquired.
+         *
+         * @returns true if the lock was acquired and false otherwise
+         */
+        virtual bool tryLock() = 0;
+
+        /**
+         * Acquires the lock if it is free within the given waiting time and the current
+         * thread has not been interrupted.
+         * <p>
+         * If the lock is available this method returns immediately with the value true.
+         * If the lock is not available then the current thread becomes disabled for thread
+         * scheduling purposes and lies dormant until one of three things happens:
+         *
+         *   * The lock is acquired by the current thread; or
+         *   * Some other thread interrupts the current thread, and interruption of lock
+         *     acquisition is supported; or
+         *   * The specified waiting time elapses
+         *
+         * If the lock is acquired then the value true is returned.
+         *
+         * If the current thread:
+         *
+         *   * has its interrupted status set on entry to this method; or
+         *   * is interrupted while acquiring the lock, and interruption of lock acquisition
+         *     is supported,
+         *
+         * then InterruptedException is thrown and the current thread's interrupted status
+         * is cleared.
+         *
+         * If the specified waiting time elapses then the value false is returned. If the
+         * time is less than or equal to zero, the method will not wait at all.
+         *
+         * Implementation Considerations
+         *
+         * The ability to interrupt a lock acquisition in some implementations may not
+         * be possible, and if possible may be an expensive operation. The programmer should
+         * be aware that this may be the case. An implementation should document when this
+         * is the case.
+         *
+         * An implementation can favor responding to an interrupt over normal method return,
+         * or reporting a timeout.
+         *
+         * A Lock implementation may be able to detect erroneous use of the lock, such as an
+         * invocation that would cause deadlock, and may throw an (unchecked) exception in
+         * such circumstances. The circumstances and the exception type must be documented by
+         * that Lock implementation.
+         *
+         * @param time
+         *        the maximum time to wait for the lock
+         * @param unit
+         *        the time unit of the time argument
+         *
+         * @returns true if the lock was acquired and false if the waiting time elapsed
+         *          before the lock was acquired
+         *
+         * @throws InterruptedException
+         *         if the current thread is interrupted while acquiring the lock (and
+         *         interruption of lock acquisition is supported)
+         */
+        virtual bool tryLock( long long time, const TimeUnit& unit )
+            throw ( decaf::lang::exceptions::InterruptedException ) = 0;
+
+        /**
+         * Releases the lock.
+         * <p>
+         * Implementation Considerations
+         *
+         * A Lock implementation will usually impose restrictions on which thread can release
+         * a lock (typically only the holder of the lock can release it) and may throw an
+         * exception if the restriction is violated. Any restrictions and the exception
+         * type must be documented by that Lock implementation.
+         */
+        virtual void unlock() = 0;
+
+        /**
+         * Returns a new Condition instance that is bound to this Lock instance.
+         * <p>
+         * Before waiting on the condition the lock must be held by the current thread.
+         * A call to Condition.await() will atomically release the lock before waiting
+         * and re-acquire the lock before the wait returns.
+         * <p>
+         * Implementation Considerations
+         * <p>
+         * The exact operation of the Condition instance depends on the Lock implementation
+         * and must be documented by that implementation.
+         *
+         * @returns A new Condition instance for this Lock instance the caller must
+         *          delete the returned Condition object when done with it.
+         *
+         * @throws UnsupportedOperationException
+         *         if this Lock implementation does not support conditions
+         */
+        virtual Condition* newCondition()
+            throw ( decaf::lang::exceptions::UnsupportedOperationException ) = 0;
+
+    };
+
+}}}}
+
+#endif /*_DECAF_UTIL_CONCURRENT_LOCKS_LOCK_H_ */

Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/ReadWriteLock.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/ReadWriteLock.h?rev=712296&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/ReadWriteLock.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/locks/ReadWriteLock.h Fri Nov  7 14:41:02 2008
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_UTIL_CONCURRENT_LOCKS_READWRITELOCK_H_
+#define _DECAF_UTIL_CONCURRENT_LOCKS_READWRITELOCK_H_
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+    /**
+     * A ReadWriteLock maintains a pair of associated locks, one for read-only operations
+     * and one for writing. The read lock may be held simultaneously by multiple reader
+     * threads, so long as there are no writers. The write lock is exclusive.
+     * <p>
+     * All ReadWriteLock implementations must guarantee that the memory synchronization
+     * effects of writeLock operations (as specified in the Lock interface) also hold with
+     * respect to the associated readLock. That is, a thread successfully acquiring the read
+     * lock will see all updates made upon previous release of the write lock.
+     * <p>
+     * A read-write lock allows for a greater level of concurrency in accessing shared data
+     * than that permitted by a mutual exclusion lock. It exploits the fact that while only
+     * a single thread at a time (a writer thread) can modify the shared data, in many cases
+     * any number of threads can concurrently read the data (hence reader threads). In theory,
+     * the increase in concurrency permitted by the use of a read-write lock will lead to
+     * performance improvements over the use of a mutual exclusion lock. In practice this
+     * increase in concurrency will only be fully realized on a multi-processor, and then
+     * only if the access patterns for the shared data are suitable.
+     * <p>
+     * Whether or not a read-write lock will improve performance over the use of a mutual
+     * exclusion lock depends on the frequency that the data is read compared to being
+     * modified, the duration of the read and write operations, and the contention for the
+     * data - that is, the number of threads that will try to read or write the data at the
+     * same time. For example, a collection that is initially populated with data and
+     * thereafter infrequently modified, while being frequently searched (such as a
+     * directory of some kind) is an ideal candidate for the use of a read-write lock.
+     * However, if updates become frequent then the data spends most of its time being
+     * exclusively locked and there is little, if any increase in concurrency. Further, if
+     * the read operations are too short the overhead of the read-write lock implementation
+     * (which is inherently more complex than a mutual exclusion lock) can dominate the
+     * execution cost, particularly as many read-write lock implementations still serialize
+     * all threads through a small section of code. Ultimately, only profiling and
+     * measurement will establish whether the use of a read-write lock is suitable for your
+     * application.
+     * <p>
+     * Although the basic operation of a read-write lock is straight-forward, there are many
+     * policy decisions that an implementation must make, which may affect the effectiveness
+     * of the read-write lock in a given application. Examples of these policies include:
+     *
+     *  * Determining whether to grant the read lock or the write lock, when both readers and
+     *    writers are waiting, at the time that a writer releases the write lock. Writer
+     *    preference is common, as writes are expected to be short and infrequent. Reader
+     *    preference is less common as it can lead to lengthy delays for a write if the
+     *    readers are frequent and long-lived as expected. Fair, or "in-order" implementations
+     *    are also possible.
+     *  * Determining whether readers that request the read lock while a reader is active and
+     *    a writer is waiting, are granted the read lock. Preference to the reader can delay
+     *    the writer indefinitely, while preference to the writer can reduce the potential for
+     *    concurrency.
+     *  * Determining whether the locks are reentrant: can a thread with the write lock
+     *    reacquire it? Can it acquire a read lock while holding the write lock? Is the read
+     *    lock itself reentrant?
+     *  * Can the write lock be downgraded to a read lock without allowing an intervening
+     *    writer? Can a read lock be upgraded to a write lock, in preference to other waiting
+     *    readers or writers?
+     *
+     * You should consider all of these things when evaluating the suitability of a given
+     * implementation for your application.
+     *
+     * @since 1.0
+     */
+    class ReadWriteLock {
+    public:
+
+        virtual ~ReadWriteLock() {}
+
+        /**
+         * Returns the lock used for reading.
+         */
+        virtual Lock& readLock() = 0;
+
+        /**
+         * Returns the lock used for writing.
+         * @rerturns the lock used for writing.
+         */
+        virtual Lock& writeLock() = 0;
+
+    };
+
+}}}}
+
+#endif /*_DECAF_UTIL_CONCURRENT_LOCKS_READWRITELOCK_H_*/