Author: tabish
Date: Tue Sep 8 23:52:58 2009
New Revision: 812733
URL: http://svn.apache.org/viewvc?rev=812733&view=rev
Log:
Updated Thread class with more functionality and better APR isolation.
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=812733&r1=812732&r2=812733&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 8 23:52:58 2009
@@ -57,15 +57,9 @@
apr_thread_t* threadHandle;
/**
- * Started state of this thread.
+ * Current state of this thread.
*/
- bool started;
-
- /**
- * Indicates whether the thread has already been
- * joined.
- */
- bool joined;
+ Thread::State state;
/**
* The Assigned name of this thread.
@@ -108,22 +102,26 @@
if( properties->exHandler != NULL ) {
properties->exHandler->uncaughtException(
properties->parent, error );
}
+ } catch( std::exception& stdEx ) {
- error.printStackTrace();
+ RuntimeException error( __FILE__, __LINE__, stdEx.what() );
+ if( properties->exHandler != NULL ) {
+ properties->exHandler->uncaughtException(
properties->parent, error );
+ }
} catch( ... ) {
+
RuntimeException error(
__FILE__, __LINE__,
- "unhandled exception bubbled up to Thread::run");
+ "Uncaught exception bubbled up to Thread::run, Thread
Terminating.");
if( properties->exHandler != NULL ) {
properties->exHandler->uncaughtException(
properties->parent, error );
}
-
- error.printStackTrace();
}
// Indicate we are done.
+ properties->state = Thread::TERMINATED;
apr_thread_exit( self, APR_SUCCESS );
return NULL;
}
@@ -166,8 +164,7 @@
this->properties->name = name;
}
- this->properties->joined = false;
- this->properties->started = false;
+ this->properties->state = Thread::NEW;
this->properties->priority = Thread::NORM_PRIORITY;
this->properties->task = task;
this->properties->threadHandle = NULL;
@@ -180,9 +177,14 @@
}
////////////////////////////////////////////////////////////////////////////////
+void Thread::run() {
+ // No work to do as yet.
+}
+
+////////////////////////////////////////////////////////////////////////////////
void Thread::start() throw ( Exception )
{
- if( this->properties->started ) {
+ if( this->properties->state > Thread::NEW ) {
throw Exception(
__FILE__, __LINE__,
"Thread::start - Thread already started");
@@ -203,27 +205,55 @@
"Thread::start - Could not start thread");
}
- // Mark the thread as started.
- this->properties->started = true;
+ this->properties->state = Thread::RUNNABLE;
}
////////////////////////////////////////////////////////////////////////////////
-void Thread::join() throw( Exception )
+void Thread::join() throw( decaf::lang::exceptions::InterruptedException )
{
- if( !this->properties->started ) {
+ if( this->properties->state < Thread::RUNNABLE ) {
throw Exception( __FILE__, __LINE__,
"Thread::join() called without having called Thread::start()");
}
- if( !this->properties->joined ) {
+ if( this->properties->state != Thread::TERMINATED ) {
apr_status_t threadReturn;
- if( apr_thread_join( &threadReturn, this->properties->threadHandle )
!= APR_SUCCESS ) {
- throw Exception( __FILE__, __LINE__,
- "Thread::join() - Failed to Join the Thread");
- }
+ apr_thread_join( &threadReturn, this->properties->threadHandle );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Thread::join( long long millisecs )
+ throw ( decaf::lang::exceptions::IllegalArgumentException,
+ decaf::lang::exceptions::InterruptedException ) {
+
+ if( millisecs < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__,
+ "Thread::join( millisecs ) - Value given {%d} is less than 0",
millisecs );
+ }
+
+ this->join();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Thread::join( long long millisecs DECAF_UNUSED, unsigned int nanos
DECAF_UNUSED )
+ throw ( decaf::lang::exceptions::IllegalArgumentException,
+ decaf::lang::exceptions::InterruptedException ) {
+
+ if( millisecs < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__,
+ "Thread::join( millisecs, nanos ) - Value given {%d} is less than
0", millisecs );
}
- this->properties->joined = true;
+ if( nanos > 999999 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__,
+ "Thread::join( millisecs, nanos ) - Nanoseconds must be in range
[0...999999]" );
+ }
+
+ this->join();
}
////////////////////////////////////////////////////////////////////////////////
@@ -231,6 +261,12 @@
throw( lang::exceptions::InterruptedException,
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 );
}
@@ -239,6 +275,20 @@
throw( lang::exceptions::InterruptedException,
lang::exceptions::IllegalArgumentException ) {
+ if( millisecs < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__,
+ "Thread::sleep( millisecs, nanos ) - Value given {%d} is less than
0", millisecs );
+ }
+
+ if( nanos > 999999 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__,
+ "Thread::sleep( millisecs, nanos ) - Nanoseconds must be in range
[0...999999]" );
+ }
+
+ // TODO -- Add in nanos
+
apr_sleep( (apr_interval_time_t)(millisecs * 1000) );
}
@@ -298,3 +348,14 @@
Integer::toString( this->properties->priority ) + ", ThreadID=" +
Long::toString( Thread::getId() );
}
+
+////////////////////////////////////////////////////////////////////////////////
+bool Thread::isAlive() const {
+ return this->properties->state != Thread::NEW &&
+ this->properties->state != Thread::TERMINATED;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Thread::State Thread::getState() const {
+ return this->properties->state;
+}
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=812733&r1=812732&r2=812733&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 8 23:52:58 2009
@@ -75,6 +75,35 @@
/** The maximum priority that a thread can have. */
static const int MAX_PRIORITY = 10;
+ /** Represents the various states that the Thread can be in during its
lifetime. */
+ enum State{
+
+ /** Before a Thread is started it exists in this State. */
+ NEW = 0,
+
+ /** While a Thread is running and is not blocked it is in this
State. */
+ RUNNABLE = 1,
+
+ /** A Thread that is waiting to acquire a lock is in this state. */
+ BLOCKED = 2,
+
+ /** A Thread that is waiting for another Thread to perform an
action is in this state */
+ WAITING = 3,
+
+ /**
+ * A Thread that is waiting for another Thread to perform an
action up to a specified
+ * time interval is in this state.
+ */
+ TIMED_WAITING = 4,
+
+ /** A Thread that is blocked in a Sleep call is in this state. */
+ SLEEPING = 5,
+
+ /** A Thread whose run method has exited is in this state. */
+ TERMINATED = 6
+
+ };
+
public:
/**
@@ -150,15 +179,48 @@
virtual void start() throw ( Exception );
/**
- * Wait til the thread exits. This is when the run()
- * method has returned or has thrown an exception.
+ * Forces the Current Thread to wait until the thread exits.
+ *
+ * @throws InterruptedException if any thread has interrupted the
current thread.
+ * The interrupted status of the current thread is cleared
when this
+ * exception is thrown.
+ */
+ virtual void join() throw (
decaf::lang::exceptions::InterruptedException );
+
+ /**
+ * Forces the Current Thread to wait until the thread exits.
+ *
+ * @param millisecs the time in Milliseconds before the thread resumes
+ *
+ * @throws IllegalArgumentException if the milliseconds parameter is
negative.
+ * @throws InterruptedException if any thread has interrupted the
current thread.
+ * The interrupted status of the current thread is cleared
when this
+ * exception is thrown.
*/
- virtual void join() throw ( Exception );
+ virtual void join( long long millisecs )
+ throw ( decaf::lang::exceptions::IllegalArgumentException,
+ decaf::lang::exceptions::InterruptedException );
+
+ /**
+ * Forces the Current Thread to wait until the thread exits.
+ *
+ * @param millisecs the time in Milliseconds before the thread resumes
+ * @param nanos 0-999999 extra nanoseconds to sleep.
+ *
+ * @throws IllegalArgumentException if the nanoseconds parameter is
out of range
+ * or the milliseconds paramter is negative.
+ * @throws InterruptedException if any thread has interrupted the
current thread.
+ * The interrupted status of the current thread is cleared
when this
+ * exception is thrown.
+ */
+ virtual void join( long long millisecs, unsigned int nanos )
+ throw ( decaf::lang::exceptions::IllegalArgumentException,
+ decaf::lang::exceptions::InterruptedException );
/**
* Default implementation of the run method - does nothing.
*/
- virtual void run(){};
+ virtual void run();
/**
* Returns the Thread's assigned name.
@@ -212,6 +274,21 @@
*/
std::string toString() const;
+ /**
+ * Returns true if the Thread is alive, meaning it has been started
and has not yet
+ * died.
+ *
+ * @return true if the thread is alive.
+ */
+ bool isAlive() const;
+
+ /**
+ * Returns the currently set State of this Thread.
+ *
+ * @return the Thread's current state.
+ */
+ Thread::State getState() const;
+
public:
/**