TuttleOFX
1
|
00001 #ifndef _TUTTLE_HOST_CORE_THREADENV_HPP_ 00002 #define _TUTTLE_HOST_CORE_THREADENV_HPP_ 00003 00004 #include <tuttle/host/NodeListArg.hpp> 00005 #include <tuttle/host/ComputeOptions.hpp> 00006 #include <tuttle/host/memory/MemoryCache.hpp> 00007 00008 #include <boost/thread/thread.hpp> 00009 #include <boost/thread/recursive_mutex.hpp> 00010 #include <boost/thread/tss.hpp> 00011 #include <tuttle/common/atomic.hpp> 00012 #include <boost/bind.hpp> 00013 00014 #include <boost/signals2.hpp> 00015 00016 00017 namespace tuttle { 00018 namespace host { 00019 00020 class Graph; 00021 00022 /** 00023 * Utility class to compute a graph inside a thread. 00024 */ 00025 class ThreadEnv 00026 { 00027 public: 00028 typedef ThreadEnv This; 00029 typedef boost::signals2::signal<void ()> SignalType; 00030 00031 ThreadEnv( const bool asynchronous = true ) 00032 : _asynchronous( asynchronous ) 00033 , _isRunning(false) 00034 , _result(false) 00035 { 00036 // By default the Thread doesn't return a buffer. 00037 _options.setReturnBuffers(false); 00038 } 00039 00040 inline memory::MemoryCache& getImageCache() { return _imageCache; } 00041 inline const memory::MemoryCache& getImageCache() const { return _imageCache; } 00042 00043 inline ComputeOptions& getComputeOptions() { return _options; } 00044 inline const ComputeOptions& getComputeOptions() const { return _options; } 00045 00046 inline This& setAsynchronous( const bool v = true ) 00047 { 00048 _asynchronous = v; 00049 return *this; 00050 } 00051 00052 /// @brief Main functions 00053 /// @{ 00054 00055 /** 00056 * @brief Is this ThreadEnv executing a compute? 00057 * Thread Safe 00058 */ 00059 inline bool isRunning() { return _isRunning.load( boost::memory_order_relaxed ); } 00060 00061 /** 00062 * @brief Launch the graph computation in a synchrone or asynchrone way. 00063 */ 00064 void compute( Graph& graph, const NodeListArg& nodes = NodeListArg() ); 00065 00066 /** 00067 * @brief The application would like to abort the process (from another thread). 00068 * Thread Safe 00069 */ 00070 inline void abort() { _options.abort(); } 00071 00072 inline void join() { _thread.join(); } 00073 00074 /** 00075 * @brief Result status of the lastest compute. 00076 * Thread Safe 00077 */ 00078 inline bool getResult() const { return _result.load( boost::memory_order_relaxed ); } 00079 00080 inline SignalType& getSignalEnd() { return _signalEnd; } 00081 00082 /// @} 00083 00084 private: 00085 static void runProcessFunc( ThreadEnv* threadEnv, Graph& graph, const std::list<std::string>& nodes ); 00086 00087 /** 00088 * @brief Result status of the lastest compute. 00089 * Thread Safe 00090 */ 00091 void setResult( const bool res ) { _result.store( res, boost::memory_order_relaxed ); } 00092 00093 /** 00094 * @brief Is this ThreadEnv executing a compute? 00095 * Thread Safe 00096 */ 00097 void setIsRunning( const bool res ) { _isRunning.store( res, boost::memory_order_relaxed ); } 00098 00099 private: 00100 boost::thread _thread; 00101 00102 bool _asynchronous; 00103 memory::MemoryCache _imageCache; 00104 ComputeOptions _options; 00105 00106 boost::atomic_bool _isRunning; 00107 boost::atomic_bool _result; 00108 00109 SignalType _signalEnd; 00110 }; 00111 00112 } 00113 } 00114 00115 #endif