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/10/04 17:38:02 UTC

svn commit: r701652 - in /activemq/activemq-cpp/trunk/src: main/decaf/util/concurrent/TimeUnit.cpp main/decaf/util/concurrent/TimeUnit.h test/decaf/util/concurrent/TimeUnitTest.cpp test/decaf/util/concurrent/TimeUnitTest.h

Author: tabish
Date: Sat Oct  4 08:38:01 2008
New Revision: 701652

URL: http://svn.apache.org/viewvc?rev=701652&view=rev
Log:
Adding Start of the TimeUnit class.

Added:
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.cpp
    activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.h
    activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.cpp
    activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.h

Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.cpp?rev=701652&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.cpp Sat Oct  4 08:38:01 2008
@@ -0,0 +1,147 @@
+/*
+ * 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 "TimeUnit.h"
+
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Thread.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+const TimeUnit TimeUnit::NANOSECONDS( 0, "NANOSECONDS" );
+const TimeUnit TimeUnit::MICROSECONDS( 1, "MICROSECONDS" );
+const TimeUnit TimeUnit::MILLISECONDS( 2, "MILLISEONDS" );
+const TimeUnit TimeUnit::SECONDS( 3, "SECONDS" );
+const TimeUnit TimeUnit::MINUTES( 4, "MINUTES" );
+const TimeUnit TimeUnit::HOURS( 5, "HOURS" );
+const TimeUnit TimeUnit::DAYS( 6, "DAYS" );
+
+////////////////////////////////////////////////////////////////////////////////
+const long long TimeUnit::multipliers[] = {
+    1,
+    1000LL,
+    1000LL * 1000LL,
+    1000LL * 1000LL * 1000LL,
+    1000LL * 1000LL * 1000LL * 60LL,
+    1000LL * 1000LL * 1000LL * 60LL * 60LL,
+    1000LL * 1000LL * 1000LL * 60LL * 60LL * 24LL,
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Lookup table to check saturation.  Note that because we are
+// dividing these down, we don't have to deal with asymmetry of
+// MIN/MAX values.
+//
+const long long TimeUnit::overflows[] = {
+    0, // unused
+    Long::MAX_VALUE / 1000LL,
+    Long::MAX_VALUE / ( 1000LL * 1000LL ),
+    Long::MAX_VALUE / ( 1000LL * 1000LL * 1000LL ),
+    Long::MAX_VALUE / ( 1000LL * 1000LL * 1000LL * 60LL ),
+    Long::MAX_VALUE / ( 1000LL * 1000LL * 1000LL * 60LL * 60LL ),
+    Long::MAX_VALUE / ( 1000LL * 1000LL * 1000LL * 60LL * 60LL * 24LL )
+};
+
+////////////////////////////////////////////////////////////////////////////////
+TimeUnit::TimeUnit( int index, const std::string& name ) {
+    this->index = index;
+    this->name = name;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long TimeUnit::convert( long long sourceDuration, const TimeUnit& sourceUnit ) const {
+    return this->doConvert( sourceUnit.index - this->index, sourceDuration );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long TimeUnit::doConvert( long long delta, long long duration ) const {
+
+    if( delta == 0 ) {
+        return duration;
+    } else if( delta < 0 ) {
+        return duration / multipliers[-delta];
+    } else if( duration > overflows[delta] ) {
+        return Long::MAX_VALUE;
+    } else if( duration < -overflows[delta] ) {
+        return Long::MIN_VALUE;
+    }
+
+    return duration * multipliers[delta];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int TimeUnit::excessNanos( long long time, long long ms ) const {
+
+    if( *this == NANOSECONDS ) {
+        return (int)( time - ( ms * 1000 * 1000 ) );
+    } else if( *this == MICROSECONDS ) {
+        return (int)( ( time * 1000 ) - ( ms * 1000 * 1000 ) );
+    }
+
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnit::sleep( long long timeout ) const {
+    if( timeout > 0 ) {
+        long long ms = toMillis( timeout );
+        int ns = excessNanos( timeout, ms );
+        Thread::sleep( ms );
+        // TODO - Only have a wait for Milliseconds currently.
+        //Thread::sleep( ms, ns );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnit::timedWait( Synchronizable* obj, long long timeout ) const {
+    if( timeout > 0 ) {
+        long ms = toMillis( timeout );
+        int ns = excessNanos( timeout, ms );
+        obj->wait( ms );
+        // TODO - Only have a wait for Milliseconds currently.
+        //obj.wait( ms, ns );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string TimeUnit::toString() const {
+    return this->name;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int TimeUnit::compareTo( const TimeUnit& value ) const {
+    return index == value.index ? 0 : ( index > value.index ? 1 : -1 );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool TimeUnit::equals( const TimeUnit& value ) const {
+    return index == value.index;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool TimeUnit::operator==( const TimeUnit& value ) const {
+    return index == value.index;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool TimeUnit::operator<( const TimeUnit& value ) const {
+    return this->compareTo( value ) == -1;
+}

Added: activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.h?rev=701652&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/util/concurrent/TimeUnit.h Sat Oct  4 08:38:01 2008
@@ -0,0 +1,289 @@
+/*
+ * 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_TIMEUNIT_H_
+#define _DECAF_UTIL_CONCURRENT_TIMEUNIT_H_
+
+#include <string>
+#include <decaf/lang/Comparable.h>
+#include <decaf/util/concurrent/Synchronizable.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+
+    /**
+     * A TimeUnit represents time durations at a given unit of granularity and
+     * provides utility methods to convert across units, and to perform timing
+     * and delay operations in these units. A TimeUnit does not maintain time
+     * information, but only helps organize and use time representations that
+     * may be maintained separately across various contexts. A nanosecond is
+     * defined as one thousandth of a microsecond, a microsecond as one thousandth
+     * of a millisecond, a millisecond as one thousandth of a second, a minute as
+     * sixty seconds, an hour as sixty minutes, and a day as twenty four hours.
+     *
+     * A TimeUnit is mainly used to inform time-based methods how a given timing
+     * parameter should be interpreted. For example, the following code will timeout
+     * in 50 milliseconds if the lock is not available:
+     *
+     *  Lock lock = ...;
+     *  if ( lock.tryLock( 50, TimeUnit.MILLISECONDS ) ) ...
+     *
+     * while this code will timeout in 50 seconds:
+     *
+     *  Lock lock = ...;
+     *  if ( lock.tryLock( 50, TimeUnit.SECONDS ) ) ...
+     *
+     * Note however, that there is no guarantee that a particular timeout implementation
+     * will be able to notice the passage of time at the same granularity as the given
+     * TimeUnit.
+     */
+    class TimeUnit : public decaf::lang::Comparable<TimeUnit> {
+    private:
+
+        /** This TimeUnit's index */
+        int index;
+
+        /** Array of Time Unit multipliers */
+        static const long long multipliers[];
+
+        /**
+         * Lookup table to check saturation.  Note that because we are
+         * dividing these down, we don't have to deal with asymmetry of
+         * MIN/MAX values.
+         */
+        static const long long overflows[];
+
+        /**
+         * Name of the Unit being represented.
+         */
+        std::string name;
+
+    public:
+
+        /**
+         * The Actual TimeUnit enumerations
+         */
+        static const TimeUnit NANOSECONDS;
+        static const TimeUnit MICROSECONDS;
+        static const TimeUnit MILLISECONDS;
+        static const TimeUnit SECONDS;
+        static const TimeUnit MINUTES;
+        static const TimeUnit HOURS;
+        static const TimeUnit DAYS;
+
+    protected:
+
+        /**
+         * Hidden Constructor, this class can not be instantiated directly.
+         * @param index - Index into the Time Unit set.
+         * @param name - Name of the unit type being represented.
+         */
+        TimeUnit( int index, const std::string& name );
+
+    public:
+
+        virtual ~TimeUnit() {}
+
+        /**
+         * Convert the given time duration in the given unit to this unit. Conversions
+         * from finer to coarser granularities truncate, so lose precision. For example
+         * converting 999 milliseconds to seconds results in 0. Conversions from coarser
+         * to finer granularities with arguments that would numerically overflow saturate
+         * to Long.MIN_VALUE if negative or Long.MAX_VALUE if positive.
+         * <p>
+         * For example, to convert 10 minutes to milliseconds, use:
+         * TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)
+         * <p>
+         * @param sourceDuration - Duration value to convert.
+         * @param sourceUnit - Unit type of the source duration.
+         * @returns the converted duration in this unit, or Long.MIN_VALUE if conversion
+         * would negatively overflow, or Long.MAX_VALUE if it would positively overflow.
+         */
+        long long convert( long long sourceDuration, const TimeUnit& sourceUnit ) const;
+
+        /**
+         * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
+         * @param duration the duration
+         * @return the converted duration,
+         * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+         * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+         * @see #convert
+         */
+        long long toNanos( long long duration ) const {
+            return doConvert( index, duration );
+        }
+
+        /**
+         * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
+         * @param duration the duration
+         * @return the converted duration,
+         * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+         * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+         * @see #convert
+         */
+        long long toMicros( long long duration ) const {
+            return doConvert( index - MICROSECONDS.index, duration );
+        }
+
+        /**
+         * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
+         * @param duration the duration
+         * @return the converted duration,
+         * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+         * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+         * @see #convert
+         */
+        long long toMillis( long long duration ) const {
+            return doConvert( index - MILLISECONDS.index, duration );
+        }
+
+        /**
+         * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
+         * @param duration the duration
+         * @return the converted duration.
+         * @see #convert
+         */
+        long long toSeconds( long long duration ) const {
+            return doConvert( index - SECONDS.index, duration );
+        }
+
+        /**
+         * Perform a timed <tt>Object.wait</tt> using this time unit.
+         * This is a convenience method that converts timeout arguments
+         * into the form required by the <tt>Object.wait</tt> method.
+         *
+         * <p>For example, you could implement a blocking <tt>poll</tt>
+         * method (see {@link BlockingQueue#poll BlockingQueue.poll})
+         * using:
+         *
+         * <pre>  public synchronized  Object poll(long timeout, TimeUnit unit) throws InterruptedException {
+         *    while (empty) {
+         *      unit.timedWait(this, timeout);
+         *      ...
+         *    }
+         *  }</pre>
+         *
+         * @param obj the object to wait on
+         * @param timeout the maximum time to wait.
+         * @throws InterruptedException if interrupted while waiting.
+         * @see Synchronizable#wait( long, int )
+         */
+        void timedWait( Synchronizable* obj, long long timeout ) const;
+
+// TODO - Can't join Threads with a Timeout currently.
+//        /**
+//         * Perform a timed <tt>Thread.join</tt> using this time unit.
+//         * This is a convenience method that converts time arguments into the
+//         * form required by the <tt>Thread.join</tt> method.
+//         * @param thread the thread to wait for
+//         * @param timeout the maximum time to wait
+//         * @throws InterruptedException if interrupted while waiting.
+//         * @see Thread#join(long, int)
+//         */
+//        void timedJoin(Thread thread, long timeout)
+//            throws InterruptedException {
+//            if (timeout > 0) {
+//                long ms = toMillis(timeout);
+//                int ns = excessNanos(timeout, ms);
+//                thread.join(ms, ns);
+//            }
+//        }
+
+        /**
+         * Perform a <tt>Thread.sleep</tt> using this unit.
+         * This is a convenience method that converts time arguments into the
+         * form required by the <tt>Thread.sleep</tt> method.
+         * @param timeout the minimum time to sleep
+         * @see Thread#sleep
+         */
+        void sleep( long long timeout ) const;
+
+        /**
+         * Converts the TimeUnit type to the Name of the TimeUnit.
+         * @return String name of the TimeUnit
+         */
+        virtual std::string toString() const;
+
+    public:
+
+        /**
+         * Compares this object with the specified object for order. Returns a
+         * negative integer, zero, or a positive integer as this object is less
+         * than, equal to, or greater than the specified object.
+         *
+         * In the foregoing description, the notation sgn(expression) designates
+         * the mathematical signum function, which is defined to return one of
+         * -1, 0, or 1 according to whether the value of expression  is negative,
+         * zero or positive. The implementor must ensure sgn(x.compareTo(y)) ==
+         * -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y)
+         * must throw an exception iff y.compareTo(x) throws an exception.)
+         *
+         * The implementor must also ensure that the relation is transitive:
+         * (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
+         *
+         * Finally, the implementer must ensure that x.compareTo(y)==0 implies
+         * that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
+         *
+         * It is strongly recommended, but not strictly required that
+         * (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class
+         * that implements the Comparable interface and violates this condition
+         * should clearly indicate this fact. The recommended language is
+         * "Note: this class has a natural ordering that is inconsistent with
+         * equals."
+         * @param value - the Object to be compared.
+         * @returns a negative integer, zero, or a positive integer as this
+         * object is less than, equal to, or greater than the specified object.
+         */
+        virtual int compareTo( const TimeUnit& value ) const;
+
+        /**
+         * @return true if this value is considered equal to the passed value.
+         */
+        virtual bool equals( const TimeUnit& 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 TimeUnit& 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 TimeUnit& value ) const;
+
+    private:
+
+        /* Perform the actual conversion */
+        long long doConvert( long long delta, long long duration ) const;
+
+        /*
+         * Utility method to compute the excess-nanosecond argument to
+         * wait, sleep, join.
+         */
+        int excessNanos( long long time, long long ms ) const;
+
+    };
+
+}}}
+
+#endif /*_DECAF_UTIL_CONCURRENT_TIMEUNIT_H_*/

Added: activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.cpp?rev=701652&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.cpp (added)
+++ activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.cpp Sat Oct  4 08:38:01 2008
@@ -0,0 +1,142 @@
+/*
+ * 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 "TimeUnitTest.h"
+
+#include <string>
+#include <decaf/util/concurrent/TimeUnit.h>
+#include <decaf/util/concurrent/Mutex.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/System.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testConvert() {
+
+    for( long long t = 0; t < 10; ++t ) {
+
+        CPPUNIT_ASSERT( t == TimeUnit::SECONDS.convert( t, TimeUnit::SECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::SECONDS.convert( 1000 * t, TimeUnit::MILLISECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::SECONDS.convert( 1000000 * t, TimeUnit::MICROSECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::SECONDS.convert( 1000000000 * t, TimeUnit::NANOSECONDS ) );
+        CPPUNIT_ASSERT( 1000 * t == TimeUnit::MILLISECONDS.convert( t, TimeUnit::SECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MILLISECONDS.convert( t, TimeUnit::MILLISECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MILLISECONDS.convert( 1000 * t, TimeUnit::MICROSECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MILLISECONDS.convert( 1000000 * t, TimeUnit::NANOSECONDS ) );
+        CPPUNIT_ASSERT( 1000000 * t == TimeUnit::MICROSECONDS.convert( t, TimeUnit::SECONDS ) );
+        CPPUNIT_ASSERT( 1000 * t == TimeUnit::MICROSECONDS.convert( t, TimeUnit::MILLISECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MICROSECONDS.convert( t, TimeUnit::MICROSECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MICROSECONDS.convert( 1000 * t, TimeUnit::NANOSECONDS ) );
+        CPPUNIT_ASSERT( 1000000000 * t == TimeUnit::NANOSECONDS.convert( t, TimeUnit::SECONDS ) );
+        CPPUNIT_ASSERT( 1000000 * t == TimeUnit::NANOSECONDS.convert( t, TimeUnit::MILLISECONDS ) );
+        CPPUNIT_ASSERT( 1000 * t == TimeUnit::NANOSECONDS.convert( t, TimeUnit::MICROSECONDS ) );
+        CPPUNIT_ASSERT( t == TimeUnit::NANOSECONDS.convert( t, TimeUnit::NANOSECONDS ) );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testToNanos() {
+    for( long long t = 0; t < 10; ++t ) {
+        CPPUNIT_ASSERT( 1000000000 * t == TimeUnit::SECONDS.toNanos( t ) );
+
+        CPPUNIT_ASSERT( 1000000 * t == TimeUnit::MILLISECONDS.toNanos( t ) );
+        CPPUNIT_ASSERT( 1000 * t == TimeUnit::MICROSECONDS.toNanos( t ) );
+        CPPUNIT_ASSERT( t == TimeUnit::NANOSECONDS.toNanos( t ) );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testToMicros() {
+
+    for( long long t = 0; t < 10; ++t ) {
+        CPPUNIT_ASSERT( 1000000 * t == TimeUnit::SECONDS.toMicros( t ) );
+        CPPUNIT_ASSERT( 1000 * t == TimeUnit::MILLISECONDS.toMicros( t ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MICROSECONDS.toMicros( t ) );
+        CPPUNIT_ASSERT( t == TimeUnit::NANOSECONDS.toMicros( t * 1000 ) );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testToMillis() {
+    for( long long t = 0; t < 10; ++t ) {
+
+        CPPUNIT_ASSERT( 1000 * t == TimeUnit::SECONDS.toMillis( t ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MILLISECONDS.toMillis( t ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MICROSECONDS.toMillis( t * 1000 ) );
+        CPPUNIT_ASSERT( t == TimeUnit::NANOSECONDS.toMillis( t * 1000000 ) );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testToSeconds() {
+    for( long long t = 0; t < 10; ++t ) {
+
+        CPPUNIT_ASSERT( t == TimeUnit::SECONDS.toSeconds( t ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MILLISECONDS.toSeconds( t * 1000 ) );
+        CPPUNIT_ASSERT( t == TimeUnit::MICROSECONDS.toSeconds( t * 1000000 ) );
+        CPPUNIT_ASSERT( t == TimeUnit::NANOSECONDS.toSeconds( t * 1000000000 ) );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testConvertSaturate() {
+    CPPUNIT_ASSERT( Long::MAX_VALUE ==
+        TimeUnit::NANOSECONDS.convert( Long::MAX_VALUE / 2, TimeUnit::SECONDS ) );
+    CPPUNIT_ASSERT( Long::MIN_VALUE ==
+        TimeUnit::NANOSECONDS.convert( -Long::MAX_VALUE / 4, TimeUnit::SECONDS ) );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testToNanosSaturate() {
+    CPPUNIT_ASSERT( Long::MAX_VALUE ==
+        TimeUnit::MILLISECONDS.toNanos( Long::MAX_VALUE / 2 ) );
+    CPPUNIT_ASSERT( Long::MIN_VALUE ==
+        TimeUnit::MILLISECONDS.toNanos( -Long::MAX_VALUE / 3 ) );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testToString() {
+    std::string s = TimeUnit::SECONDS.toString();
+    CPPUNIT_ASSERT( s.find_first_of( "ECOND" ) >= (std::size_t)0 );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testTimedWait() {
+
+    Mutex o;
+
+    long long now = System::currentTimeMillis();
+    synchronized( &o ) {
+        TimeUnit::SECONDS.timedWait( &o, 1 );
+    }
+    long long later = System::currentTimeMillis();
+
+    CPPUNIT_ASSERT( later - now + 10 >= TimeUnit::SECONDS.toMillis( 1 ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+void TimeUnitTest::testSleep() {
+
+    long long now = System::currentTimeMillis();
+    TimeUnit::SECONDS.sleep( 1 );
+    long long later = System::currentTimeMillis();
+    CPPUNIT_ASSERT( later - now + 10 >= TimeUnit::SECONDS.toMillis( 1 ) );
+}

Added: activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.h?rev=701652&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.h (added)
+++ activemq/activemq-cpp/trunk/src/test/decaf/util/concurrent/TimeUnitTest.h Sat Oct  4 08:38:01 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_TIMEUNITTEST_H_
+#define _DECAF_UTIL_CONCURRENT_TIMEUNITTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+
+    class TimeUnitTest : public CppUnit::TestFixture {
+
+        CPPUNIT_TEST_SUITE( TimeUnitTest );
+        CPPUNIT_TEST( testConvert );
+        CPPUNIT_TEST( testToNanos );
+        CPPUNIT_TEST( testToMicros );
+        CPPUNIT_TEST( testToMillis );
+        CPPUNIT_TEST( testToSeconds );
+        CPPUNIT_TEST( testConvertSaturate );
+        CPPUNIT_TEST( testToNanosSaturate );
+        CPPUNIT_TEST( testToString );
+        CPPUNIT_TEST( testTimedWait );
+        CPPUNIT_TEST( testSleep );
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        TimeUnitTest() {}
+        virtual ~TimeUnitTest() {}
+
+        void testConvert();
+        void testToNanos();
+        void testToMicros();
+        void testToMillis();
+        void testToSeconds();
+        void testConvertSaturate();
+        void testToNanosSaturate();
+        void testToString();
+        void testTimedWait();
+        void testSleep();
+
+    };
+
+}}}
+
+#endif /*_DECAF_UTIL_CONCURRENT_TIMEUNITTEST_H_ */