You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2009/09/03 00:55:42 UTC
svn commit: r810727 - in
/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang: Thread.cpp
Thread.h
Author: tabish
Date: Wed Sep 2 22:55:42 2009
New Revision: 810727
URL: http://svn.apache.org/viewvc?rev=810727&view=rev
Log:
Refactored thread class implementation hides all the implementation details from the user, no more dependency on APR includes or macros in the header.
Modified:
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/lang/Thread.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Thread.cpp?rev=810727&r1=810726&r2=810727&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 Wed Sep 2 22:55:42 2009
@@ -21,12 +21,15 @@
#pragma warning( disable: 4311 )
#endif
+#include <apr.h>
#include <apr_time.h>
#include <apr_portable.h>
+#include <apr_thread_proc.h>
#include <decaf/internal/DecafRuntime.h>
#include <decaf/lang/Exception.h>
#include <decaf/lang/exceptions/RuntimeException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
using namespace decaf;
using namespace decaf::internal;
@@ -34,29 +37,98 @@
using namespace decaf::lang::exceptions;
////////////////////////////////////////////////////////////////////////////////
+namespace decaf{
+namespace lang{
+
+ class ThreadProperties {
+ public:
+
+ /**
+ * The task to be run by this thread, defaults to
+ * this thread object.
+ */
+ Runnable* task;
+
+ /**
+ * APR Thread Handle
+ */
+ apr_thread_t* threadHandle;
+
+ /**
+ * Started state of this thread.
+ */
+ bool started;
+
+ /**
+ * Indicates whether the thread has already been
+ * joined.
+ */
+ bool joined;
+
+ public:
+
+ ThreadProperties() : task( NULL ), threadHandle( NULL ), started( false ), joined( false ) {
+ }
+
+ ThreadProperties( Runnable* task ) : task( task ), threadHandle( NULL ), started( false ), joined( false ) {
+ }
+
+ static void* APR_THREAD_FUNC runCallback( apr_thread_t* self, void* param ) {
+
+ // Get the instance.
+ ThreadProperties* properties = (ThreadProperties*)param;
+
+ // Invoke run on the task.
+ try{
+ properties->task->run();
+ } catch( ... ){
+ RuntimeException ex(
+ __FILE__, __LINE__,
+ "unhandled exception bubbled up to Thread::run");
+ ex.printStackTrace();
+ }
+
+ // Indicate we are done.
+ apr_thread_exit( self, APR_SUCCESS );
+ return NULL;
+ }
+
+ };
+
+}}
+
+////////////////////////////////////////////////////////////////////////////////
Thread::Thread() {
- this->task = this;
- this->started = false;
- this->joined = false;
- this->threadHandle = NULL;
+
+ this->initialize( this );
}
////////////////////////////////////////////////////////////////////////////////
Thread::Thread( Runnable* task ) {
- this->task = task;
- this->started = false;
- this->joined = false;
- this->threadHandle = NULL;
+
+ if( task == NULL ) {
+ throw NullPointerException(
+ __FILE__, __LINE__,
+ "Thread::Thread( Runnable* ) Runnable instance passed was NULL" );
+ }
+
+ this->initialize( task );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Thread::initialize( Runnable* task ) {
+
+ this->properties.reset( new ThreadProperties( task ) );
}
////////////////////////////////////////////////////////////////////////////////
-Thread::~Thread(){
+Thread::~Thread() {
}
////////////////////////////////////////////////////////////////////////////////
void Thread::start() throw ( Exception )
{
- if( this->started ) {
+ if( this->properties->started ) {
throw Exception(
__FILE__, __LINE__,
"Thread::start - Thread already started");
@@ -65,10 +137,10 @@
DecafRuntime* runtime = dynamic_cast<DecafRuntime*>( Runtime::getRuntime() );
apr_status_t err = apr_thread_create(
- &this->threadHandle,
+ &this->properties->threadHandle,
NULL,
- runCallback,
- this,
+ this->properties->runCallback,
+ this->properties.get(),
runtime->getGlobalPool() );
if( err != APR_SUCCESS ) {
@@ -78,25 +150,26 @@
}
// Mark the thread as started.
- started = true;
+ this->properties->started = true;
}
////////////////////////////////////////////////////////////////////////////////
void Thread::join() throw( Exception )
{
- if( !this->started ) {
+ if( !this->properties->started ) {
throw Exception( __FILE__, __LINE__,
"Thread::join() called without having called Thread::start()");
}
- if( !this->joined ) {
+ if( !this->properties->joined ) {
apr_status_t threadReturn;
- if( apr_thread_join( &threadReturn, this->threadHandle ) != APR_SUCCESS ) {
+ if( apr_thread_join( &threadReturn, this->properties->threadHandle ) != APR_SUCCESS ) {
throw Exception( __FILE__, __LINE__,
"Thread::join() - Failed to Join the Thread");
}
}
- this->joined = true;
+
+ this->properties->joined = true;
}
////////////////////////////////////////////////////////////////////////////////
@@ -113,24 +186,3 @@
unsigned long Thread::getId() {
return (unsigned long)( apr_os_thread_current() );
}
-
-////////////////////////////////////////////////////////////////////////////////
-void* APR_THREAD_FUNC Thread::runCallback( apr_thread_t* self, void* param ) {
-
- // Get the instance.
- Thread* thread = (Thread*)param;
-
- // Invoke run on the task.
- try{
- thread->task->run();
- } catch( ... ){
- RuntimeException ex(
- __FILE__, __LINE__,
- "unhandled exception bubbled up to Thread::run");
- ex.printStackTrace();
- }
-
- // Indicate we are done.
- apr_thread_exit( self, APR_SUCCESS );
- return NULL;
-}
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=810727&r1=810726&r2=810727&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 Wed Sep 2 22:55:42 2009
@@ -20,44 +20,46 @@
#include <decaf/lang/Exception.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/Config.h>
-#include <stdexcept>
-#include <assert.h>
-
-#include <apr_thread_proc.h>
+#include <memory>
namespace decaf{
namespace lang{
+ class ThreadProperties;
+
/**
- * Basic thread class - mimics the Java Thread. Derived classes may
- * implement the run method, or this class can be used as is with
- * a provided Runnable delegate.
+ * A {@code Thread} is a concurrent unit of execution. It has its own call stack for
+ * methods being invoked, their arguments and local variables. Each process has at
+ * least one main {@code Thread} running when it is started; typically, there are
+ * several others for housekeeping. The application might decide to launch additional
+ * {@code Thread}s for specific purposes.
+ *
+ * {@code Thread}s in the same process interact and synchronize by the use of shared
+ * objects and monitors associated with these objects.
+ *
+ * There are basically two main ways of having a {@code Thread} execute application
+ * code. One is providing a new class that extends {@code Thread} and overriding
+ * its {@link #run()} method. The other is providing a new {@code Thread} instance
+ * with a {@link Runnable} object during its creation. In both cases, the
+ * {@link #start()} method must be called to actually execute the new {@code Thread}.
+ *
+ * Each {@code Thread} has an integer priority that basically determines the amount
+ * of CPU time the {@code Thread} gets. It can be set using the {@link #setPriority(int)}
+ * method. A {@code Thread} can also be made a daemon, which makes it run in the
+ * background. The latter also affects VM termination behavior: the VM does not
+ * terminate automatically as long as there are non-daemon threads running.
+ *
+ * @see decaf.lang.ThreadGroup
+ *
+ * @since 1.0
*/
- class DECAF_API Thread : public Runnable
- {
+ class DECAF_API Thread : public Runnable {
private:
/**
- * The task to be run by this thread, defaults to
- * this thread object.
- */
- Runnable* task;
-
- /**
- * APR Thread Handle
- */
- apr_thread_t* threadHandle;
-
- /**
- * Started state of this thread.
- */
- bool started;
-
- /**
- * Indicates whether the thread has already been
- * joined.
+ * The internal data necessary to manage a Thread instance.
*/
- bool joined;
+ std::auto_ptr<ThreadProperties> properties;
public:
@@ -120,8 +122,8 @@
private:
- // Internal thread handling
- static void* APR_THREAD_FUNC runCallback( apr_thread_t* self, void* param );
+ // Initialize the Threads internal state
+ void initialize( Runnable* task );
};