Bytemaster's Boost Libraries
/Users/dlarimer/dev/libs/cmt/include/boost/cmt/task.hpp
00001 #ifndef BOOST_CMT_TASK_HPP
00002 #define BOOST_CMT_TASK_HPP
00003 #include <boost/enable_shared_from_this.hpp>
00004 #include <boost/cmt/error.hpp>
00005 #include <boost/cmt/retainable.hpp>
00006 #include <boost/cmt/future.hpp>
00007 #include <boost/function.hpp>
00008 #include <boost/exception/diagnostic_information.hpp>
00009 #include <boost/cmt/log/log.hpp>
00010 
00011 namespace boost { namespace cmt {
00012      struct priority {
00013        explicit priority( int v = 0):value(v){}
00014        priority( const priority& p ):value(p.value){}
00015        bool operator < ( const priority& p )const {
00016         return value < p.value;
00017        }
00018        int value;
00019      };
00020     class task : public retainable {
00021         public:
00022             typedef task* ptr;
00023             task(priority p=priority())
00024             :prio(p),next(0){
00025                 static int64_t global_task_count=0;
00026                 posted_num = ++global_task_count;
00027             }
00028 
00029             virtual void run() = 0;
00030             virtual void cancel() = 0;
00031             virtual const char* name() { return "unknown"; }
00032         protected:
00033             static int64_t task_num;
00034             friend class   thread;
00035             friend class   thread_private;
00036             uint64_t       posted_num;
00037             priority       prio;
00038             task*          next;
00039     };
00040 
00041     template<typename R = void>
00042     class rtask : public task {
00043         public:
00044             rtask( const boost::function<R()>& f, const typename promise<R>::ptr& p, priority prio, const char* name = "" )
00045             :task(prio),m_functor(f),m_prom(p),m_name(name){}
00046 
00047             void cancel() {
00048                 try {
00049                     BOOST_THROW_EXCEPTION( error::task_canceled() );
00050                 } catch ( ... ) {
00051                     m_prom->set_exception(boost::current_exception());
00052                 }
00053             }
00054             void run() {
00055                 try {
00056                     m_prom->set_value( m_functor() );
00057                 } catch( ... ) {
00058                     m_prom->set_exception(boost::current_exception());
00059                 }
00060             }
00061             const char* name() { return m_name; }
00062 
00063             boost::function<R()>        m_functor;
00064             typename promise<R>::ptr    m_prom;
00065             const char*                 m_name;
00066     };
00067 
00068     template<>
00069     class rtask<void> : public task {
00070         public:
00071             rtask( const boost::function<void()>& f, const  promise<void>::ptr& p, priority prio=priority(), const char* name = "" )
00072             :task(prio),m_functor(f),m_prom(p),m_name(name){}
00073 
00074             void cancel() {
00075                 try {
00076                     BOOST_THROW_EXCEPTION( error::task_canceled() );
00077                 } catch ( ... ) {
00078                     m_prom->set_exception(boost::current_exception());
00079                 }
00080             }
00081             void run() {
00082                 try {
00083                     m_functor();
00084                     m_prom->set_value( void_t() );
00085                 } catch( ... ) {
00086                     m_prom->set_exception(boost::current_exception());
00087                 }
00088             }
00089             const char* name() { return m_name; }
00090         
00091             boost::function<void()>     m_functor;
00092             promise<void>::             ptr m_prom;
00093             const char*                 m_name;
00094 
00095     };
00096 
00097     template<typename R = void_t>
00098     class reftask : public task {
00099         public:
00100             reftask( const boost::function<R()>& f, const typename promise<R>::ptr& p, priority prio =priority(), const char* name = "" )
00101             :task(prio),m_functor(f),m_prom(p),m_name(name){}
00102 
00103             void cancel() {
00104                 try {
00105                     BOOST_THROW_EXCEPTION( error::task_canceled() );
00106                 } catch ( ... ) {
00107                     m_prom->set_exception(boost::current_exception());
00108                 }
00109             }
00110             void run() {
00111                 try {
00112                     m_prom->set_value( m_functor() );
00113                 } catch( ... ) {
00114                     m_prom->set_exception(boost::current_exception());
00115                 }
00116             }
00117             const char* name() { return m_name; }
00118 
00119             const char*                 m_name;
00120             const boost::function<R()>& m_functor;
00121             typename promise<R>::ptr    m_prom;
00122     };
00123     template<>
00124     class reftask<void> : public task {
00125             reftask( const boost::function<void()>& f, const  promise<void>::ptr& p, priority prio=priority(),const char* name = "" )
00126             :task(prio),m_functor(f),m_prom(p),m_name(name){}
00127 
00128             void cancel() {
00129                 try {
00130                     BOOST_THROW_EXCEPTION( error::task_canceled() );
00131                 } catch ( ... ) {
00132                     m_prom->set_exception(boost::current_exception());
00133                 }
00134             }
00135             void run() {
00136                 try {
00137                     m_functor();
00138                     m_prom->set_value( void_t());
00139                 } catch( ... ) {
00140                     m_prom->set_exception(boost::current_exception());
00141                 }
00142             }
00143             const char* name() { return m_name; }
00144 
00145             const boost::function<void()>& m_functor;
00146             promise<void>::ptr              m_prom;
00147             const char*                    m_name;
00148     };
00149 
00150 
00151     class vtask : public task {
00152         
00153         public:
00154         vtask( const boost::function<void()>& f, priority prio = priority() )
00155         :task(prio),m_functor(f){
00156         }
00157 
00158         void cancel() {}
00159         void run() {
00160             try {
00161                 m_functor();
00162             } catch( const boost::exception& e ) {
00163                 elog( "%1%", boost::diagnostic_information(e) );
00164             } catch( const std::exception& e ) {
00165                 elog( "%1%", boost::diagnostic_information(e) );
00166             } catch( ... ) {
00167                 BOOST_ASSERT(!"unhandled exception");
00168             }
00169         }
00170         boost::function<void()> m_functor;
00171     };
00172 
00173 } } // namespace boost cmt
00174 
00175 #endif // BOOST_CMT_TASK_HPP
 All Classes Namespaces Files Functions Variables Typedefs Defines