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( ¤tThreadKey, 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( ¤tThreadKey, 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