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;
+}