00001
00014 #include <exception>
00015 #include <iostream>
00016 #include <sstream>
00017 #include <dlrCommon/exception.h>
00018 #include <dlrThread/threadFunctor.h>
00019
00020 namespace {
00021
00027 struct TFAdaptor {
00028
00029 TFAdaptor(dlr::thread::ThreadFunctor* threadFunctorPtr)
00030 : m_threadFunctorPtr(threadFunctorPtr) {}
00031
00032 void operator()() {m_threadFunctorPtr->operator()();}
00033
00034 private:
00035 dlr::thread::ThreadFunctor* m_threadFunctorPtr;
00036 };
00037
00038 }
00039
00040
00041 namespace dlr {
00042
00043 namespace thread {
00044
00045
00046 ThreadFunctor::
00047 ~ThreadFunctor()
00048 {
00049 if(m_threadPtr != 0) {
00050
00051
00052 delete m_threadPtr;
00053 }
00054 }
00055
00056
00057
00058 ThreadFunctor&
00059 ThreadFunctor::
00060 operator=(const ThreadFunctor& source)
00061 {
00062 if(&source != this) {
00063 if(m_threadPtr != 0) {
00064 std::ostringstream message;
00065 message << "[" << m_threadName << "] "
00066 << "Can't complete assignment while a subordinate thread "
00067 << "is running. Please call the join() method of the "
00068 << "assignee prior to assignment.";
00069 DLR_THROW(StateException, "ThreadFunctor::operator=()",
00070 message.str().c_str());
00071 }
00072 m_threadName = source.m_threadName;
00073 }
00074 return *this;
00075 }
00076
00077
00078
00079
00080
00081 void
00082 ThreadFunctor::
00083 operator()() {
00084 try {
00085 this->main();
00086 } catch(const dlr::Exception& caughtException) {
00087 this->handleError(caughtException.what(),
00088 caughtException.trace());
00089 } catch(const std::exception& caughtException) {
00090 this->handleError(caughtException.what(), "");
00091 } catch(...) {
00092 this->handleError(
00093 "Unknown exception. No further information available.", "");
00094 }
00095 }
00096
00097
00098
00099
00100
00101 void
00102 ThreadFunctor::
00103 handleError(const std::string& errorMessage,
00104 const std::string& errorDetail)
00105 {
00106 std::cerr << "WARNING: Unhandled exception in thread "
00107 << m_threadName << ".\n"
00108 << " " << errorMessage << "\n";
00109 if(errorDetail != "") {
00110 std::cerr << errorDetail << "\n";
00111 }
00112 std::cerr << "=============== Ending thread " << m_threadName
00113 << ". ===============\n"
00114 << std::endl;
00115 }
00116
00117
00118
00119
00120 void
00121 ThreadFunctor::
00122 join()
00123 {
00124 if(m_threadPtr == 0) {
00125 std::ostringstream message;
00126 message << "[" << m_threadName << "] "
00127 << "No subordinate thread is currently running.";
00128 DLR_THROW(StateException, "ThreadFunctor::join()",
00129 message.str().c_str());
00130 }
00131 m_threadPtr->join();
00132 delete m_threadPtr;
00133 m_threadPtr = 0;
00134 }
00135
00136
00137
00138
00139 void
00140 ThreadFunctor::
00141 run()
00142 {
00143 if(m_threadPtr != 0) {
00144 std::ostringstream message;
00145 message << "[" << m_threadName << "] "
00146 << "Can't start a new subordinate thread because a "
00147 << "subordinate thread is already running.";
00148 DLR_THROW(StateException, "ThreadFunctor::run()",
00149 message.str().c_str());
00150 }
00151 m_threadPtr = new boost::thread(TFAdaptor(this));
00152 }
00153
00154
00155 }
00156
00157 }