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