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_*/