activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r817641 - in /activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf: internal/ internal/lang/ internal/lang/unix/ internal/lang/windows/ lang/ util/concurrent/locks/ util/concurrent/locks/unix/ util/concurrent/locks/windows/
Date Tue, 22 Sep 2009 12:47:23 GMT
Author: tabish
Date: Tue Sep 22 12:47:22 2009
New Revision: 817641

URL: http://svn.apache.org/viewvc?rev=817641&view=rev
Log:
More cleanup in the Threading API, remove more APR usage and hide implementation details.

Added:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantLock.h
  (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/unix/
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/unix/ReentrantLock.cpp
  (with props)
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/windows/
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/windows/ReentrantLock.cpp
  (with props)
Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/ThreadImpl.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadHandle.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadImpl.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadHandle.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadImpl.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.h

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.cpp?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.cpp Tue
Sep 22 12:47:22 2009
@@ -21,18 +21,40 @@
 #include <apr_general.h>
 #include <apr_pools.h>
 
+#include <decaf/lang/Thread.h>
+
 using namespace decaf;
 using namespace decaf::internal;
 using namespace decaf::lang;
 
 ////////////////////////////////////////////////////////////////////////////////
+namespace decaf{
+namespace internal{
+
+    class RuntimeData {
+    public:
+
+        mutable apr_pool_t* aprPool;
+
+    public:
+
+        RuntimeData() : aprPool(NULL) {
+        }
+
+    };
+
+}}
+
+////////////////////////////////////////////////////////////////////////////////
 DecafRuntime::DecafRuntime() {
 
+    this->runtimeData.reset( new RuntimeData() );
+
     // Initializes the APR Runtime from within a library.
     apr_initialize();
 
     // Create a Global Pool for Threads to use
-    apr_pool_create_ex( &aprPool, NULL, NULL, NULL );
+    apr_pool_create_ex( &runtimeData->aprPool, NULL, NULL, NULL );
 
 }
 
@@ -40,7 +62,7 @@
 DecafRuntime::~DecafRuntime() {
 
     // Destroy the Global Thread Memory Pool
-    apr_pool_destroy( aprPool );
+    apr_pool_destroy( this->runtimeData->aprPool );
 
     // Cleans up APR data structures.
     apr_terminate();
@@ -48,7 +70,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 apr_pool_t* DecafRuntime::getGlobalPool() const {
-    return this->aprPool;
+    return this->runtimeData->aprPool;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -65,6 +87,9 @@
     // Do this for now, once we remove APR we can do this in a way that
     // makes more sense.
     Runtime::getRuntime();
+
+    // Initialize any Platform specific Threading primitives
+    Thread::initThreading();
 }
 
 ////////////////////////////////////////////////////////////////////////////////

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.h?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/DecafRuntime.h Tue Sep
22 12:47:22 2009
@@ -20,21 +20,22 @@
 
 #include <decaf/util/Config.h>
 #include <decaf/lang/Runtime.h>
+
+#include <memory>
 #include <apr_pools.h>
 
 namespace decaf {
 namespace internal {
 
+    class RuntimeData;
+
     /**
      * Handles APR initialization and termination.
      */
     class DECAF_API DecafRuntime : public decaf::lang::Runtime {
     private:
 
-        /**
-         * Internal APR pool
-         */
-        mutable apr_pool_t* aprPool;
+        std::auto_ptr<RuntimeData> runtimeData;
 
     public:
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/ThreadImpl.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/ThreadImpl.h?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/ThreadImpl.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/ThreadImpl.h Tue
Sep 22 12:47:22 2009
@@ -36,6 +36,17 @@
     public:
 
         /**
+         * Initializes that Thread specific data structures used to provide all the services
+         * that this collection of Thread methods provides.
+         */
+        static void initializeThreading();
+
+        /**
+         * Shutdown and Deallocate all resources associated with Threading.
+         */
+        static void shutdownThreading();
+
+        /**
          * Create a new OS Thread.  When the new thread is created the given start routine
is
          * called and the supplied argument is passed along with ThreadHandle associated
with
          * this thread.  If successful this method returns the active ThreadHandle to the
caller,
@@ -106,6 +117,16 @@
          */
         static long long getThreadId();
 
+        /**
+         * Gets a Pointer to the Thread object associated with the currently running Thread.
+         *
+         * This pointer is not owned by the caller and is deallocated as soon as the current
+         * Thread dies.
+         *
+         * @return Thread pointer for the currently running Thread.
+         */
+        static decaf::lang::Thread* getCurrentThread();
+
     };
 
 }}}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadHandle.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadHandle.h?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadHandle.h
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadHandle.h
Tue Sep 22 12:47:22 2009
@@ -28,6 +28,8 @@
 namespace decaf {
 namespace lang {
 
+    class Thread;
+
     /**
      * Platform definition of a Thread Handle on Unix, contains the PThread
      * constructs and additional data necessary to implement a thread on
@@ -46,6 +48,7 @@
             returnStatus = false;
             userArg = NULL;
             entryFunctionPtr = NULL;
+            parent = NULL;
         }
 
         ~ThreadHandle() {
@@ -58,6 +61,7 @@
         threadEntry entryFunctionPtr;
         void* userArg;
         bool running;
+        Thread* parent;
 
     };
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadImpl.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadImpl.cpp?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadImpl.cpp
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/unix/ThreadImpl.cpp
Tue Sep 22 12:47:22 2009
@@ -56,17 +56,35 @@
 ////////////////////////////////////////////////////////////////////////////////
 namespace{
 
+    pthread_key_t currentThreadKey;
+
     void* threadWorker( void* arg ) {
         ThreadHandle* handle = (ThreadHandle*)arg;
+        pthread_setspecific( currentThreadKey, (void*)handle->parent );
         handle->running = true;
         handle->entryFunctionPtr( handle, handle->userArg );
         handle->running = false;
+        pthread_setspecific( currentThreadKey, NULL );
         pthread_exit(0);
         return NULL;
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+void ThreadImpl::initializeThreading() {
+
+    // Create the Key used to store the Current Thread data
+    pthread_key_create( &currentThreadKey, NULL );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadImpl::shutdownThreading() {
+
+    // Destroy the current Thread key now, no longer needed.
+    pthread_key_delete( currentThreadKey );
+}
+
+////////////////////////////////////////////////////////////////////////////////
 ThreadHandle* ThreadImpl::create( decaf::lang::Thread* parent,
                                   void (*threadEntry)( decaf::lang::ThreadHandle* self, void*
data ),
                                   void* userArg ) {
@@ -84,6 +102,7 @@
     std::auto_ptr<ThreadHandle> handle( new ThreadHandle );
     handle->entryFunctionPtr = threadEntry;
     handle->userArg = userArg;
+    handle->parent = parent;
 
     int result = pthread_create( &( handle->thread ), &( handle->attributes
), threadWorker, handle.get() );
 
@@ -165,3 +184,17 @@
 long long ThreadImpl::getThreadId() {
     return (long long)pthread_self();
 }
+
+////////////////////////////////////////////////////////////////////////////////
+decaf::lang::Thread* ThreadImpl::getCurrentThread() {
+
+    // Grab the Thread Local copy
+    void* result = pthread_getspecific( currentThreadKey );
+
+    if( result == NULL ) {
+        throw RuntimeException(
+            __FILE__, __LINE__, "Failed to find the Current Thread pointer in the TLS." );
+    }
+
+    return (Thread*)result;
+}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadHandle.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadHandle.h?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadHandle.h
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadHandle.h
Tue Sep 22 12:47:22 2009
@@ -24,6 +24,8 @@
 namespace decaf {
 namespace lang {
 
+    class Thread;
+
     /**
      * Platform definition of a Thread Handle on Windows, contains the type
      * constructs and additional data necessary to implement a thread on
@@ -42,6 +44,7 @@
             userArg = NULL;
             entryFunctionPtr = NULL;
             handle = NULL;
+            parent = NULL;
         }
 
         ~ThreadHandle() {
@@ -53,6 +56,7 @@
         threadEntry entryFunctionPtr;
         void* userArg;
         bool running;
+        Thread* parent;
 
     };
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadImpl.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadImpl.cpp?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadImpl.cpp
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/lang/windows/ThreadImpl.cpp
Tue Sep 22 12:47:22 2009
@@ -38,6 +38,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 namespace{
 
+    Thread* currentThread;
+
     unsigned int __stdcall threadWorker( void* arg ) {
         ThreadHandle* handle = (ThreadHandle*)arg;
         handle->running = true;
@@ -55,6 +57,18 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+void ThreadImpl::initializeThreading() {
+
+    // Create the Key used to store the Current Thread data
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ThreadImpl::shutdownThreading() {
+
+    // Destroy the current Thread key now, no longer needed.
+}
+
+////////////////////////////////////////////////////////////////////////////////
 ThreadHandle* ThreadImpl::create( decaf::lang::Thread* parent,
                                   void (*threadEntry)( decaf::lang::ThreadHandle* self, void*
data ),
                                   void* userArg ) {

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.cpp?rev=817641&r1=817640&r2=817641&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.cpp Tue Sep 22 12:47:22
2009
@@ -24,17 +24,42 @@
 #include <decaf/internal/DecafRuntime.h>
 #include <decaf/lang/Integer.h>
 #include <decaf/lang/Long.h>
+#include <decaf/lang/Math.h>
 #include <decaf/lang/Exception.h>
 #include <decaf/lang/exceptions/RuntimeException.h>
 #include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/util/concurrent/TimeUnit.h>
 
-#include <decaf/internal/lang/ThreadImpl.h>
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_SCHED_H
+#include <sched.h>
+#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
 
 using namespace decaf;
 using namespace decaf::internal;
-using namespace decaf::internal::lang;
 using namespace decaf::lang;
 using namespace decaf::lang::exceptions;
+using namespace decaf::util::concurrent;
 
 ////////////////////////////////////////////////////////////////////////////////
 namespace decaf{
@@ -50,9 +75,14 @@
         Runnable* task;
 
         /**
-         * APR Thread Handle
+         * The Platform Specific Thread Handle.
          */
-        std::auto_ptr<ThreadHandle> threadHandle;
+        #ifdef HAVE_PTHREAD_H
+            pthread_t handle;
+            pthread_attr_t attributes;
+        #else
+            HANDLE handle;
+        #endif
 
         /**
          * Current state of this thread.
@@ -87,11 +117,25 @@
 
     public:
 
-        //static void* APR_THREAD_FUNC runCallback( apr_thread_t* self, void* param ) {
-        static void runCallback( ThreadHandle* thread DECAF_UNUSED, void* param ) {
+        ThreadProperties() {
 
-            // Get the instance.
-            ThreadProperties* properties = (ThreadProperties*)param;
+            #ifdef HAVE_PTHREAD_H
+                pthread_attr_init( &attributes );
+            #endif
+        }
+
+        ~ThreadProperties() {
+
+            #ifdef HAVE_PTHREAD_H
+                pthread_attr_destroy( &attributes );
+            #endif
+        }
+
+    public:
+
+        static void runCallback( ThreadProperties* properties ) {
+
+            properties->state = Thread::RUNNABLE;
 
             // Invoke run on the task.
             try{
@@ -128,9 +172,85 @@
 }}
 
 ////////////////////////////////////////////////////////////////////////////////
+namespace{
+
+    #ifdef HAVE_PTHREAD_H
+
+        pthread_key_t currentThreadKey;
+
+        void* threadWorker( void* arg ) {
+
+            ThreadProperties* properties = (ThreadProperties*)arg;
+
+            pthread_setspecific( currentThreadKey, (void*)properties->parent );
+
+            ThreadProperties::runCallback( properties );
+
+            pthread_setspecific( currentThreadKey, NULL );
+            pthread_exit(0);
+
+            return NULL;
+        }
+    #else
+
+        Thread* currentThread;
+
+        unsigned int __stdcall threadWorker( void* arg ) {
+            ThreadHandle* handle = (ThreadHandle*)arg;
+            handle->running = true;
+            handle->entryFunctionPtr( handle, handle->userArg );
+            handle->running = false;
+
+            #ifndef _WIN32_WCE
+                _endthreadex( 0 );
+            #else
+                ExitThread( 0 );
+            #endif
+
+            ::CloseHandle( handle->handle );
+
+            return NULL;
+        }
+
+    #endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
 unsigned int ThreadProperties::id = 0;
 
 ////////////////////////////////////////////////////////////////////////////////
+void Thread::initThreading() {
+
+    Thread* mainThread = new Thread( "Main Thread" );
+
+    mainThread->properties->state = Thread::RUNNABLE;
+    mainThread->properties->priority = Thread::NORM_PRIORITY;
+    mainThread->properties->parent = mainThread;
+
+    #ifdef HAVE_PTHREAD_H
+
+        mainThread->properties->handle = pthread_self();
+
+        // Create the Key used to store the Current Thread data
+        pthread_key_create( &currentThreadKey, NULL );
+        pthread_setspecific( currentThreadKey, mainThread );
+
+    #endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Thread::shutdownThreading() {
+
+    // Get the Main Thread and Destroy it
+    Thread* mainThread = (Thread*) pthread_getspecific( currentThreadKey );
+
+    delete mainThread;
+
+    // Destroy the current Thread key now, no longer needed.
+    pthread_key_delete( currentThreadKey );
+}
+
+////////////////////////////////////////////////////////////////////////////////
 Thread::Thread() {
     this->initialize( this, "" );
 }
@@ -184,15 +304,49 @@
     try {
 
         if( this->properties->state > Thread::NEW ) {
-            throw RuntimeException(
+            throw IllegalThreadStateException(
                 __FILE__, __LINE__,
                 "Thread::start - Thread already started");
         }
 
-        this->properties->threadHandle.reset( ThreadImpl::create(
-             this, this->properties->runCallback, this->properties.get() ) );
+        #ifdef HAVE_PTHREAD_H
+            int result = pthread_create( &( properties->handle ),
+                                         &( properties->attributes ),
+                                         threadWorker, properties.get() );
+
+            if( result != 0 ) {
+                throw RuntimeException(
+                    __FILE__, __LINE__, "Failed to create new Thread." );
+            }
+
+        #else
+
+            unsigned int threadId = 0;
+
+            #ifndef _WIN32_WCE
+
+                handle->handle = (HANDLE)_beginthreadex(
+                     NULL, (DWORD)0, threadWorker, properties.get(), 0, &threadId );
+
+            #else
 
-        this->properties->state = Thread::RUNNABLE;
+                handle->hanlde = CreateThread( NULL, 0, threadWorker, handle.get(), 0,
&threadId ) );
+
+                if( handle->handle == 0 ) {
+                    throw RuntimeException(
+                        __FILE__, __LINE__, "Failed to create new Thread." );
+                }
+
+            #endif
+
+        #endif
+
+        // Only try and set this if its not the default value.
+        if( properties->priority != Thread::NORM_PRIORITY ) {
+            setPriority( properties->priority );
+        }
+
+        properties->state = Thread::RUNNABLE;
      }
      DECAF_CATCH_RETHROW( IllegalThreadStateException )
      DECAF_CATCH_RETHROW( RuntimeException )
@@ -209,7 +363,13 @@
     }
 
     if( this->properties->state != Thread::TERMINATED ) {
-        ThreadImpl::join( this->properties->threadHandle.get() );
+
+        #ifdef HAVE_PTHREAD_H
+            void* theReturn = 0;
+            pthread_join( properties->handle, &theReturn );
+        #else
+            Thread::join( INFINITE, 0 );
+        #endif
     }
 }
 
@@ -224,7 +384,7 @@
             "Thread::join( millisecs ) - Value given {%d} is less than 0", millisecs );
     }
 
-    this->join( millisecs );
+    this->join( millisecs, 0 );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -244,7 +404,25 @@
             "Thread::join( millisecs, nanos ) - Nanoseconds must be in range [0...999999]"
);
     }
 
-    ThreadImpl::join( this->properties->threadHandle.get(), millisecs, nanos );
+    #ifdef HAVE_PTHREAD_H
+
+        void* theReturn = NULL;
+
+        // TODO - Still need a way to do this if the non-posix method doesn't exist.
+        #if HAVE_PTHREAD_TIMEDJOIN_NP
+
+            long long totalTime = TimeUnit::MILLISECONDS.toNanos( millisecs ) + nanos;
+
+            timespec time;
+            time.tv_nsec = totalTime % 1000000000;
+            time.tv_sec = totalTime / 1000000000;
+
+            pthread_timedjoin_np( properties->handle, &theReturn, &time );
+
+        #endif
+    #else
+        unsigned int rv = WaitForSingleObject( properties->handle, (DWORD)millisecs );
+    #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -252,12 +430,6 @@
     throw( decaf::lang::exceptions::InterruptedException,
            decaf::lang::exceptions::IllegalArgumentException ) {
 
-    if( millisecs < 0 ) {
-        throw IllegalArgumentException(
-            __FILE__, __LINE__,
-            "Thread::sleep( millisecs ) - Value given {%d} is less than 0", millisecs );
-    }
-
     Thread::sleep( millisecs, 0 );
 }
 
@@ -278,17 +450,45 @@
             "Thread::sleep( millisecs, nanos ) - Nanoseconds must be in range [0...999999]"
);
     }
 
-    ThreadImpl::sleep( millisecs, nanos );
+    #ifdef HAVE_PTHREAD_H
+        long long usecs = TimeUnit::MILLISECONDS.toMicros( millisecs ) +
+                          TimeUnit::NANOSECONDS.toMicros( nanos );
+
+        struct timeval tv;
+        tv.tv_usec = usecs % 1000000;
+        tv.tv_sec = usecs / 1000000;
+        select( 0, NULL, NULL, NULL, &tv );
+    #else
+        ::Sleep( (DWORD)mills );
+    #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void Thread::yield() {
-    ThreadImpl::yeild();
+
+    #ifdef HAVE_PTHREAD_H
+        #ifdef HAVE_PTHREAD_YIELD
+            pthread_yield();
+        #else
+            #ifdef HAVE_SCHED_YIELD
+                sched_yield();
+            #endif
+        #endif
+    #else
+        #ifndef _WIN32_WCE
+            SwitchToThread();
+        #endif
+    #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 long long Thread::getId() {
-    return ThreadImpl::getThreadId();
+
+    #ifdef HAVE_PTHREAD_H
+        return (long long)pthread_self();
+    #else
+        return (long long)::GetCurrentThreadId();
+    #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -312,7 +512,7 @@
 
     this->properties->priority = value;
 
-    ThreadImpl::setPriority( this->properties->threadHandle.get(), value );
+    //ThreadImpl::setPriority( this->properties->threadHandle.get(), value );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -348,3 +548,21 @@
 Thread::State Thread::getState() const {
     return this->properties->state;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+Thread* Thread::currentThread() {
+
+    #ifdef HAVE_PTHREAD_H
+        // Grab the Thread Local copy
+        void* result = pthread_getspecific( currentThreadKey );
+
+        if( result == NULL ) {
+            throw RuntimeException(
+                __FILE__, __LINE__, "Failed to find the Current Thread pointer in the TLS."
);
+        }
+
+        return (Thread*)result;
+    #else
+        return NULL;
+    #endif
+}

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=817641&r1=817640&r2=817641&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 Tue Sep 22 12:47:22
2009
@@ -27,8 +27,14 @@
 #include <memory>
 
 namespace decaf{
+namespace util{
+namespace concurrent{
+namespace locks{
+    class LockSupport;
+}}}
 namespace lang{
 
+    class Runtime;
     class ThreadGroup;
     class ThreadProperties;
 
@@ -341,11 +347,32 @@
          */
         static long long getId();
 
+        /**
+         * Returns a pointer to the currently executing thread object.
+         *
+         * @return Pointer to the Thread object representing the currently running Thread.
+         */
+        static Thread* currentThread();
+
     private:
 
         // Initialize the Threads internal state
         void initialize( Runnable* task, const std::string& name );
 
+        // Called by the Decaf Runtime at startup to allow the Platform Threading
+        // code to initialize any necessary Threading constructs needed to support
+        // the features of this class.
+        static void initThreading();
+
+        // Called by the Decf Runtime at Shutdown to allow the Platform Threading
+        // code to return any resources that were allocated at startup for the
+        // Threading library.
+        static void shutdownThreading();
+
+        // Allow some Decaf Classes greater access to the Threading model.
+        friend class decaf::util::concurrent::locks::LockSupport;
+        friend class decaf::lang::Runtime;
+
     };
 
 }}

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantLock.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantLock.h?rev=817641&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantLock.h
(added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReentrantLock.h
Tue Sep 22 12:47:22 2009
@@ -0,0 +1,97 @@
+/*
+ * 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_REENTRANTLOCK_H_
+#define _DECAF_UTIL_CONCURRENT_LOCKS_REENTRANTLOCK_H_
+
+#include <decaf/util/Config.h>
+
+#include <decaf/util/concurrent/locks/Lock.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+    class LockHandle;
+
+    /**
+     * A reentrant mutual exclusion Lock with extended capabilities.
+     *
+     * A ReentrantLock is owned by the thread last successfully locking, but not yet unlocking
it.
+     * A thread invoking lock will return, successfully acquiring the lock, when the lock
is not
+     * owned by another thread. The method will return immediately if the current thread
already
+     * owns the lock. This can be checked using methods isHeldByCurrentThread(), and getHoldCount().
+     *
+     * The constructor for this class accepts an optional fairness parameter. When set true,
under
+     * contention, locks favor granting access to the longest-waiting thread. Otherwise this
lock
+     * does not guarantee any particular access order. Programs using fair locks accessed
by many
+     * threads may display lower overall throughput (i.e., are slower; often much slower)
than
+     * those using the default setting, but have smaller variances in times to obtain locks
and
+     * guarantee lack of starvation. Note however, that fairness of locks does not guarantee
+     * fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain
it
+     * multiple times in succession while other active threads are not progressing and not
currently
+     * holding the lock. Also note that the untimed tryLock method does not honor the fairness
+     * setting. It will succeed if the lock is available even if other threads are waiting.
+     *
+     * It is recommended practice to always immediately follow a call to lock with a try
block,
+     * most typically in a before/after construction such as:
+     *
+     *    class X {
+     *    private:
+     *
+     *        ReentrantLock lock;
+     *        // ...
+     *
+     *    public:
+     *
+     *        void m() {
+     *            lock.lock();  // block until condition holds
+     *
+     *            try {
+     *                // ... method body
+     *            } finally {
+     *                lock.unlock()
+     *            }
+     *        }
+     *    }
+     *
+     * In addition to implementing the Lock interface, this class defines methods isLocked
and
+     * getLockQueueLength, as well as some associated protected access methods that may be
useful
+     * for instrumentation and monitoring.
+     *
+     * This lock supports a maximum of 2147483647 recursive locks by the same thread. Attempts
+     * to exceed this limit result in Error throws from locking methods.
+     *
+     * @since 1.0
+     */
+    class DECAF_API ReentrantLock : public Lock {
+    private:
+
+        std::auto_ptr<LockHandle> handle;
+
+    public:
+
+        ReentrantLock();
+
+        virtual ~ReentrantLock();
+
+    };
+
+}}}}
+
+#endif /* _DECAF_UTIL_CONCURRENT_LOCKS_REENTRANTLOCK_H_ */

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

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/unix/ReentrantLock.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/unix/ReentrantLock.cpp?rev=817641&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/unix/ReentrantLock.cpp
(added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/unix/ReentrantLock.cpp
Tue Sep 22 12:47:22 2009
@@ -0,0 +1,32 @@
+/*
+ * 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 "ReentrantLock.h"
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+using namespace decaf::util::concurrent::locks;
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantLock::ReentrantLock() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantLock::~ReentrantLock() {
+}

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

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/windows/ReentrantLock.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/windows/ReentrantLock.cpp?rev=817641&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/windows/ReentrantLock.cpp
(added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/windows/ReentrantLock.cpp
Tue Sep 22 12:47:22 2009
@@ -0,0 +1,32 @@
+/*
+ * 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 "ReentrantLock.h"
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+using namespace decaf::util::concurrent::locks;
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantLock::ReentrantLock() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ReentrantLock::~ReentrantLock() {
+}

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



Mime
View raw message