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/04/29 22:52:37 UTC
svn commit: r652104 [19/29] - in /activemq/activemq-cpp/trunk: ./ m4/
src/examples/ src/examples/consumers/ src/main/ src/main/decaf/
src/main/decaf/internal/ src/main/decaf/internal/net/
src/main/decaf/internal/nio/ src/main/decaf/internal/util/ src/m...
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/Queue.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/Queue.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/Queue.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/Queue.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,265 @@
+/*
+ * 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_QUEUE_H_
+#define _DECAF_UTIL_QUEUE_H_
+
+#include <list>
+#include <vector>
+#include <decaf/util/concurrent/Mutex.h>
+#include <decaf/lang/Exception.h>
+
+namespace decaf{
+namespace util{
+
+ /**
+ * The Queue class accepts messages with an psuh(m) command
+ * where m is the message to be queued. It destructively
+ * returns the message with pop(). pop() returns messages in
+ * the order they were enqueued.
+ *
+ * Queue is implemented with an instance of the STL queue object.
+ * The interface is essentially the same as that of the STL queue
+ * except that the pop method actually reaturns a reference to the
+ * element popped. This frees the app from having to call the
+ * <code>front</code> method before calling pop.
+ *
+ * Queue<string> sq; // make a queue to hold string messages
+ * sq.push(s); // enqueues a message m
+ * string s = sq.pop(); // dequeues a message
+ *
+ * = DESIGN CONSIDERATIONS
+ *
+ * The Queue class inherits from the Synchronizable interface and
+ * provides methods for locking and unlocking this queue as well as
+ * waiting on this queue. In a multi-threaded app this can allow
+ * for multiple threads to be reading from and writing to the same
+ * Queue.
+ *
+ * Clients should consider that in a multiple threaded app it is
+ * possible that items could be placed on the queue faster than
+ * you are taking them off, so protection should be placed in your
+ * polling loop to ensure that you don't get stuck there.
+ */
+
+ template <typename T> class Queue : public concurrent::Synchronizable {
+ public:
+
+ Queue() {}
+ virtual ~Queue() {}
+
+ /**
+ * Empties this queue.
+ */
+ void clear() {
+ queue.clear();
+ }
+
+ /**
+ * Returns a Reference to the element at the head of the queue
+ * @return reference to a queue type object or (safe)
+ */
+ T& front() {
+ if( queue.empty() ) {
+ return getSafeValue();
+ }
+
+ return queue.front();
+ }
+
+ /**
+ * Returns a Reference to the element at the head of the queue
+ * @return reference to a queue type object or (safe)
+ */
+ const T& front() const {
+ if( queue.empty() ) {
+ return getSafeValue();
+ }
+
+ return queue.front();
+ }
+
+ /**
+ * Returns a Reference to the element at the tail of the queue
+ * @return reference to a queue type object or (safe)
+ */
+ T& back() {
+ if( queue.empty() ) {
+ return getSafeValue();
+ }
+
+ return queue.back();
+ }
+
+ /**
+ * Returns a Reference to the element at the tail of the queue
+ * @return reference to a queue type object or (safe)
+ */
+ const T& back() const {
+ if( queue.empty() ) {
+ return getSafeValue();
+ }
+
+ return queue.back();
+ }
+
+ /**
+ * Places a new Object at the Tail of the queue
+ * @param t - Queue Object Type reference.
+ */
+ void push( const T &t ) {
+ queue.push_back( t );
+ }
+
+ /**
+ * Places a new Object at the front of the queue
+ * @param t - Queue Object Type reference.
+ */
+ void enqueueFront( const T &t ) {
+ queue.push_front( t );
+ }
+
+ /**
+ * Removes and returns the element that is at the Head of the queue
+ * @return reference to a queue type object or (safe)
+ */
+ T pop() {
+ if( queue.empty() ) {
+ return getSafeValue();
+ }
+
+ // Pop the element into a temp, since we need to remain locked.
+ // this means getting front and then popping.
+ T temp = queue.front();
+ queue.pop_front();
+
+ return temp;
+ }
+
+ /**
+ * Gets the Number of elements currently in the Queue
+ * @return Queue Size
+ */
+ size_t size() const{
+ return queue.size();
+ }
+
+ /**
+ * Checks if this Queue is currently empty
+ * @return boolean indicating queue emptiness
+ */
+ bool empty() const {
+ return queue.empty();
+ }
+
+ /**
+ * @return the all values in this queue as a std::vector.
+ */
+ virtual std::vector<T> toArray() const {
+ std::vector<T> valueArray( queue.begin(), queue.end() );
+ return valueArray;
+ }
+
+ /**
+ * Reverses the order of the contents of this queue and stores them
+ * in the target queue.
+ * @param target - The target queue that will receive the contents of
+ * this queue in reverse order.
+ */
+ void reverse( Queue<T>& target ) const {
+ target.queue.insert( target.queue.end(), queue.rbegin(), queue.rend() );
+ }
+
+ /**
+ * Locks the object.
+ */
+ virtual void lock() throw( lang::Exception ){
+ mutex.lock();
+ }
+
+ /**
+ * Unlocks the object.
+ */
+ virtual void unlock() throw( lang::Exception ){
+ mutex.unlock();
+ }
+
+ /**
+ * Waits on a signal from this object, which is generated
+ * by a call to Notify. Must have this object locked before
+ * calling.
+ */
+ virtual void wait() throw( lang::Exception ){
+ mutex.wait();
+ }
+
+ /**
+ * Waits on a signal from this object, which is generated
+ * by a call to Notify. Must have this object locked before
+ * calling. This wait will timeout after the specified time
+ * interval.
+ * @param millisecs time to wait, or WAIT_INIFINITE
+ * @throws ActiveMQException
+ */
+ virtual void wait( unsigned long millisecs )
+ throw( lang::Exception ) {
+
+ mutex.wait(millisecs);
+ }
+
+ /**
+ * Signals a waiter on this object that it can now wake
+ * up and continue. Must have this object locked before
+ * calling.
+ */
+ virtual void notify() throw( lang::Exception ){
+ mutex.notify();
+ }
+
+ /**
+ * Signals the waiters on this object that it can now wake
+ * up and continue. Must have this object locked before
+ * calling.
+ */
+ virtual void notifyAll() throw( lang::Exception ){
+ mutex.notifyAll();
+ }
+
+ public: // Statics
+
+ /**
+ * Fetch a reference to the safe value this object will return
+ * when there is nothing to fetch from the queue.
+ * @return Reference to this Queues safe object
+ */
+ T& getSafeValue() {
+ static T safe;
+ return safe;
+ }
+
+ private:
+
+ // The real queue
+ std::list<T> queue;
+
+ // Object used for sync
+ util::concurrent::Mutex mutex;
+
+ };
+
+}}
+
+#endif /*_DECAF_UTIL_QUEUE_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/Random.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/Random.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/Random.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/Random.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+#include "Random.h"
+
+#include <decaf/util/Date.h>
+
+using namespace decaf;
+using namespace decaf::util;
+using namespace decaf::lang;
+
+unsigned long long Random::multiplier = 0x5deece66dLL;
+
+////////////////////////////////////////////////////////////////////////////////
+Random::Random() {
+ setSeed(Date::getCurrentTimeMilliseconds());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Random::Random( unsigned long long seed ) {
+ setSeed(seed);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool Random::nextBoolean() {
+ return next(1) != 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Random::nextBytes( std::vector<unsigned char>& buf ) {
+ int rand = 0;
+ std::size_t count = 0, loop = 0;
+ while (count < buf.size()) {
+ if (loop == 0) {
+ rand = nextInt();
+ loop = 3;
+ } else {
+ loop--;
+ }
+ buf[count++] = (unsigned char) rand;
+ rand >>= 8;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double Random::nextDouble() {
+ // was: return ((((long long) next(26) << 27) + next(27)) / (double) (1L << 53));
+ long long divisor = 1LL;
+ divisor <<= 31;
+ divisor <<= 22;
+ return ((((long long) next(26) << 27) + next(27)) / (double) divisor);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float Random::nextFloat() {
+ return (next(24) / 16777216.0f);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double Random::nextGaussian() {
+ if (haveNextNextGaussian) {
+ // if X1 has been returned, return the second Gaussian
+ haveNextNextGaussian = false;
+ return nextNextGaussian;
+ }
+
+ double v1, v2, s;
+ do {
+ // Generates two independent random variables U1, U2
+ v1 = 2 * nextDouble() - 1;
+ v2 = 2 * nextDouble() - 1;
+ s = v1 * v1 + v2 * v2;
+ } while (s >= 1);
+ double norm = std::sqrt(-2 * std::log(s) / s);
+ // should that not be norm instead of multiplier ?
+ nextNextGaussian = v2 * norm;
+ haveNextNextGaussian = true;
+ // should that not be norm instead of multiplier ?
+ return v1 * norm;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Random::nextInt() {
+ return next(32);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Random::nextInt( int n ) throw( exceptions::IllegalArgumentException ) {
+ if (n > 0) {
+ if ((n & -n) == n) {
+ return (int) ((n * (long long) next(31)) >> 31);
+ }
+ int bits, val;
+ do {
+ bits = next(31);
+ val = bits % n;
+ } while (bits - val + (n - 1) < 0);
+ return val;
+ }
+ throw exceptions::IllegalArgumentException();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long Random::nextLong() {
+ return ((long long) next(32) << 32) + next(32);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Random::setSeed( unsigned long long seed ) {
+ // was this->seed = (seed ^ multiplier) & ((1L << 48) - 1);
+ unsigned long long mask = 1ULL;
+ mask <<= 31;
+ mask <<= 17;
+ this->seed = (seed ^ multiplier) & (mask - 1);
+ haveNextNextGaussian = false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Random::next( int bits ) {
+ // was: seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
+ long long mask = 1L;
+ mask <<= 31;
+ mask <<= 17;
+ seed = (seed * multiplier + 0xbL) & (mask - 1);
+ // was: return (int) (seed >>> (48 - bits));
+ return (int) (seed >> (48 - bits));
+}
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/Random.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/Random.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/Random.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/Random.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,200 @@
+/*
+ * 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_RANDOM_H_
+#define _DECAF_UTIL_RANDOM_H_
+
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <decaf/util/Config.h>
+#include <vector>
+#include <cmath>
+
+namespace decaf{
+namespace util{
+
+ class DECAF_API Random
+ {
+ public:
+
+ /**
+ * Construct a random generator with the current time of day in
+ * milliseconds as the initial state.
+ *
+ * @see #setSeed
+ */
+ Random();
+
+ /**
+ * Construct a random generator with the given <code>seed</code>
+ * as the initial state.
+ *
+ * @param seed the seed that will determine the initial state of
+ * this random number generator
+ *
+ * @see #setSeed
+ */
+ Random( unsigned long long seed );
+
+ /**
+ * Answers the next pseudo-random, uniformly distributed boolean
+ * value generated by this generator.
+ *
+ * @return boolean a pseudo-random, uniformly distributed boolean
+ * value
+ */
+ bool nextBoolean();
+
+ /**
+ * Modifies the byte array by a random sequence of bytes generated
+ * by this random number generator.
+ *
+ * @param buf non-null array to contain the new random bytes
+ *
+ * @see #next
+ */
+ void nextBytes( std::vector<unsigned char>& buf );
+
+ /**
+ * Generates a normally distributed random double number between
+ * 0.0 inclusively and 1.0 exclusively.
+ *
+ * @return double
+ *
+ * @see #nextFloat
+ */
+ double nextDouble();
+
+ /**
+ * Generates a normally distributed random float number between
+ * 0.0 inclusively and 1.0 exclusively.
+ *
+ * @return float a random float number between 0.0 and 1.0
+ *
+ * @see #nextDouble
+ */
+ float nextFloat();
+
+ /**
+ * Pseudo-randomly generates (approximately) a normally
+ * distributed <code>double</code> value with mean 0.0 and a
+ * standard deviation value of <code>1.0</code> using the <i>polar
+ * method<i> of G. E. P. Box, M. E. Muller, and G. Marsaglia, as
+ * described by Donald E. Knuth in <i>The Art of Computer
+ * Programming, Volume 2: Seminumerical Algorithms</i>, section
+ * 3.4.1, subsection C, algorithm P
+ *
+ * @return double
+ *
+ * @see #nextDouble
+ */
+ double nextGaussian();
+
+ /**
+ * Generates a uniformly distributed 32-bit <code>int</code> value
+ * from the this random number sequence.
+ *
+ * @return int uniformly distributed <code>int</code> value
+ *
+ * @see #next
+ * @see #nextLong
+ */
+ int nextInt();
+
+ /**
+ * Returns to the caller a new pseudo-random integer value which
+ * is uniformly distributed between 0 (inclusively) and the value
+ * of <code>n</code> (exclusively).
+ *
+ * @return int
+ * @param n int
+ *
+ * @throws IllegalArgumentException
+ */
+ int nextInt( int n ) throw( lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Generates a uniformly distributed 64-bit <code>int</code> value
+ * from the this random number sequence.
+ *
+ * @return 64-bit <code>int</code> random number
+ *
+ * @see #next
+ * @see #nextInt()
+ * @see #nextInt(int)
+ */
+ long long nextLong();
+
+ /**
+ * Modifies the seed using linear congruential formula presented
+ * in <i>The Art of Computer Programming, Volume 2</i>, Section
+ * 3.2.1.
+ *
+ * @param seed the seed that alters the state of the random number
+ * generator
+ *
+ * @see #next
+ * @see #Random()
+ * @see #Random(long)
+ */
+ void setSeed( unsigned long long seed );
+
+ protected:
+
+ /**
+ * Answers a pseudo-random uniformly distributed <code>int</code>
+ * value of the number of bits specified by the argument
+ * <code>bits</code> as described by Donald E. Knuth in <i>The Art
+ * of Computer Programming, Volume 2: Seminumerical
+ * Algorithms</i>, section 3.2.1.
+ *
+ * @return int a pseudo-random generated int number
+ * @param bits number of bits of the returned value
+ *
+ * @see #nextBytes
+ * @see #nextDouble
+ * @see #nextFloat
+ * @see #nextInt()
+ * @see #nextInt(int)
+ * @see #nextGaussian
+ * @see #nextLong
+ */
+ int next( int bits );
+
+ private:
+
+ static unsigned long long multiplier;
+
+ /**
+ * The boolean value indicating if the second Gaussian number is available.
+ */
+ bool haveNextNextGaussian;
+
+ /**
+ * It is associated with the internal state of this generator.
+ */
+ unsigned long long seed;
+
+ /**
+ * The second Gaussian generated number.
+ */
+ double nextNextGaussian;
+
+ };
+
+}}
+
+#endif /*_DECAF_UTIL_RANDOM_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/Set.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/Set.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/Set.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/Set.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,255 @@
+/*
+ * 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_SET_H_
+#define _DECAF_UTIL_SET_H_
+
+#include <set>
+#include <vector>
+#include <decaf/lang/exceptions/NoSuchElementException.h>
+#include <decaf/util/concurrent/Synchronizable.h>
+#include <decaf/util/concurrent/Mutex.h>
+#include <decaf/util/Iterator.h>
+
+namespace decaf{
+namespace util{
+
+ /**
+ * Map template that wraps around a std::map to provide
+ * a more user-friendly interface and to provide common
+ * functions that do not exist in std::map.
+ */
+ template <typename E> class Set : public util::concurrent::Synchronizable
+ {
+ private:
+
+ std::set<E> values;
+ util::concurrent::Mutex mutex;
+
+ private:
+
+ class SetIterator : public Iterator<E> {
+ private:
+
+ typename std::set<E>::iterator current;
+ typename std::set<E>::iterator previous;
+ typename std::set<E>* set;
+
+ public:
+
+ SetIterator( typename std::set<E>* set ) {
+ this->current = set->begin();
+ this->previous = set->end();
+ this->set = set;
+ }
+ virtual ~SetIterator() {}
+
+ virtual E next() throw( lang::exceptions::NoSuchElementException ){
+ if( this->current == set->end() ) {
+ throw lang::exceptions::NoSuchElementException(
+ __FILE__, __LINE__,
+ "Set::Iterator::next - No more elements to return" );
+ }
+
+ this->previous = this->current;
+ return *( this->current++ );
+ }
+
+ virtual bool hasNext() const {
+ return ( this->current != set->end() );
+ }
+
+ virtual void remove() throw ( lang::exceptions::IllegalStateException,
+ lang::exceptions::UnsupportedOperationException ){
+ if( this->previous == set->end() ) {
+ throw lang::exceptions::IllegalStateException(
+ __FILE__, __LINE__,
+ "Set::Iterator::remove - Invalid State to call remove" );
+ }
+
+ this->set->erase( this->previous );
+ this->previous = this->set->end();
+ }
+ };
+
+ public:
+
+ /**
+ * Default constructor - does nothing.
+ */
+ Set(){}
+
+ /**
+ * Copy constructor - copies the content of the given set into this
+ * one.
+ * @param source The source set.
+ */
+ Set( const Set& source ){
+ copy( source );
+ }
+
+ virtual ~Set(){}
+
+ /**
+ * Returns an iterator for this collection. The order of Iteration
+ * is in no particular order other than the natural ording of the
+ * elements in the Set class.
+ * @returns Iterator<E> for this collection
+ */
+ Iterator<E>* iterator() {
+ return new SetIterator( &values );
+ }
+
+ /**
+ * Copies the content of the source set into this set. Erases
+ * all existing data in this st.
+ * @param source The source object to copy from.
+ */
+ virtual void copy( const Set& source ) {
+ // Add all of the entries to this map.
+ values = source.values;
+ }
+
+ /**
+ * Removes all values from this set.
+ */
+ virtual void clear() {
+ values.clear();
+ }
+
+ /**
+ * Indicates whether or this set contains the given value.
+ * @param value The value to look up.
+ * @return true if this set contains the value, otherwise false.
+ */
+ virtual bool contains( const E& value ) const {
+ typename std::set<E>::const_iterator iter;
+ iter = values.find( value );
+ return iter != values.end();
+ }
+
+ /**
+ * @return if the set contains any element or not, TRUE or FALSE
+ */
+ virtual bool isEmpty() const {
+ return values.empty();
+ }
+
+ /**
+ * @return The number of elements in this set.
+ */
+ virtual std::size_t size() const {
+ return values.size();
+ }
+
+ /**
+ * Adds the given value to the set.
+ * @param value The value to add.
+ */
+ virtual void add( const E& value ) {
+ values.insert( value );
+ }
+
+ /**
+ * Removes the value from the set.
+ * @param value The value to be removed.
+ */
+ virtual void remove( const E& value ) {
+ values.erase( value );
+ }
+
+ /**
+ * @return the all values in this set as a std::vector.
+ */
+ virtual std::vector<E> toArray() const {
+ std::vector<E> valueArray( values.size() );
+
+ typename std::set<E>::const_iterator iter;
+ iter=values.begin();
+ for( int ix=0; iter != values.end(); ++iter, ++ix ){
+ valueArray[ix] = *iter;
+ }
+
+ return valueArray;
+ }
+
+ public: // Methods from Synchronizable
+
+ /**
+ * Locks the object.
+ * @throws Exception
+ */
+ virtual void lock() throw( lang::Exception ) {
+ mutex.lock();
+ }
+
+ /**
+ * Unlocks the object.
+ * @throws Exception
+ */
+ virtual void unlock() throw( lang::Exception ) {
+ mutex.unlock();
+ }
+
+ /**
+ * Waits on a signal from this object, which is generated
+ * by a call to Notify. Must have this object locked before
+ * calling.
+ * @throws Exception
+ */
+ virtual void wait() throw( lang::Exception ) {
+ mutex.wait();
+ }
+
+ /**
+ * Waits on a signal from this object, which is generated
+ * by a call to Notify. Must have this object locked before
+ * calling. This wait will timeout after the specified time
+ * interval.
+ * @param millisecs the time in millisecsonds to wait, or
+ * WAIT_INIFINITE
+ * @throws Exception
+ */
+ virtual void wait( unsigned long millisecs )
+ throw( lang::Exception ) {
+ mutex.wait( millisecs );
+ }
+
+ /**
+ * Signals a waiter on this object that it can now wake
+ * up and continue. Must have this object locked before
+ * calling.
+ * @throws Exception
+ */
+ virtual void notify() throw( lang::Exception ) {
+ mutex.notify();
+ }
+
+ /**
+ * Signals the waiters on this object that it can now wake
+ * up and continue. Must have this object locked before
+ * calling.
+ * @throws Exception
+ */
+ virtual void notifyAll() throw( lang::Exception ) {
+ mutex.notifyAll();
+ }
+ };
+
+}}
+
+#endif /*_DECAF_UTIL_SET_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+#include "StringTokenizer.h"
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::util;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+StringTokenizer::StringTokenizer( const std::string& str,
+ const std::string& delim,
+ bool returnDelims ) {
+ // store off the data
+ this->str = str;
+ this->delim = delim;
+ this->returnDelims = returnDelims;
+
+ // Start and the beginning
+ pos = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringTokenizer::~StringTokenizer(){
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringTokenizer::countTokens() const
+{
+ int count = 0;
+ string::size_type localPos = pos;
+ string::size_type lastPos = pos;
+
+ while( localPos != string::npos ) {
+
+ if( returnDelims && str.find_first_of( delim, localPos ) == localPos ) {
+ count += 1;
+ localPos += 1;
+ continue;
+ }
+
+ // Find first token by spanning the fist non-delimiter, to the
+ // next delimiter, skipping any delimiters that are at the curret
+ // location.
+ lastPos = str.find_first_not_of( delim, localPos );
+ localPos = str.find_first_of( delim, lastPos );
+
+ if( lastPos != string::npos ) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool StringTokenizer::hasMoreTokens() const
+{
+ string::size_type nextpos =
+ returnDelims ? str.find_first_of( delim, pos ) :
+ str.find_first_not_of( delim, pos );
+
+ return ( nextpos != string::npos );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string StringTokenizer::nextToken()
+ throw ( lang::exceptions::NoSuchElementException )
+{
+ if( pos == string::npos ) {
+ throw NoSuchElementException(
+ __FILE__, __LINE__,
+ "StringTokenizer::nextToken - No more Tokens available");
+ }
+
+ if( returnDelims ) {
+ // if char at current pos is a delim return it and advance pos
+ if( str.find_first_of( delim, pos ) == pos ) {
+ return str.substr( pos++, 1 );
+ }
+ }
+
+ // Skip delimiters at beginning.
+ string::size_type lastPos = str.find_first_not_of( delim, pos );
+
+ // Find the next delimiter in the string, the charactors in between
+ // will be the token to return. If this returns string::npos then
+ // there are no more delimiters in the string.
+ pos = str.find_first_of( delim, lastPos );
+
+ if( string::npos != lastPos ) {
+ // Found a token, count it, if the pos of the next delim is npos
+ // then we set length to copy to npos so that all the remianing
+ // portion of the string is copied, otherwise we set it to the
+ return str.substr( lastPos,
+ pos == string::npos ? pos : pos-lastPos );
+ } else {
+ throw NoSuchElementException(
+ __FILE__, __LINE__,
+ "StringTokenizer::nextToken - No more Tokens available" );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string StringTokenizer::nextToken( const std::string& delim )
+ throw ( lang::exceptions::NoSuchElementException ) {
+
+ this->delim = delim;
+ return nextToken();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+unsigned int StringTokenizer::toArray( std::vector<std::string>& array )
+{
+ int count = 0;
+
+ while( hasMoreTokens() ) {
+ array.push_back( nextToken() );
+ count++;
+ }
+
+ return count;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringTokenizer::reset( const std::string& str,
+ const std::string& delim,
+ bool returnDelims )
+{
+ if( str != "" ) {
+ this->str = str;
+ }
+
+ if( delim != "" ) {
+ this->delim = delim;
+ }
+
+ this->returnDelims = returnDelims;
+
+ // Begin at the Beginning
+ this->pos = 0;
+}
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/StringTokenizer.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,137 @@
+/*
+ * 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_STRINGTOKENIZER_H_
+#define _DECAF_UTIL_STRINGTOKENIZER_H_
+
+#include <decaf/lang/exceptions/NoSuchElementException.h>
+#include <decaf/util/Config.h>
+#include <string>
+
+namespace decaf{
+namespace util{
+
+ class DECAF_API StringTokenizer
+ {
+ private:
+
+ // String to tokenize
+ std::string str;
+
+ // The delimiter string
+ std::string delim;
+
+ // The current pos in the string
+ std::string::size_type pos;
+
+ // Are we returning delimiters
+ bool returnDelims;
+
+ public:
+
+ /**
+ * Constructs a string tokenizer for the specified string. All
+ * characters in the delim argument are the delimiters for separating
+ * tokens.
+ *
+ * If the returnDelims flag is true, then the delimiter characters are
+ * also returned as tokens. Each delimiter is returned as a string of
+ * length one. If the flag is false, the delimiter characters are
+ * skipped and only serve as separators between tokens.
+ *
+ * Note that if delim is "", this constructor does not throw an
+ * exception. However, trying to invoke other methods on the resulting
+ * StringTokenizer may result in an Exception.
+ * @param string to tokenize
+ * @param String containing the delimiters
+ * @param boolean indicating if the delimiters are returned as tokens
+ */
+ StringTokenizer( const std::string& str,
+ const std::string& delim = " \t\n\r\f",
+ bool returnDelims = false);
+
+ virtual ~StringTokenizer();
+
+ /**
+ * Calculates the number of times that this tokenizer's nextToken
+ * method can be called before it generates an exception. The current
+ * position is not advanced.
+ * @return Count of remaining tokens
+ */
+ virtual int countTokens() const;
+
+ /**
+ * Tests if there are more tokens available from this tokenizer's
+ * string.
+ * @return true if there are more tokens remaining
+ */
+ virtual bool hasMoreTokens() const;
+
+ /**
+ * Returns the next token from this string tokenizer.
+ * @return string value of next token
+ * @thorws NoSuchElementException
+ */
+ virtual std::string nextToken()
+ throw ( lang::exceptions::NoSuchElementException );
+
+ /**
+ * Returns the next token in this string tokenizer's string. First,
+ * the set of characters considered to be delimiters by this
+ * StringTokenizer object is changed to be the characters in the
+ * string delim. Then the next token in the string after the current
+ * position is returned. The current position is advanced beyond the
+ * recognized token. The new delimiter set remains the default after
+ * this call.
+ * @param string containing the new set of delimiters
+ * @return next string in the token list
+ * @throw NoSuchElementException
+ */
+ virtual std::string nextToken( const std::string& delim )
+ throw ( lang::exceptions::NoSuchElementException );
+
+ /**
+ * Grab all remaining tokens in the String and return them
+ * in the vector that is passed in by reference.
+ * @param vector to place token strings in
+ * @return number of string placed into the vector
+ */
+ virtual unsigned int toArray( std::vector< std::string >& array );
+
+ /**
+ * Resets the Tokenizer's position in the String to the Beginning
+ * calls to countToken and nextToken now start back at the beginning.
+ * This allows this object to be reused, the caller need not create
+ * a new instance every time a String needs tokenizing.
+ * If set the string param will reset the string that this Tokenizer
+ * is working on. If set to "" no change is made.
+ * If set the delim param will reset the string that this Tokenizer
+ * is using to tokenizer the string. If set to "", no change is made
+ * If set the return Delims will set if this Tokenizer will return
+ * delimiters as tokens. Defaults to false.
+ * @param New String to tokenize or "", defaults to ""
+ * @param New Delimiter String to use or "", defaults to ""
+ * @param Should the Tokenizer return delimiters as Tokens, default false
+ */
+ virtual void reset( const std::string& str = "",
+ const std::string& delim = "",
+ bool returnDelims = false );
+
+ };
+
+}}
+
+#endif /*_DECAF_UTIL_STRINGTOKENIZER_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+#include "UUID.h"
+#include <apr_strings.h>
+#include <apr_md5.h>
+#include <decaf/lang/exceptions/RuntimeException.h>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::util;
+using namespace decaf::lang;
+
+////////////////////////////////////////////////////////////////////////////////
+UUID::UUID( long long mostSigBits, long long leastSigBits ) {
+
+ memcpy( &apr_uuid.data[0], &mostSigBits, sizeof( long long ) );
+ memcpy( &apr_uuid.data[sizeof(long long)], &leastSigBits, sizeof(long long ) );
+
+ this->mostSigBits = mostSigBits;
+ this->leastSigBits = leastSigBits;
+
+ // Version indicator, set when a UUID is generated
+ this->uuidVersion = (int)( mostSigBits & 0x000000000000F000LL ) >> 12;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+UUID::~UUID() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int UUID::compareTo( const UUID& value ) const {
+ return apr_strnatcmp( this->toString().c_str(), value.toString().c_str() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool UUID::equals( const UUID& value ) const {
+ return this->getMostSignificantBits() == value.getMostSignificantBits() &&
+ this->getLeastSignificantBits() == value.getLeastSignificantBits();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool UUID::operator==( const UUID& value ) const {
+ return this->equals( value );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool UUID::operator<( const UUID& value ) const {
+ return this->compareTo( value ) == -1 ? true : false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string UUID::toString() const {
+ char buffer[APR_UUID_FORMATTED_LENGTH+1] = {0};
+ apr_uuid_format( &buffer[0], &apr_uuid );
+ return &buffer[0];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long UUID::getLeastSignificantBits() const {
+ return this->leastSigBits;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long UUID::getMostSignificantBits() const {
+ long long result = 0;
+ memcpy( &result, &this->apr_uuid.data[sizeof(long long)], sizeof(long long) );
+ return this->mostSigBits;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long UUID::node() throw ( lang::exceptions::UnsupportedOperationException ) {
+
+ if( this->version() != 1 ) {
+ throw exceptions::UnsupportedOperationException(
+ __FILE__, __LINE__,
+ "UUID::node - Only a Version 1 UUID supports this operation." );
+ }
+
+ return ( this->leastSigBits & 0x0000FFFFFFFFFFFFULL );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long UUID::timestamp() throw ( lang::exceptions::UnsupportedOperationException ) {
+
+ if( this->version() != 1 ) {
+ throw exceptions::UnsupportedOperationException(
+ __FILE__, __LINE__,
+ "UUID::node - Only a Version 1 UUID supports this operation." );
+ }
+
+ // Mask out the version and shift values around to make time.
+ long long timeLow = ( mostSigBits & 0xFFFFFFFF00000000ULL) >> 32;
+ long long timeMid = ( mostSigBits & 0x00000000FFFF0000ULL) << 16;
+ long long timeHigh = ( mostSigBits & 0x0000000000000FFFULL) << 48;
+
+ return timeLow | timeMid | timeHigh;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int UUID::clockSequence() throw ( lang::exceptions::UnsupportedOperationException ) {
+
+ if( this->version() != 1 ) {
+ throw exceptions::UnsupportedOperationException(
+ __FILE__, __LINE__,
+ "UUID::node - Only a Version 1 UUID supports this operation." );
+ }
+
+ return (int)( ( this->leastSigBits & 0x3FFF000000000000ULL ) >> 48 );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int UUID::variant() throw ( lang::exceptions::UnsupportedOperationException ) {
+
+ // determine variant field
+ if( ( this->leastSigBits & 0x8000000000000000ULL ) == 0 ) {
+ // MSB0 not set, NCS backwards compatibility variant
+ return 0;
+ } else if( ( this->leastSigBits & 0x4000000000000000ULL ) != 0 ) {
+ // MSB1 set, either MS reserved or future reserved
+ return (int)( ( this->leastSigBits & 0xE000000000000000ULL ) >> 61 );
+ }
+
+ // MSB1 not set, RFC 4122 variant
+ return 2;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int UUID::version() throw ( lang::exceptions::UnsupportedOperationException ) {
+ return this->uuidVersion;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+UUID UUID::randomUUID() {
+
+ apr_uuid_t temp;
+ // Generate some random bytes.
+ apr_uuid_get( &temp );
+
+ long long msb = 0;
+ long long lsb = 0;
+
+ msb = (temp.data[0] & 0xFFLL) << 56;
+ msb |= (temp.data[1] & 0xFFLL) << 48;
+ msb |= (temp.data[2] & 0xFFLL) << 40;
+ msb |= (temp.data[3] & 0xFFLL) << 32;
+ msb |= (temp.data[4] & 0xFFLL) << 24;
+ msb |= (temp.data[5] & 0xFFLL) << 16;
+ msb |= (temp.data[6] & 0x0FLL) << 8;
+ msb |= (0x4LL << 12); // set the version to 4
+ msb |= (temp.data[7] & 0xFFLL);
+
+ lsb = (temp.data[8] & 0x3FLL) << 56;
+ lsb |= (0x2LL << 62); // set the variant to bits 01
+ lsb |= (temp.data[9] & 0xFFLL) << 48;
+ lsb |= (temp.data[10] & 0xFFLL) << 40;
+ lsb |= (temp.data[11] & 0xFFLL) << 32;
+ lsb |= (temp.data[12] & 0xFFLL) << 24;
+ lsb |= (temp.data[13] & 0xFFLL) << 16;
+ lsb |= (temp.data[14] & 0xFFLL) << 8;
+ lsb |= (temp.data[15] & 0xFFLL);
+
+ return UUID( msb, lsb );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+UUID UUID::nameUUIDFromBytes( const std::vector<char>& name ) {
+ return UUID::nameUUIDFromBytes( &name[0], name.size() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+UUID UUID::nameUUIDFromBytes( const char* name, std::size_t size ) {
+
+ apr_uuid_t temp;
+
+ if( apr_md5( &temp.data[0], name, size ) != APR_SUCCESS ) {
+ throw exceptions::RuntimeException(
+ __FILE__, __LINE__,
+ "UUID::nameUUIDFromBytes - Failed to run MD5 encoder." );
+ }
+
+ long long msb = 0;
+ long long lsb = 0;
+
+ msb = (temp.data[0] & 0xFFLL) << 56;
+ msb |= (temp.data[1] & 0xFFLL) << 48;
+ msb |= (temp.data[2] & 0xFFLL) << 40;
+ msb |= (temp.data[3] & 0xFFLL) << 32;
+ msb |= (temp.data[4] & 0xFFLL) << 24;
+ msb |= (temp.data[5] & 0xFFLL) << 16;
+ msb |= (temp.data[6] & 0x0FLL) << 8;
+ msb |= (0x3LL << 12); // set the version to 3
+ msb |= (temp.data[7] & 0xFFLL);
+
+ lsb = (temp.data[8] & 0x3FLL) << 56;
+ lsb |= (0x2LL << 62); // set the variant to bits 01
+ lsb |= (temp.data[9] & 0xFFLL) << 48;
+ lsb |= (temp.data[10] & 0xFFLL) << 40;
+ lsb |= (temp.data[11] & 0xFFLL) << 32;
+ lsb |= (temp.data[12] & 0xFFLL) << 24;
+ lsb |= (temp.data[13] & 0xFFLL) << 16;
+ lsb |= (temp.data[14] & 0xFFLL) << 8;
+ lsb |= (temp.data[15] & 0xFFLL);
+
+ return UUID( msb, lsb );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+UUID UUID::fromString( const std::string& name )
+ throw ( lang::exceptions::IllegalArgumentException ){
+
+ apr_uuid_t temp;
+
+ if( apr_uuid_parse( &temp, name.c_str() ) != APR_SUCCESS ) {
+ throw lang::exceptions::IllegalArgumentException(
+ __FILE__, __LINE__,
+ "UUID::fromString - Invalid UUID String: ",
+ name.c_str() );
+ }
+
+ long long mostSigBits = 0;
+ long long leastSigBits = 0;
+
+ // Extract to data from the uuid data
+ memcpy( &mostSigBits, &temp.data[0], sizeof(long long) );
+ memcpy( &leastSigBits, &temp.data[sizeof(long long)], sizeof(long long) );
+
+ return UUID( mostSigBits, leastSigBits );
+}
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/UUID.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,258 @@
+/*
+ * 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_UUID_H_
+#define _DECAF_UTIL_UUID_H_
+
+#include <decaf/util/Config.h>
+#include <decaf/lang/Comparable.h>
+#include <decaf/lang/exceptions/UnsupportedOperationException.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <apr_uuid.h>
+#include <string>
+
+namespace decaf{
+namespace util{
+
+ /**
+ * A class that represents an immutable universally unique identifier (UUID).
+ * A UUID represents a 128-bit value.
+ *
+ * There exist different variants of these global identifiers. The methods of
+ * this class are for manipulating the Leach-Salz variant, although the
+ * constructors allow the creation of any variant of UUID (described below).
+ *
+ * The layout of a variant 2 (Leach-Salz) UUID is as follows: The most
+ * significant long consists of the following unsigned fields:
+ *
+ * 0xFFFFFFFF00000000 time_low
+ * 0x00000000FFFF0000 time_mid
+ * 0x000000000000F000 version
+ * 0x0000000000000FFF time_hi
+ *
+ * The least significant long consists of the following unsigned fields:
+ *
+ * 0xC000000000000000 variant
+ * 0x3FFF000000000000 clock_seq
+ * 0x0000FFFFFFFFFFFF node
+ *
+ * The variant field contains a value which identifies the layout of the UUID.
+ * The bit layout described above is valid only for a UUID with a variant value
+ * of 2, which indicates the Leach-Salz variant.
+ *
+ * The version field holds a value that describes the type of this UUID. There
+ * are four different basic types of UUIDs: time-based, DCE security, name-based,
+ * and randomly generated UUIDs. These types have a version value of 1, 2, 3 and
+ * 4, respectively.
+ *
+ * For more information including algorithms used to create UUIDs, see the
+ * Internet-Draft UUIDs and GUIDs or the standards body definition at
+ * ISO/IEC 11578:1996.
+ */
+ class DECAF_API UUID : public lang::Comparable<UUID> {
+ private:
+
+ // APR Uuid Type
+ apr_uuid_t apr_uuid;
+
+ // Copy of the High part of the data
+ unsigned long long mostSigBits;
+
+ // Copy of the Low part of the data
+ unsigned long long leastSigBits;
+
+ // Version indicator, set when a UUID is generated
+ int uuidVersion;
+
+ public:
+
+ /**
+ * Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
+ * The UUID is generated using a cryptographically strong pseudo random
+ * number generator.
+ * @return type 4 UUID
+ */
+ static UUID randomUUID();
+
+ /**
+ * Static factory to retrieve a type 3 (name based) UUID based on the
+ * specified byte array.
+ * @param name - a byte array to be used to construct a UUID.
+ * @return type 3 UUID
+ */
+ static UUID nameUUIDFromBytes( const std::vector<char>& name );
+
+ /**
+ * Static factory to retrieve a type 3 (name based) UUID based on the
+ * specified byte array.
+ * @param name - a byte array to be used to construct a UUID.
+ * @param size - the size of the byte array, or number of bytes to use.
+ * @return type 3 UUID
+ */
+ static UUID nameUUIDFromBytes( const char* name, std::size_t size );
+
+ /**
+ * Creates a UUID from the string standard representation as described
+ * in the toString() method.
+ * @param name - a string to be used to construct a UUID.
+ * @return type 3 UUID
+ */
+ static UUID fromString( const std::string& name )
+ throw ( lang::exceptions::IllegalArgumentException );
+
+ public:
+
+ /**
+ * Constructs a new UUID using the specified data. mostSigBits is used
+ * for the most significant 64 bits of the UUID and leastSigBits becomes
+ * the least significant 64 bits of the UUID.
+ * @param mostSigBits
+ * @param leastSigBits
+ */
+ UUID( long long mostSigBits, long long leastSigBits );
+
+ virtual ~UUID();
+
+ /**
+ * Compare the given UUID to this one
+ * @param value - the UUID to compare to
+ */
+ virtual int compareTo( const UUID& value ) const;
+
+ /**
+ * Compares this UUID to the one given, returns true if they are
+ * equal
+ * @param value - the UUID to compare to.
+ * @return true if UUIDs are the same.
+ */
+ virtual bool equals( const UUID& value ) const;
+
+ /**
+ * Compares equality between this object and the one passed.
+ * @param value - the value to be compared to this one.
+ * @return true if this object is equal to the one passed.
+ */
+ virtual bool operator==( const UUID& value ) const;
+
+ /**
+ * Compares this object to another and returns true if this object
+ * is considered to be less than the one passed. This
+ * @param value - the value to be compared to this one.
+ * @return true if this object is equal to the one passed.
+ */
+ virtual bool operator<( const UUID& value ) const;
+
+ /**
+ * Returns a String object representing this UUID. UUID's are formatted
+ * as: 00112233-4455-6677-8899-AABBCCDDEEFF whose length is 36.
+ * @returns formatted string for this UUID
+ */
+ virtual std::string toString() const;
+
+ /**
+ * @returns the most significant 64 bits of this UUID's 128 bit value.
+ */
+ virtual long long getLeastSignificantBits() const;
+
+ /**
+ * @returns the most significant 64 bits of this UUID's 128 bit value.
+ */
+ virtual long long getMostSignificantBits() const;
+
+ /**
+ * The node value associated with this UUID.
+ *
+ * The 48 bit node value is constructed from the node field of this UUID.
+ * This field is intended to hold the IEEE 802 address of the machine that
+ * generated this UUID to guarantee spatial uniqueness.
+ *
+ * The node value is only meaningful in a time-based UUID, which has
+ * version type 1. If this UUID is not a time-based UUID then this method
+ * throws UnsupportedOperationException.
+ * @returns the node value of this UUID
+ * @throws UnsupportedOperationException
+ */
+ virtual long long node()
+ throw ( lang::exceptions::UnsupportedOperationException );
+
+ /**
+ * The timestamp value associated with this UUID.
+ *
+ * The 60 bit timestamp value is constructed from the time_low, time_mid,
+ * and time_hi fields of this UUID. The resulting timestamp is measured in
+ * 100-nanosecond units since midnight, October 15, 1582 UTC.
+ *
+ * The timestamp value is only meaningful in a time-based UUID, which has
+ * version type 1. If this UUID is not a time-based UUID then this method
+ * throws UnsupportedOperationException.
+ * @returns the timestamp associated with a V1 UUID
+ * @throws UnsupportedOperationException
+ */
+ virtual long long timestamp()
+ throw ( lang::exceptions::UnsupportedOperationException );
+
+ /**
+ * The clock sequence value associated with this UUID.
+ *
+ * The 14 bit clock sequence value is constructed from the clock sequence
+ * field of this UUID. The clock sequence field is used to guarantee temporal
+ * uniqueness in a time-based UUID.
+ *
+ * The clockSequence value is only meaningful in a time-based UUID, which
+ * has version type 1. If this UUID is not a time-based UUID then this
+ * method throws UnsupportedOperationException.
+ * @returns the clockSequeunce associated with a V1 UUID
+ * @throws UnsupportedOperationException
+ */
+ virtual int clockSequence()
+ throw ( lang::exceptions::UnsupportedOperationException );
+
+ /**
+ * The variant number associated with this UUID. The variant number describes
+ * the layout of the UUID. The variant number has the following meaning:
+ *
+ * * 0 Reserved for NCS backward compatibility
+ * * 2 The Leach-Salz variant (used by this class)
+ * * 6 Reserved, Microsoft Corporation backward compatibility
+ * * 7 Reserved for future definition
+ *
+ * @returns the variant associated with a V1 UUID
+ * @throws UnsupportedOperationException
+ */
+ virtual int variant()
+ throw ( lang::exceptions::UnsupportedOperationException );
+
+ /**
+ * The version number associated with this UUID. The version number describes
+ * how this UUID was generated. The version number has the following meaning:
+ *
+ * * 1 Time-based UUID
+ * * 2 DCE security UUID
+ * * 3 Name-based UUID
+ * * 4 Randomly generated UUID
+ *
+ * @returns the version associated with a V1 UUID
+ * @throws UnsupportedOperationException
+ */
+ virtual int version()
+ throw ( lang::exceptions::UnsupportedOperationException );
+
+ };
+
+}}
+
+#endif /*_DECAF_UTIL_UUID_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Concurrent.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Concurrent.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Concurrent.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Concurrent.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,63 @@
+/*
+ * 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_CONCURRENT_H_
+#define _DECAF_UTIL_CONCURRENT_CONCURRENT_H_
+
+#include <decaf/util/concurrent/Lock.h>
+
+namespace decaf{
+namespace util{
+namespace concurrent{
+
+/**
+ * The synchronized macro defines a mechanism for snycronizing
+ * a scetion of code. The macro must be passed an object that
+ * implements the Syncronizable interface.
+ *
+ * The macro works by creating a for loop that will loop exactly
+ * once, creating a Lock object that is scoped to the loop. Once
+ * the loop conpletes and exits the Lock object goes out of scope
+ * releasing the lock on object W. For added safety the if else
+ * is used because not all compiles restrict the lifetime of
+ * loop variables to the loop, they will however restrict them
+ * to the scope of the else.
+ *
+ * The macro would be used as follows.
+ *
+ * <Syncronizable> X;
+ *
+ * somefunction()
+ * {
+ * syncronized(X)
+ * {
+ * // Do something that needs syncronizing.
+ * }
+ * }
+ */
+
+#define WAIT_INFINITE 0xFFFFFFFF
+
+#define synchronized(W) \
+ if(false){} \
+ else \
+ for( decaf::util::concurrent::Lock lock_W(W); \
+ lock_W.isLocked(); lock_W.unlock() )
+
+}}}
+
+#endif /*_DECAF_UTIL_CONCURRENT_CONCURRENT_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#include "CountDownLatch.h"
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+CountDownLatch::CountDownLatch( int count )
+{
+ this->count = count;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+CountDownLatch::~CountDownLatch()
+{
+ try {
+
+ synchronized( &mutex ) {
+ mutex.notifyAll();
+ }
+ }
+ DECAF_CATCHALL_NOTHROW()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void CountDownLatch::await() throw ( lang::Exception ) {
+
+ try {
+
+ synchronized( &mutex ) {
+ if( count == 0 ){
+ return;
+ }
+
+ mutex.wait();
+ }
+ }
+ DECAF_CATCH_RETHROW( lang::Exception )
+ DECAF_CATCHALL_THROW( lang::Exception )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool CountDownLatch::await( unsigned long timeOut ) throw ( lang::Exception ) {
+ try {
+
+ synchronized( &mutex ) {
+ if( count == 0 ){
+ return true;
+ }
+
+ mutex.wait( timeOut );
+
+ return count == 0;
+ }
+
+ return true;
+ }
+ DECAF_CATCH_RETHROW( lang::Exception )
+ DECAF_CATCHALL_THROW( lang::Exception )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void CountDownLatch::countDown() {
+ try {
+
+ if( count == 0 ) {
+ return;
+ }
+
+ synchronized( &mutex ) {
+ count--;
+
+ // Signal when done.
+ if( count == 0 ){
+ mutex.notifyAll();
+ }
+ }
+ }
+ DECAF_CATCHALL_NOTHROW()
+}
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/CountDownLatch.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,84 @@
+/*
+ * 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_CONCURRENT_COUNTDOWNLATCH_H_
+#define _DECAF_CONCURRENT_COUNTDOWNLATCH_H_
+
+#include <decaf/util/concurrent/Mutex.h>
+#include <decaf/util/Config.h>
+#include <decaf/lang/Exception.h>
+
+namespace decaf{
+namespace util{
+namespace concurrent{
+
+ class DECAF_API CountDownLatch
+ {
+ private:
+
+ /**
+ * number to count down to
+ */
+ int count;
+
+ /**
+ * Mutex to protect the counts, and wait on.
+ */
+ Mutex mutex;
+
+ public:
+
+ /**
+ * Constructor
+ * @param count - number to count down from.
+ */
+ CountDownLatch( int count );
+
+ virtual ~CountDownLatch();
+
+ /**
+ * Waits for the Count to be zero, and then returns
+ * @throws CMSException
+ */
+ virtual void await() throw ( lang::Exception );
+
+ /**
+ * Waits for the Count to hit zero, or a timeout.
+ * @param timeOut - time in milliseconds to wait.
+ * @returns true if the wait made it to count zero, otherwise false
+ */
+ virtual bool await( unsigned long timeOut ) throw ( lang::Exception );
+
+ /**
+ * Counts down the latch, releasing all waiting threads when
+ * the count hits zero.
+ */
+ virtual void countDown();
+
+ /**
+ * Gets the current count
+ * @returns int count value
+ */
+ virtual int getCount() const {
+ return this->count;
+ }
+
+ };
+
+}}}
+
+#endif /*_DECAF_CONCURRENT_COUNTDOWNLATCH_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Lock.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Lock.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Lock.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Lock.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,126 @@
+/*
+ * 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_LOCK_H_
+#define _DECAF_UTIL_CONCURRENT_LOCK_H_
+
+#include <decaf/lang/Exception.h>
+#include <decaf/util/concurrent/Synchronizable.h>
+#include <decaf/util/Config.h>
+
+namespace decaf{
+namespace util{
+namespace concurrent{
+
+ /**
+ * A wrapper class around a given synchronization mechanism that
+ * provides automatic release upon destruction.
+ * @author Nathan Mittler
+ */
+ class Lock
+ {
+ private:
+
+ /**
+ * Flag to indicate whether or not this object has locked the
+ * sync object.
+ */
+ bool locked;
+
+ /**
+ * The synchronizable object to lock/unlock.
+ */
+ Synchronizable* syncObject;
+
+ public:
+
+ /**
+ * Constructor - initializes the object member and locks
+ * the object if desired.
+ * @param object The sync object to control
+ * @param intiallyLocked If true, the object will automatically
+ * be locked.
+ */
+ Lock( Synchronizable* object, const bool intiallyLocked = true )
+ {
+ try{
+ syncObject = object;
+ locked = false;
+
+ if( intiallyLocked )
+ {
+ lock();
+ }
+ }
+ DECAF_CATCH_RETHROW( lang::Exception )
+ DECAF_CATCHALL_THROW( lang::Exception )
+ }
+
+ /**
+ * Destructor - Unlocks the object if it is locked.
+ */
+ virtual ~Lock()
+ {
+ try{
+ if( locked )
+ {
+ syncObject->unlock();
+ }
+ }
+ DECAF_CATCH_RETHROW( lang::Exception )
+ DECAF_CATCHALL_THROW( lang::Exception )
+ }
+
+ /**
+ * Locks the object.
+ */
+ void lock()
+ {
+ try{
+ syncObject->lock();
+ locked = true;
+ }
+ DECAF_CATCH_RETHROW( lang::Exception )
+ DECAF_CATCHALL_THROW( lang::Exception )
+ }
+
+ /**
+ * Unlocks the object.
+ */
+ void unlock()
+ {
+ try{
+ if(locked)
+ {
+ syncObject->unlock();
+ locked = false;
+ }
+ }
+ DECAF_CATCH_RETHROW( lang::Exception )
+ DECAF_CATCHALL_THROW( lang::Exception )
+ }
+
+ /**
+ * Indicates whether or not the object is locked.
+ * @return true if the object is locked, otherwise false.
+ */
+ bool isLocked() const{ return locked; }
+ };
+
+}}}
+
+#endif // _DECAF_UTIL_CONCURRENT_LOCK_H_
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+#include <decaf/util/concurrent/Mutex.h>
+
+#include <apr_errno.h>
+#include <apr_time.h>
+
+using namespace decaf;
+using namespace decaf::internal;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+Mutex::Mutex() {
+
+ apr_thread_mutex_create( &mutex, APR_THREAD_MUTEX_NESTED, aprPool.getAprPool() );
+ this->lock_owner = 0;
+ this->lock_count = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Mutex::~Mutex() {
+
+ // Unlock the mutex.
+ unlock();
+
+ apr_thread_mutex_destroy( mutex );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Mutex::lock() throw( lang::Exception ) {
+
+ unsigned long threadId = lang::Thread::getId();
+
+ if( threadId == lock_owner ) {
+ lock_count++;
+ } else {
+ apr_thread_mutex_lock( mutex );
+ lock_owner = threadId;
+ lock_count = 1;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Mutex::unlock() throw( lang::Exception ) {
+
+ if( lock_owner == 0 ) {
+ return;
+ }
+
+ if( !isLockOwner() ) {
+ throw lang::Exception(
+ __FILE__, __LINE__,
+ "Mutex::unlock - Failed, not Lock Owner!" );
+ }
+
+ lock_count--;
+
+ if(lock_count == 0) {
+ lock_owner = 0;
+ apr_thread_mutex_unlock( mutex );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Mutex::wait() throw( lang::Exception ) {
+ // Delegate to the timed version
+ wait( WAIT_INFINITE );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Mutex::wait( unsigned long millisecs )
+ throw( lang::Exception ) {
+
+ if( !isLockOwner() ) {
+ throw lang::Exception(
+ __FILE__, __LINE__,
+ "Mutex::wait - Failed, not Lock Owner!");
+ }
+
+ // Save the current owner as we are going to unlock and release for
+ // someone else to lock on potentially. When we come back and
+ // re-lock we want to restore to the state we were in before.
+ unsigned long lock_owner = this->lock_owner;
+ unsigned long lock_count = this->lock_count;
+
+ this->lock_owner = 0;
+ this->lock_count = 0;
+
+ // Create this threads wait event
+ apr_thread_cond_t* waitEvent = NULL;
+ apr_thread_cond_create( &waitEvent, aprPool.getAprPool() );
+
+ // Store the event in the queue so that a notify can
+ // call it and wake up the thread.
+ eventQ.push_back( waitEvent );
+
+ if( millisecs != WAIT_INFINITE ) {
+ apr_interval_time_t wait = millisecs * 1000;
+ apr_thread_cond_timedwait( waitEvent, mutex, wait );
+ } else {
+ apr_thread_cond_wait( waitEvent, mutex );
+ }
+
+ // Be Sure that the event is now removed
+ eventQ.remove( waitEvent );
+
+ // Destroy our wait event now, the notify method will have removed it
+ // from the event queue.
+ apr_thread_cond_destroy( waitEvent );
+
+ // restore the owner
+ this->lock_owner = lock_owner;
+ this->lock_count = lock_count;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Mutex::notify() throw( lang::Exception )
+{
+ if( !isLockOwner() ) {
+ throw lang::Exception(
+ __FILE__, __LINE__,
+ "Mutex::Notify - Failed, not Lock Owner!" );
+ }
+
+ if( !eventQ.empty() ) {
+ apr_thread_cond_t* event = eventQ.front();
+ eventQ.remove( event );
+ apr_thread_cond_signal( event );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Mutex::notifyAll() throw( lang::Exception )
+{
+ if( !isLockOwner() ) {
+ throw lang::Exception(
+ __FILE__, __LINE__,
+ "Mutex::NotifyAll - Failed, not Lock Owner!" );
+ }
+
+ while( !eventQ.empty() ) {
+ apr_thread_cond_t* event = eventQ.front();
+ eventQ.remove( event );
+ apr_thread_cond_signal( event );
+ }
+}
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/Mutex.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,129 @@
+/*
+ * 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_CONCURRENT_MUTEX_H_
+#define _DECAF_CONCURRENT_MUTEX_H_
+
+#include <decaf/util/concurrent/Synchronizable.h>
+#include <decaf/util/concurrent/Concurrent.h>
+#include <decaf/lang/Thread.h>
+#include <decaf/util/Config.h>
+#include <decaf/internal/AprPool.h>
+
+#include <apr_thread_mutex.h>
+#include <apr_thread_cond.h>
+
+#include <list>
+#include <assert.h>
+
+namespace decaf{
+namespace util{
+namespace concurrent{
+
+ /**
+ * Creates a pthread_mutex_t object. The object is created
+ * such that successive locks from the same thread is allowed
+ * and will be successful.
+ * @see pthread_mutex_t
+ */
+ class DECAF_API Mutex : public Synchronizable {
+ private:
+
+ // Our one and only APR Pool
+ internal::AprPool aprPool;
+
+ // The mutex object.
+ apr_thread_mutex_t* mutex;
+
+ // List of waiting threads
+ std::list<apr_thread_cond_t*> eventQ;
+
+ // Lock Status Members
+ volatile unsigned long lock_owner;
+ volatile unsigned long lock_count;
+
+ public:
+
+ /**
+ * Constructor - creates and initializes the mutex.
+ */
+ Mutex();
+
+ /**
+ * Destructor - destroys the mutex object.
+ */
+ virtual ~Mutex();
+
+ /**
+ * Locks the object.
+ * @throws ActiveMQException
+ */
+ virtual void lock() throw( lang::Exception );
+
+ /**
+ * Unlocks the object.
+ * @throws ActiveMQException
+ */
+ virtual void unlock() throw( lang::Exception );
+
+ /**
+ * Waits on a signal from this object, which is generated
+ * by a call to Notify.
+ * @throws ActiveMQException
+ */
+ virtual void wait() throw( lang::Exception );
+
+ /**
+ * Waits on a signal from this object, which is generated
+ * by a call to Notify. Must have this object locked before
+ * calling. This wait will timeout after the specified time
+ * interval.
+ * @param millisecs the time in milliseconds to wait.
+ * @throws ActiveMQException
+ */
+ virtual void wait( unsigned long millisecs )
+ throw( lang::Exception );
+
+ /**
+ * Signals a waiter on this object that it can now wake
+ * up and continue.
+ * @throws ActiveMQException
+ */
+ virtual void notify() throw( lang::Exception );
+
+ /**
+ * Signals the waiters on this object that it can now wake
+ * up and continue.
+ * @throws ActiveMQException
+ */
+ virtual void notifyAll() throw( lang::Exception );
+
+ private:
+
+ /**
+ * Check if the calling thread is the Lock Owner
+ * @retun true if the caller is the lock owner
+ */
+ bool isLockOwner(){
+ return lock_owner == lang::Thread::getId();
+ }
+
+ };
+
+}}}
+
+#endif /*_DECAF_CONCURRENT_MUTEX_H_*/
Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/PooledThread.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/PooledThread.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/PooledThread.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/PooledThread.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+#include <decaf/util/concurrent/PooledThread.h>
+#include <decaf/util/concurrent/ThreadPool.h>
+#include <decaf/util/concurrent/TaskListener.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+
+#include <iostream>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+LOGDECAF_INITIALIZE(logger, PooledThread, "com.activemq.concurrent.PooledThread")
+
+////////////////////////////////////////////////////////////////////////////////
+PooledThread::PooledThread(ThreadPool* pool)
+{
+ if(pool == NULL)
+ {
+ throw IllegalArgumentException( __FILE__, __LINE__,
+ "PooledThread::PooledThread");
+ }
+
+ busy = false;
+ done = false;
+
+ listener = NULL;
+
+ // Store our Pool.
+ this->pool = pool;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+PooledThread::~PooledThread()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PooledThread::run(void)
+{
+ ThreadPool::Task task;
+
+ try
+ {
+ while(!done)
+ {
+ //LOGCMS_DEBUG(logger, "PooledThread::run - Entering deQ");
+
+ // Blocks until there something to be done
+ task = pool->deQueueTask();
+
+ //LOGCMS_DEBUG(logger, "PooledThread::run - Exited deQ");
+
+ // Check if the Done Flag is set, in case it happened while we
+ // were waiting for a task
+ if(done)
+ {
+ break;
+ }
+
+ // If we got here and the runnable was null then something
+ // bad must have happened. Throw an Exception and bail.
+ if(!task.first)
+ {
+ throw Exception( __FILE__, __LINE__,
+ "PooledThread::run - Retrieive NULL task from Pool.");
+ }
+
+ // Got some work to do, so set flag to busy
+ busy = true;
+
+ // Inform a listener that we are going to start
+ if(listener)
+ {
+ /*LOGCMS_DEBUG(logger,
+ "PooledThread::run - Inform Listener we are starting");*/
+ listener->onTaskStarted(this);
+ }
+
+ // Perform the work
+ task.first->run();
+
+ /*LOGCMS_DEBUG(logger,
+ "PooledThread::run - Inform Task Listener we are done");*/
+
+ // Notify the Task listener that we are done
+ task.second->onTaskComplete(task.first);
+
+ // Inform a listener that we are going to stop and wait
+ // for a new task
+ if(listener)
+ {
+ /*LOGCMS_DEBUG(logger,
+ "PooledThread::run - Inform Listener we are done");*/
+ listener->onTaskCompleted(this);
+ }
+
+ // Set flag to inactive, we will wait for work
+ busy = false;
+ }
+ }
+ catch( Exception& ex )
+ {
+ ex.setMark( __FILE__, __LINE__ );
+
+ // Notify the Task owner
+ if(task.first && task.second)
+ {
+ task.second->onTaskException(task.first, ex);
+ }
+
+ busy = false;
+
+ // Notify the PooledThreadListener
+ if(listener)
+ {
+ listener->onTaskException(this, ex);
+ }
+ }
+ catch(...)
+ {
+ Exception ex(
+ __FILE__, __LINE__,
+ "PooledThread::run - Caught Unknown Exception");
+
+ // Notify the Task owner
+ if(task.first && task.second)
+ {
+ task.second->onTaskException(task.first, ex);
+ }
+
+ busy = false;
+
+ // Notify the PooledThreadListener
+ if(listener)
+ {
+ listener->onTaskException(this, ex);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PooledThread::stop(void) throw ( Exception )
+{
+ done = true;
+}