threadFunctor.cpp

Go to the documentation of this file.
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 } // namespace
00039 
00040 
00041 namespace dlr {
00042 
00043   namespace thread {
00044     
00045     // Destroys the ThreadFunctor instance and releases any resources.
00046     ThreadFunctor::
00047     ~ThreadFunctor()
00048     {
00049       if(m_threadPtr != 0) {
00050         // Warning(xxx): Shouldn't we call thread::terminate() or
00051         // something?
00052         delete m_threadPtr;
00053       }
00054     }
00055 
00056     
00057     // The assignment operator does a deep copy.
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     // This operator executes this->main(), catches any exceptions
00079     // thrown by this->main(), and handles those exceptions by
00080     // calling this->handleError().
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     // This member function is called if an exception is thrown by
00099     // this->main(), and sends notification that the thread has (is
00100     // about to) terminate.
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     // This member function blocks until the thread associated with
00119     // *this exits.
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     // This member function creates a new thread and executes
00138     // this->operator()() from within that thread.
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   } // namespace thread
00156 
00157 } // namespace dlr

Generated on Mon Jul 9 20:34:03 2007 for dlrLibs Utility Libraries by  doxygen 1.5.2