activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r1345326 [1/2] - in /activemq/activemq-cpp/trunk/activemq-cpp/src: main/ main/decaf/internal/util/concurrent/ main/decaf/lang/ main/decaf/util/ main/decaf/util/concurrent/locks/ test/ test/decaf/lang/ test/decaf/util/concurrent/locks/
Date Fri, 01 Jun 2012 20:00:05 GMT
Author: tabish
Date: Fri Jun  1 20:00:04 2012
New Revision: 1345326

URL: http://svn.apache.org/viewvc?rev=1345326&view=rev
Log:
Implement the ThreadLocal class and underlying structure to support cross platform thread locals

Added:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.cpp   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.h   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.cpp   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.h   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.cpp   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.h   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.h   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.cpp   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.h   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/ReentrantReadWriteLockTest.cpp   (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/ReentrantReadWriteLockTest.h   (with props)
Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Config.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/Makefile.am
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadTest.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/testRegistry.cpp

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am Fri Jun  1 20:00:04 2012
@@ -329,6 +329,7 @@ cc_sources = \
     decaf/internal/util/TimerTaskHeap.cpp \
     decaf/internal/util/concurrent/ExecutorsSupport.cpp \
     decaf/internal/util/concurrent/SynchronizableImpl.cpp \
+    decaf/internal/util/concurrent/ThreadLocalImpl.cpp \
     decaf/internal/util/concurrent/Threading.cpp \
     decaf/internal/util/concurrent/unix/Atomics.cpp \
     decaf/internal/util/concurrent/unix/PlatformThread.cpp \
@@ -377,6 +378,8 @@ cc_sources = \
     decaf/lang/System.cpp \
     decaf/lang/Thread.cpp \
     decaf/lang/ThreadGroup.cpp \
+    decaf/lang/ThreadLocal.cpp \
+    decaf/lang/Types.cpp \
     decaf/net/DatagramPacket.cpp \
     decaf/net/Inet4Address.cpp \
     decaf/net/Inet6Address.cpp \
@@ -475,6 +478,7 @@ cc_sources = \
     decaf/util/concurrent/locks/AbstractQueuedSynchronizer.cpp \
     decaf/util/concurrent/locks/LockSupport.cpp \
     decaf/util/concurrent/locks/ReentrantLock.cpp \
+    decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp \
     decaf/util/logging/ConsoleHandler.cpp \
     decaf/util/logging/ErrorManager.cpp \
     decaf/util/logging/Formatter.cpp \
@@ -860,6 +864,7 @@ h_sources = \
     decaf/internal/util/concurrent/ExecutorsSupport.h \
     decaf/internal/util/concurrent/PlatformThread.h \
     decaf/internal/util/concurrent/SynchronizableImpl.h \
+    decaf/internal/util/concurrent/ThreadLocalImpl.h \
     decaf/internal/util/concurrent/Threading.h \
     decaf/internal/util/concurrent/ThreadingTypes.h \
     decaf/internal/util/concurrent/TransferQueue.h \
@@ -928,7 +933,9 @@ h_sources = \
     decaf/lang/System.h \
     decaf/lang/Thread.h \
     decaf/lang/ThreadGroup.h \
+    decaf/lang/ThreadLocal.h \
     decaf/lang/Throwable.h \
+    decaf/lang/Types.h \
     decaf/lang/exceptions/ClassCastException.h \
     decaf/lang/exceptions/ExceptionDefines.h \
     decaf/lang/exceptions/IllegalArgumentException.h \
@@ -1087,6 +1094,7 @@ h_sources = \
     decaf/util/concurrent/locks/LockSupport.h \
     decaf/util/concurrent/locks/ReadWriteLock.h \
     decaf/util/concurrent/locks/ReentrantLock.h \
+    decaf/util/concurrent/locks/ReentrantReadWriteLock.h \
     decaf/util/logging/ConsoleHandler.h \
     decaf/util/logging/ErrorManager.h \
     decaf/util/logging/Filter.h \

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.cpp?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.cpp Fri Jun  1 20:00:04 2012
@@ -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.
+ */
+
+#include "ThreadLocalImpl.h"
+
+#include <decaf/internal/util/concurrent/Threading.h>
+
+#include <decaf/lang/exceptions/RuntimeException.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::internal;
+using namespace decaf::internal::util;
+using namespace decaf::internal::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+ThreadLocalImpl::ThreadLocalImpl() : tlsKey(0) {
+    tlsKey = Threading::createThreadLocalSlot(this);
+
+    if (tlsKey < 0) {
+        throw RuntimeException(
+            __FILE__, __LINE__, "Thread Local storage limit reached.");
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ThreadLocalImpl::~ThreadLocalImpl() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void* ThreadLocalImpl::getRawValue() const {
+    return Threading::getThreadLocalValue(this->tlsKey);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadLocalImpl::setRawValue(void* value) {
+    void* oldValue = this->getRawValue();
+    Threading::setThreadLocalValue(this->tlsKey, value);
+
+    if (oldValue != NULL) {
+        doDelete(oldValue);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadLocalImpl::removeAll() {
+    Threading::destoryThreadLocalSlot(this->tlsKey);
+}

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.h?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.h Fri Jun  1 20:00:04 2012
@@ -0,0 +1,82 @@
+/*
+ * 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_INTERNAL_UTIL_CONCURRENT_THREADLOCALIMPL_H_
+#define _DECAF_INTERNAL_UTIL_CONCURRENT_THREADLOCALIMPL_H_
+
+#include <decaf/util/Config.h>
+
+namespace decaf {
+namespace internal {
+namespace util {
+namespace concurrent {
+
+    class DECAF_API ThreadLocalImpl {
+    private:
+
+        int tlsKey;
+
+    public:
+
+        ThreadLocalImpl();
+
+        virtual ~ThreadLocalImpl();
+
+        /**
+         * Returns the current threads assigned value, but retains ownership
+         * to this value unless the remove method is subsequently called.
+         *
+         * @returns the currently held value for this thread.
+         */
+        void* getRawValue() const;
+
+        /**
+         * Sets the raw void* value for the current thread.  If the value
+         * is NULL and the old value is non-NULL then the library will call
+         * the doDelete method to destroy the previous value.
+         *
+         * @param value
+         *      Pointer to the value to be stored for the current thread or NULL.
+         */
+        void setRawValue(void* value);
+
+        /**
+         * Removes from all threads any allocated data stored for this ThreadLocal
+         * instance.  Subclasses should call this method in their destructor to ensure
+         * that all the values that are stored in each thread can be deallocated using
+         * their custom doDelete method.
+         */
+        void removeAll();
+
+    public:
+
+        /**
+         * Called to destroy the value held by the current thread or by the
+         * library on shutdown if there are still ThreadLocalImpl instances that
+         * have assigned TLS slots.  Its up to the implementor if this interface
+         * to ensure that the value held in the void* is cleaned up correctly.
+         *
+         * @param value
+         *      The value to be destroyed for the current thread.
+         */
+        virtual void doDelete(void* value) = 0;
+
+    };
+
+}}}}
+
+#endif /* _DECAF_INTERNAL_UTIL_CONCURRENT_THREADLOCALIMPL_H_ */

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/ThreadLocalImpl.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.cpp?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.cpp Fri Jun  1 20:00:04 2012
@@ -23,11 +23,15 @@
 #include <decaf/lang/exceptions/NullPointerException.h>
 #include <decaf/util/concurrent/Executors.h>
 
+#include <decaf/internal/util/concurrent/ThreadLocalImpl.h>
 #include <decaf/internal/util/concurrent/ThreadingTypes.h>
 #include <decaf/internal/util/concurrent/PlatformThread.h>
 #include <decaf/internal/util/concurrent/Atomics.h>
 #include <decaf/util/concurrent/atomic/AtomicInteger.h>
 
+#include <vector>
+#include <list>
+
 using namespace decaf;
 using namespace decaf::lang;
 using namespace decaf::lang::exceptions;
@@ -106,18 +110,22 @@ namespace {
         decaf_tls_key selfKey;
         decaf_mutex_t globalLock;
         decaf_mutex_t tlsLock;
+        std::vector<ThreadLocalImpl*> tlsSlots;
         std::vector<Thread*> osThreads;
         decaf_thread_t mainThread;
+        std::list<ThreadHandle*> activeThreads;
         std::vector<int> priorityMapping;
         AtomicInteger osThreadId;
         MonitorPool* monitors;
     };
 
+    #define MAX_TLS_SLOTS 128
     #define MONITOR_POOL_BLOCK_SIZE 64
 
     ThreadingLibrary* library = NULL;
 
     // ------------------------ Forward Declare All Utility Methds ----------------------- //
+    void threadExitTlsCleanup(ThreadHandle* thread);
     void unblockThreads(ThreadHandle* monitor);
     void createThreadInstance(ThreadHandle* thread, long long stackSize, int priority,
                               bool suspended, threadingTask threadMain, void* threadArg);
@@ -159,7 +167,12 @@ namespace {
         PlatformThread::setTlsValue(library->threadKey, NULL);
         PlatformThread::setTlsValue(library->selfKey, NULL);
 
-        // TODO tls_finalize (self);
+        // Ensure all of this thread's local values are purged.
+        threadExitTlsCleanup(self);
+
+        // Remove from the set of active threads under global lock, threads that
+        // are iterating on global state need a stable list.
+        library->activeThreads.remove(self);
 
         PlatformThread::unlockMutex(self->mutex);
         PlatformThread::unlockMutex(library->globalLock);
@@ -198,6 +211,10 @@ namespace {
             PLATFORM_THREAD_RETURN()
         }
 
+        PlatformThread::lockMutex(library->globalLock);
+        library->activeThreads.push_back(thread);
+        PlatformThread::unlockMutex(library->globalLock);
+
         thread->state = Thread::RUNNABLE;
 
         thread->threadMain(thread->threadArg);
@@ -388,6 +405,24 @@ namespace {
         return result;
     }
 
+    void threadExitTlsCleanup(ThreadHandle* thread) {
+        for (int index = 0; index < MAX_TLS_SLOTS; ++index) {
+            if (thread->tls[index] != NULL) {
+                ThreadLocalImpl* handler = NULL;
+                void *value = NULL;
+
+                PlatformThread::lockMutex(library->tlsLock);
+                value = thread->tls[index];
+                handler = library->tlsSlots[index];
+                PlatformThread::unlockMutex(library->tlsLock);
+
+                if (value != NULL) {
+                    handler->doDelete(value);
+                }
+            }
+        }
+    }
+
     void unblockThreads(ThreadHandle* queueHead) {
         ThreadHandle* current = NULL;
         ThreadHandle* next = NULL;
@@ -740,6 +775,8 @@ void Threading::initialize() {
     library->monitors->head = batchAllocateMonitors();
     library->monitors->count = MONITOR_POOL_BLOCK_SIZE;
 
+    library->tlsSlots.resize(MAX_TLS_SLOTS);
+
     // We mark the thread where Decaf's Init routine is called from as our Main Thread.
     library->mainThread = PlatformThread::getCurrentThread();
 
@@ -838,7 +875,9 @@ ThreadHandle* Threading::attachToCurrent
 
     // Store the Thread that wraps this OS thread for later deletion since
     // no other owners exist.
+    PlatformThread::lockMutex(library->globalLock);
     library->osThreads.push_back(osThread.release());
+    PlatformThread::unlockMutex(library->globalLock);
 
     return thread.release();
 }
@@ -1444,3 +1483,77 @@ bool Threading::monitorTryEnterUsingThre
 
     return false;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+int Threading::createThreadLocalSlot(ThreadLocalImpl* threadLocal) {
+
+    if (threadLocal == NULL) {
+        throw NullPointerException(
+            __FILE__, __LINE__, "Null ThreadLocalImpl Pointer Passed." );
+    }
+
+    int index;
+
+    PlatformThread::lockMutex(library->tlsLock);
+
+    for (index = 0; index < MAX_TLS_SLOTS; index++) {
+        if (library->tlsSlots[index] == NULL) {
+            library->tlsSlots[index] = threadLocal;
+            break;
+        }
+    }
+
+    PlatformThread::unlockMutex(library->tlsLock);
+
+    return index < MAX_TLS_SLOTS ? index : -1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void* Threading::getThreadLocalValue(int slot) {
+    ThreadHandle* thisThread = getCurrentThreadHandle();
+    return thisThread->tls[slot];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Threading::setThreadLocalValue(int slot, void* value) {
+    ThreadHandle* thisThread = getCurrentThreadHandle();
+    thisThread->tls[slot] = value;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Threading::destoryThreadLocalSlot(int slot) {
+
+    ThreadHandle* current = NULL;
+    ThreadLocalImpl* local = library->tlsSlots[slot];
+
+    // Must lock globally so that no thread can terminate and call its own
+    // tls cleanup and our list of thread remains stable.
+    PlatformThread::lockMutex(library->globalLock);
+
+    std::list<ThreadHandle*>::const_iterator iter = library->activeThreads.begin();
+    while (iter != library->activeThreads.end()) {
+        current = *(iter++);
+        void* value = current->tls[slot];
+        if (value != NULL) {
+            local->doDelete(value);
+            current->tls[slot] = NULL;
+        }
+    }
+
+    std::vector<decaf::lang::Thread*>::const_iterator osIter = library->osThreads.begin();
+    while (osIter != library->osThreads.end()) {
+        current = (*(osIter++))->getHandle();
+        void* value = current->tls[slot];
+        if (value != NULL) {
+            local->doDelete(value);
+            current->tls[slot] = NULL;
+        }
+    }
+
+    PlatformThread::unlockMutex(library->globalLock);
+
+    // Return the slot to the pool under lock so that a taker waits.
+    PlatformThread::lockMutex(library->tlsLock);
+    library->tlsSlots[slot] = NULL;
+    PlatformThread::unlockMutex(library->tlsLock);
+}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.h?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.h Fri Jun  1 20:00:04 2012
@@ -29,6 +29,7 @@ namespace concurrent {
 
     using decaf::lang::Thread;
 
+    class ThreadLocalImpl;
     struct ThreadHandle;
     struct MonitorHandle;
 
@@ -239,20 +240,88 @@ namespace concurrent {
 
         static void destroyThread(ThreadHandle* thread);
 
+        /**
+         * Creates and returns a ThreadHandle that references the currently running thread.
+         *
+         * This method is called to obtain a ThreadHandle that references an thread that was
+         * not created using the Decaf Thread class.  A parent Thread instance is passed to
+         * associate with the target thread so that a call to getCurrentThread can return a
+         * Decaf Thread as it would for any thread created using Thread.
+         *
+         * @param parent
+         *      The Decaf thread instace to associate with this thread handle.
+         * @param name
+         *      The name to assign to the returned ThreadHandle.
+         *
+         * @returns a new ThreadHandle instance for the parent Decaf Thread.
+         */
         static ThreadHandle* createThreadWrapper(decaf::lang::Thread* parent, const char* name);
 
+        /**
+         * @returns the Decaf Thread pointer instance for the currently running thread.
+         */
         static Thread* getCurrentThread();
+
+        /**
+         * @returns the ThreadHandle instance for the currently running thread.
+         */
         static ThreadHandle* getCurrentThreadHandle();
 
-        // Remove the given thread from scheduling
+        /**
+         * Removes the given thread from scheduling unless a call to unpark has already
+         * reset the park token in which case this method simple consumes the unpark
+         * token and returned.
+         *
+         * @param thread
+         *      The target thread to park.
+         */
         static void park(Thread* thread);
 
-        // Remove the given thread from scheduling for the given time
+        /**
+         * Removes the given thread from scheduling unless a call to unpark has already
+         * reset the park token in which case this method simple consumes the unpark
+         * token and returned.
+         *
+         * @param thread
+         *      The target thread to park.
+         * @param mills
+         *      The time in milliseconds to park the target thread.
+         * @param nanos
+         *      The additional time in nanoseconds to park the target thread.
+         */
         static bool park(Thread* thread, long long mills, int nanos);
 
-        // Makes the given thread available for scheduling once again.
+        /**
+         * If the target thread is not currently parked then this method sets the un-park
+         * token for the thread and returns.  If the thread is parked than this method
+         * places the thread back in a state where it can be scheduled once more.
+         *
+         * @param thread
+         *      The thread to unpark.
+         */
         static void unpark(Thread* thread);
 
+    public:  // Thread local storage
+
+        /**
+         * Allocates a slot in the library for a new ThreadLocalImpl to store its values
+         * for each thread.  The parent ThreadLocalImpl is stored so that the library can
+         * call each ThreadLocalImpl to cleanup its resources if there are active objects
+         * at the time the library is shutdown or the Thread terminates.
+         *
+         * @param threadLocal
+         *      The ThreadLocalImpl to assign a storage slot.
+         *
+         * @returns a new storage slot Id for the given ThreadLocalImpl's value to be assigned.
+         */
+        static int createThreadLocalSlot(ThreadLocalImpl* threadLocal);
+
+        static void* getThreadLocalValue(int slot);
+
+        static void setThreadLocalValue(int slot, void* value);
+
+        static void destoryThreadLocalSlot(int slot);
+
     private:
 
         static ThreadHandle* attachToCurrentThread();
@@ -260,7 +329,6 @@ namespace concurrent {
         static void monitorEnterUsingThreadId(MonitorHandle* monitor, ThreadHandle* thread);
         static bool monitorTryEnterUsingThreadId(MonitorHandle* monitor, ThreadHandle* thread);
         static void monitorExitUsingThreadId(MonitorHandle* monitor, ThreadHandle* thread);
-
     };
 
 }}}}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.h?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.h Fri Jun  1 20:00:04 2012
@@ -154,7 +154,7 @@ namespace lang
          * @param task the Runnable that this thread manages, if the task is NULL the Thread's
          *        run method is used instead.
          */
-        Thread( Runnable* task );
+        Thread(Runnable* task);
 
         /**
          * Constructs a new Thread with the given name. This constructor has the same effect
@@ -164,7 +164,7 @@ namespace lang
          *
          * @param name the name to assign to this Thread.
          */
-        Thread( const std::string& name );
+        Thread(const std::string& name);
 
         /**
          * Constructs a new Thread with the given target Runnable task and name. This constructor
@@ -176,7 +176,7 @@ namespace lang
          *        run method is used instead.
          * @param name the name to assign to this Thread.
          */
-        Thread( Runnable* task, const std::string& name );
+        Thread(Runnable* task, const std::string& name);
 
         /**
          * Constructs a new Thread with the given target Runnable task and name. This constructor
@@ -197,7 +197,7 @@ namespace lang
          * @param stackSize
          *      The size of the newly allocated thread's stack.
          */
-        Thread( Runnable* task, const std::string& name, long long stackSize );
+        Thread(Runnable* task, const std::string& name, long long stackSize);
 
         virtual ~Thread();
 
@@ -230,7 +230,7 @@ namespace lang
          *         The interrupted status of the current thread is cleared when this
          *         exception is thrown.
          */
-        virtual void join( long long millisecs );
+        virtual void join(long long millisecs);
 
         /**
          * Forces the Current Thread to wait until the thread exits.
@@ -244,7 +244,7 @@ namespace lang
          *         The interrupted status of the current thread is cleared when this
          *         exception is thrown.
          */
-        virtual void join( long long millisecs, int nanos );
+        virtual void join(long long millisecs, int nanos);
 
         /**
          * Default implementation of the run method - does nothing.
@@ -270,7 +270,7 @@ namespace lang
          *
          * @paran name the new name of the Thread.
          */
-        void setName( const std::string& name );
+        void setName(const std::string& name);
 
         /**
          * Gets the currently set priority for this Thread.
@@ -287,7 +287,7 @@ namespace lang
          *
          * @throws IllegalArgumentException if the value is out of range.
          */
-        void setPriority( int value );
+        void setPriority(int value);
 
         /**
          * Set the handler invoked when this thread abruptly terminates due to an uncaught exception.
@@ -302,7 +302,7 @@ namespace lang
          * @param handler the UncaightExceptionHandler to invoke when the Thread terminates due
          *                to an uncaught exception.
          */
-        void setUncaughtExceptionHandler( UncaughtExceptionHandler* handler );
+        void setUncaughtExceptionHandler(UncaughtExceptionHandler* handler);
 
         /**
          * Returns a string that describes the Thread.
@@ -361,7 +361,7 @@ namespace lang
          * @throws IllegalArgumentException if the milliseconds parameter is negative.
          * @throws InterruptedException if the Thread was interrupted while sleeping.
          */
-        static void sleep( long long millisecs );
+        static void sleep(long long millisecs);
 
         /**
          * Causes the currently executing thread to halt execution for the specified number of
@@ -378,7 +378,7 @@ namespace lang
          *         or the milliseconds paramter is negative.
          * @throws InterruptedException if the Thread was interrupted while sleeping.
          */
-        static void sleep( long long millisecs, int nanos );
+        static void sleep(long long millisecs, int nanos);
 
         /**
          * Causes the currently executing thread object to temporarily pause
@@ -426,7 +426,7 @@ namespace lang
     private:
 
         // Initialize the Threads internal state
-        void initializeSelf( Runnable* task, const std::string& name, long long stackSize );
+        void initializeSelf(Runnable* task, const std::string& name, long long stackSize);
 
         // Creates a Thread instance for a ThreadProperties pointer, used for
         // wrapping OS threads
@@ -439,6 +439,7 @@ namespace lang
 
         // Allow some Decaf Classes greater access to the Thread class.
         friend class decaf::internal::util::concurrent::Threading;
+        friend class ThreadGroup;
 
     };
 

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.cpp?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.cpp Fri Jun  1 20:00:04 2012
@@ -0,0 +1,18 @@
+/*
+ * 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 "ThreadLocal.h"

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.h?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.h Fri Jun  1 20:00:04 2012
@@ -0,0 +1,131 @@
+/*
+ * 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_LANG_THREADLOCAL_H_
+#define _DECAF_LANG_THREADLOCAL_H_
+
+#include <decaf/util/Config.h>
+
+#include <decaf/internal/util/concurrent/ThreadLocalImpl.h>
+
+namespace decaf {
+namespace lang {
+
+    /**
+     * This class provides thread-local variables. These variables differ from their normal
+     * counterparts in that each thread that accesses one (via its get or set method) has its
+     * own, independently initialized copy of the variable. ThreadLocal instances are typically
+     * private static fields in classes that wish to associate state with a thread (e.g., a
+     * user ID or Transaction ID).  This class imposes the restriction on the type that it will
+     * contains that it must by both assignable and copyable.
+     *
+     * Each thread holds an implicit reference to its copy of a thread-local variable as long as
+     * the thread is alive and the ThreadLocal instance is accessible; after a thread goes away,
+     * all of its copies of thread-local instances are destroyed.
+     *
+     * @since 1.0
+     */
+    template <typename E>
+    class ThreadLocal : protected decaf::internal::util::concurrent::ThreadLocalImpl {
+    public:
+
+        /**
+         * Creates a new instance of a ThreadLocal
+         */
+        ThreadLocal() : ThreadLocalImpl() {}
+
+        virtual ~ThreadLocal() {
+            try {
+                removeAll();
+            } catch(...) {}
+        }
+
+        /**
+         * Returns the value in the current thread's copy of this thread-local variable. If the
+         * variable has no value for the current thread, it is first initialized to the value
+         * returned by an invocation of the initialValue() method.
+         *
+         * @returns the current thread's value for this thread local.
+         */
+        E get() {
+            void* bytes = getRawValue();
+            if (bytes == NULL) {
+                E* value = new E();
+                *value = initialValue();
+                setRawValue((void*)value);
+                bytes = value;
+            }
+            return *((E*)bytes);
+        }
+
+        /**
+         * Sets the current thread's copy of this thread-local variable to the specified value.
+         * Most subclasses will have no need to override this method, relying solely on the
+         * initialValue() method to set the values of thread-locals.
+         *
+         * @param value
+         *      The new value to assign to this Thread local.
+         */
+        void set(const E& value) {
+            setRawValue((void*)(new E(value)));
+        }
+
+        /**
+         * Removes the current thread's value for this thread-local variable. If this thread-local
+         * variable is subsequently read by the current thread, its value will be reinitialized by
+         * invoking its initialValue() method, unless its value is set by the current thread in the
+         * interim. This may result in multiple invocations of the initialValue method in the
+         * current thread.
+         */
+        void remove() {
+            this->setRawValue(NULL);
+        }
+
+    protected:
+
+        /**
+         * Returns the current thread's "initial value" for this thread-local variable. This
+         * method will be invoked the first time a thread accesses the variable with the get()
+         * method, unless the thread previously invoked the set() method, in which case the
+         * initialValue method will not be invoked for the thread. Normally, this method is
+         * invoked at most once per thread, but it may be invoked again in case of subsequent
+         * invocations of remove() followed by get().
+         *
+         * This implementation simply returns E(); if the programmer desires thread-local
+         * variables to have an initial value other than E(), ThreadLocal must be subclassed,
+         * and this method overridden. Typically, an inner class will be used.
+         *
+         * @param value
+         *      Pointer to the thread local value created by this thread when get() is first called.
+         */
+        virtual E initialValue() const {
+            return E();
+        }
+
+    protected:
+
+        virtual void doDelete(void* value) {
+            if (value != 0) {
+                delete static_cast<E*>(value);
+            }
+        }
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_THREADLOCAL_H_ */

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ThreadLocal.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.cpp?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.cpp Fri Jun  1 20:00:04 2012
@@ -0,0 +1,29 @@
+/*
+ * 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 "Types.h"
+
+using namespace decaf;
+using namespace decaf::lang;
+
+////////////////////////////////////////////////////////////////////////////////
+Types::Types() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Types::~Types() {
+}

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.h?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.h Fri Jun  1 20:00:04 2012
@@ -0,0 +1,41 @@
+/*
+ * 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_LANG_TYPES_H_
+#define _DECAF_LANG_TYPES_H_
+
+#include <decaf/util/Config.h>
+
+namespace decaf {
+namespace lang {
+
+    class DECAF_API Types {
+    public:
+
+        Types();
+        virtual ~Types();
+
+        template<typename T>
+        bool isPointer() const {
+            return false;
+        }
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_TYPES_H_ */

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Types.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Config.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Config.h?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Config.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Config.h Fri Jun  1 20:00:04 2012
@@ -17,6 +17,8 @@
 #ifndef _DECAF_UTIL_CONFIG_H_
 #define _DECAF_UTIL_CONFIG_H_
 
+#include <stddef.h>
+
 #ifdef DECAF_DLL
 #ifdef DECAF_EXPORTS
 #define DECAF_API __declspec(dllexport)

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp Fri Jun  1 20:00:04 2012
@@ -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 "ReentrantReadWriteLock.h"
+
+#include <decaf/lang/Exception.h>
+#include <decaf/util/concurrent/locks/AbstractQueuedSynchronizer.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+using namespace decaf::util::concurrent::locks;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class Sync : public AbstractQueuedSynchronizer {
+    private:
+
+        /*
+         * Read vs write count extraction constants and functions.
+         * Lock state is logically divided into two unsigned shorts:
+         * The lower one representing the exclusive (writer) lock hold count,
+         * and the upper the shared (reader) hold count.
+         */
+
+        static const int SHARED_SHIFT;
+        static const int SHARED_UNIT;
+        static const int MAX_COUNT;
+        static const int EXCLUSIVE_MASK;
+
+    protected:
+
+        /** Returns the number of shared holds represented in count  */
+        static int sharedCount(int c) {
+            return c >> SHARED_SHIFT;
+        }
+
+        /** Returns the number of exclusive holds represented in count  */
+        static int exclusiveCount(int c) {
+            return c & EXCLUSIVE_MASK;
+        }
+
+    public:
+
+    };
+
+    const int Sync::SHARED_SHIFT   = 16;
+    const int Sync::SHARED_UNIT    = (1 << SHARED_SHIFT);
+    const int Sync::MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
+    const int Sync::EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
+
+    class FairSync : public Sync {
+    public:
+
+    };
+
+    class NonFairSync : public Sync {
+    public:
+
+    };
+
+    class ReadLock : public Lock {
+    public:
+
+        Sync* sync;
+
+        ReadLock(Sync* sync) : Lock(), sync(sync) {
+        }
+
+    };
+
+    class WriteLock : public Lock {
+    public:
+
+        Sync* sync;
+
+        WriteLock(Sync* sync) : Lock(), sync(sync) {
+        }
+
+    };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+    class ReentrantReadWriteLockImpl {
+    public:
+
+        Lock* readLock;
+        Lock* writeLock;
+        Sync* sync;
+
+        ReentrantReadWriteLockImpl(bool fair) : readLock(NULL), writeLock(NULL), sync(NULL) {
+            if (fair) {
+                sync = new FairSync();
+            } else {
+                sync = new NonFairSync();
+            }
+
+//            readLock = new ReadLock(sync);
+//            writeLock = new WriteLock(sync);
+        }
+
+        ~ReentrantReadWriteLockImpl() {
+            delete readLock;
+            delete writeLock;
+            delete sync;
+        }
+    };
+
+}}}}
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantReadWriteLock::ReentrantReadWriteLock() : ReadWriteLock(), impl(new ReentrantReadWriteLockImpl(true)) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantReadWriteLock::ReentrantReadWriteLock(bool fair) :
+    ReadWriteLock(), impl(new ReentrantReadWriteLockImpl(fair)) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantReadWriteLock::~ReentrantReadWriteLock() {
+    try {
+        delete impl;
+    }
+    DECAF_CATCHALL_NOTHROW()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Lock& ReentrantReadWriteLock::readLock() {
+    throw "";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Lock& ReentrantReadWriteLock::writeLock() {
+    throw "";
+}

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.h?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.h Fri Jun  1 20:00:04 2012
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_UTIL_CONCURRENT_LOCKS_REENTRANTREADWRITELOCK_H_
+#define _DECAF_UTIL_CONCURRENT_LOCKS_REENTRANTREADWRITELOCK_H_
+
+#include <decaf/util/Config.h>
+
+#include <decaf/util/concurrent/locks/ReadWriteLock.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+    class ReentrantReadWriteLockImpl;
+
+    /**
+     *
+     * @since 1.0
+     */
+    class DECAF_API ReentrantReadWriteLock : public ReadWriteLock {
+    private:
+
+        ReentrantReadWriteLockImpl* impl;
+
+    public:
+
+        /**
+         * Creates a new ReentrantReadWriteLock with the default ordering property of Not-Fair.
+         */
+        ReentrantReadWriteLock();
+
+        /**
+         * Creates a new ReentrantReadWriteLock with the given fairness policy.
+         *
+         * @param fair
+         *      Boolean value indicating whether this lock uses a fair or non-fair policy.
+         */
+        ReentrantReadWriteLock(bool fair);
+
+        virtual ~ReentrantReadWriteLock();
+
+    public:
+
+        /**
+         * {@inheritDoc}
+         */
+        virtual Lock& readLock();
+
+        /**
+         * {@inheritDoc}
+         */
+        virtual Lock& writeLock();
+
+    };
+
+}}}}
+
+#endif /* _DECAF_UTIL_CONCURRENT_LOCKS_REENTRANTREADWRITELOCK_H_ */

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantReadWriteLock.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/Makefile.am
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/Makefile.am?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/Makefile.am (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/Makefile.am Fri Jun  1 20:00:04 2012
@@ -173,6 +173,7 @@ cc_sources = \
     decaf/lang/ShortTest.cpp \
     decaf/lang/StringTest.cpp \
     decaf/lang/SystemTest.cpp \
+    decaf/lang/ThreadLocalTest.cpp \
     decaf/lang/ThreadTest.cpp \
     decaf/net/Inet4AddressTest.cpp \
     decaf/net/Inet6AddressTest.cpp \
@@ -225,6 +226,7 @@ cc_sources = \
     decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.cpp \
     decaf/util/concurrent/locks/LockSupportTest.cpp \
     decaf/util/concurrent/locks/ReentrantLockTest.cpp \
+    decaf/util/concurrent/locks/ReentrantReadWriteLockTest.cpp \
     decaf/util/zip/Adler32Test.cpp \
     decaf/util/zip/CRC32Test.cpp \
     decaf/util/zip/CheckedInputStreamTest.cpp \
@@ -404,6 +406,7 @@ h_sources = \
     decaf/lang/ShortTest.h \
     decaf/lang/StringTest.h \
     decaf/lang/SystemTest.h \
+    decaf/lang/ThreadLocalTest.h \
     decaf/lang/ThreadTest.h \
     decaf/net/Inet4AddressTest.h \
     decaf/net/Inet6AddressTest.h \
@@ -456,6 +459,7 @@ h_sources = \
     decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.h \
     decaf/util/concurrent/locks/LockSupportTest.h \
     decaf/util/concurrent/locks/ReentrantLockTest.h \
+    decaf/util/concurrent/locks/ReentrantReadWriteLockTest.h \
     decaf/util/zip/Adler32Test.h \
     decaf/util/zip/CRC32Test.h \
     decaf/util/zip/CheckedInputStreamTest.h \

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.cpp?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.cpp Fri Jun  1 20:00:04 2012
@@ -0,0 +1,173 @@
+/*
+ * 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 "ThreadLocalTest.h"
+
+#include <decaf/util/concurrent/Mutex.h>
+#include <decaf/lang/System.h>
+#include <decaf/lang/ThreadLocal.h>
+#include <decaf/lang/exceptions/InterruptedException.h>
+#include <decaf/lang/exceptions/RuntimeException.h>
+
+#include <memory>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+
+////////////////////////////////////////////////////////////////////////////////
+ThreadLocalTest::ThreadLocalTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ThreadLocalTest::~ThreadLocalTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadLocalTest::testConstructor() {
+    ThreadLocal<int> local;
+    CPPUNIT_ASSERT(local.get() == 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class StringThreadLocal : public ThreadLocal<std::string> {
+    public:
+
+        StringThreadLocal() : ThreadLocal<std::string>() {}
+        virtual ~StringThreadLocal() {}
+
+    protected:
+
+        virtual std::string initialValue() const {
+            return "initial";
+        }
+    };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadLocalTest::testRemove() {
+
+    StringThreadLocal tl;
+
+    CPPUNIT_ASSERT_EQUAL(std::string("initial"), tl.get());
+    tl.set("fixture");
+    CPPUNIT_ASSERT_EQUAL(std::string("fixture"), tl.get());
+    tl.remove();
+    CPPUNIT_ASSERT_EQUAL(std::string("initial"), tl.get());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class TestGetRunnable : public Runnable {
+    private:
+
+        std::string* result;
+        StringThreadLocal* local;
+
+    public:
+
+        TestGetRunnable(StringThreadLocal* local, std::string* result) : Runnable(), result(result), local(local) {}
+        virtual ~TestGetRunnable() {}
+
+        virtual void run() {
+            *result = local->get();
+        }
+    };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadLocalTest::testGet() {
+
+    ThreadLocal<long long> l;
+    CPPUNIT_ASSERT_MESSAGE("ThreadLocal's initial value is 0", l.get() == 0);
+
+    // The ThreadLocal has to run once for each thread that touches the
+    // ThreadLocal
+    StringThreadLocal local;
+
+    CPPUNIT_ASSERT_MESSAGE(std::string("ThreadLocal's initial value should be 'initial'")
+                           + " but is " + local.get(), local.get() == "initial");
+
+    std::string result;
+    TestGetRunnable runnable(&local, &result);
+    Thread t(&runnable);
+
+    // Alter the ThreadLocal here and then check that another thread still gets the default
+    // initial value when it calls get.
+    local.set("updated");
+
+    t.start();
+    try {
+        t.join();
+    } catch (InterruptedException& ie) {
+        CPPUNIT_FAIL("Interrupted!!");
+    }
+
+    CPPUNIT_ASSERT_MESSAGE("ThreadLocal's initial value in other Thread should be 'initial'",
+                           result == "initial");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class TestSetRunnable : public Runnable {
+    private:
+
+        StringThreadLocal* local;
+
+    public:
+
+        TestSetRunnable(StringThreadLocal* local) : Runnable(), local(local) {}
+        virtual ~TestSetRunnable() {}
+
+        virtual void run() {
+            local->set("some other value");
+        }
+    };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadLocalTest::testSet() {
+
+    StringThreadLocal local;
+    CPPUNIT_ASSERT_MESSAGE(std::string("ThreadLocal's initial value should be 'initial'")
+                           + " but is " + local.get(), local.get() == "initial");
+
+    TestSetRunnable runnable(&local);
+    Thread t(&runnable);
+
+    // Alter the ThreadLocal here and then check that another thread still gets the default
+    // initial value when it calls get.
+    local.set("updated");
+
+    t.start();
+    try {
+        t.join();
+    } catch (InterruptedException& ie) {
+        CPPUNIT_FAIL("Interrupted!!");
+    }
+
+    CPPUNIT_ASSERT_MESSAGE("ThreadLocal's value in this Thread should be 'updated'",
+                           local.get() == "updated");
+}

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.h?rev=1345326&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.h Fri Jun  1 20:00:04 2012
@@ -0,0 +1,50 @@
+/*
+ * 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_LANG_THREADLOCALTEST_H_
+#define _DECAF_LANG_THREADLOCALTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace decaf {
+namespace lang {
+
+    class ThreadLocalTest : public CppUnit::TestFixture {
+
+        CPPUNIT_TEST_SUITE( ThreadLocalTest );
+        CPPUNIT_TEST( testConstructor );
+        CPPUNIT_TEST( testGet );
+        CPPUNIT_TEST( testRemove );
+        CPPUNIT_TEST( testSet );
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        ThreadLocalTest();
+        virtual ~ThreadLocalTest();
+
+        void testConstructor();
+        void testGet();
+        void testRemove();
+        void testSet();
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_THREADLOCALTEST_H_ */

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadLocalTest.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadTest.h?rev=1345326&r1=1345325&r2=1345326&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadTest.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/ThreadTest.h Fri Jun  1 20:00:04 2012
@@ -21,9 +21,6 @@
 #include <cppunit/TestFixture.h>
 #include <cppunit/extensions/HelperMacros.h>
 
-#include <decaf/lang/Thread.h>
-#include <time.h>
-
 namespace decaf{
 namespace lang{
 



Mime
View raw message