future.hpp
Go to the documentation of this file.
00001 
00017 #ifndef THREADPOOL_DETAIL_FUTURE_IMPL_HPP_INCLUDED
00018 #define THREADPOOL_DETAIL_FUTURE_IMPL_HPP_INCLUDED
00019 
00020 
00021 #include "locking_ptr.hpp"
00022 
00023 #include <boost/smart_ptr.hpp>
00024 #include <boost/optional.hpp>
00025 #include <boost/thread/mutex.hpp>
00026 #include <boost/thread/condition.hpp>
00027 #include <boost/thread/xtime.hpp>
00028 #include <boost/utility/result_of.hpp>
00029 #include <boost/static_assert.hpp>
00030 #include <boost/type_traits.hpp>
00031 
00032 namespace boost { namespace threadpool { namespace detail 
00033 {
00034 
00035 template<class Result> 
00036 class future_impl
00037 {
00038 public:
00039   typedef Result const & result_type; 
00040 
00041   typedef Result future_result_type; 
00042   typedef future_impl<future_result_type> future_type;
00043 
00044 private:
00045     volatile bool m_ready;
00046     volatile future_result_type m_result;
00047 
00048     mutable mutex m_monitor;
00049     mutable condition m_condition_ready;        
00050 
00051     volatile bool m_is_cancelled;
00052     volatile bool m_executing;
00053 
00054 public:
00055 
00056 
00057 public:
00058 
00059   future_impl()
00060   : m_ready(false)
00061   , m_is_cancelled(false)
00062   {
00063   }
00064 
00065   bool ready() const volatile
00066   {
00067     return m_ready; 
00068   }
00069 
00070   void wait() const volatile
00071   {
00072     const future_type* self = const_cast<const future_type*>(this);
00073     mutex::scoped_lock lock(self->m_monitor);
00074 
00075     while(!m_ready)
00076     {
00077       self->m_condition_ready.wait(lock);
00078     }
00079   }
00080 
00081 
00082   bool timed_wait(boost::xtime const & timestamp) const
00083   {
00084     const future_type* self = const_cast<const future_type*>(this);
00085     mutex::scoped_lock lock(self->m_monitor);
00086 
00087     while(!m_ready)
00088     {
00089       if(!self->m_condition_ready.timed_wait(lock, timestamp)) return false;
00090     }
00091 
00092     return true;
00093   }
00094 
00095 
00096   result_type operator()() const volatile
00097   {
00098     wait();
00099 /*
00100     if( throw_exception_ != 0 )
00101     {
00102       throw_exception_( this );
00103     }
00104 */
00105  
00106     return *(const_cast<const future_result_type*>(&m_result));
00107   }
00108 
00109 
00110   void set_value(future_result_type const & r) volatile
00111   {
00112     locking_ptr<future_type, mutex> lockedThis(*this, m_monitor);
00113     if(!m_ready && !m_is_cancelled)
00114     {
00115       lockedThis->m_result = r;
00116       lockedThis->m_ready = true;
00117       lockedThis->m_condition_ready.notify_all();
00118     }
00119   }
00120 /*
00121   template<class E> void set_exception() // throw()
00122   {
00123     m_impl->template set_exception<E>();
00124   }
00125 
00126   template<class E> void set_exception( char const * what ) // throw()
00127   {
00128     m_impl->template set_exception<E>( what );
00129   }
00130   */
00131 
00132 
00133    bool cancel() volatile
00134    {
00135      if(!m_ready || m_executing)
00136      {
00137         m_is_cancelled = true;
00138         return true;
00139      }
00140      else
00141      {
00142        return false;
00143      }
00144    }
00145 
00146 
00147    bool is_cancelled() const volatile
00148    {
00149      return m_is_cancelled;
00150    }
00151 
00152 
00153    void set_execution_status(bool executing) volatile
00154    {
00155      m_executing = executing;
00156    }
00157 };
00158 
00159 
00160 template<
00161   template <typename> class Future,
00162   typename Function
00163 >
00164 class future_impl_task_func
00165 {
00166 
00167 public:
00168   typedef void result_type;                         
00169 
00170   typedef Function function_type;                   
00171   typedef typename result_of<function_type()>::type future_result_type; 
00172   typedef Future<future_result_type> future_type;   
00173 
00174   // The task is required to be a nullary function.
00175   BOOST_STATIC_ASSERT(function_traits<function_type()>::arity == 0);
00176 
00177   // The task function's result type is required not to be void.
00178   BOOST_STATIC_ASSERT(!is_void<future_result_type>::value);
00179 
00180 private:
00181   function_type             m_function;
00182   shared_ptr<future_type>   m_future;
00183 
00184 public:
00185   future_impl_task_func(function_type const & function, shared_ptr<future_type> const & future)
00186   : m_function(function)
00187   , m_future(future)
00188   {
00189   }
00190 
00191   void operator()()
00192   {
00193     if(m_function)
00194     {
00195       m_future->set_execution_status(true);
00196       if(!m_future->is_cancelled())
00197       {
00198         // TODO future exeception handling 
00199         m_future->set_value(m_function());
00200       }
00201       m_future->set_execution_status(false); // TODO consider exceptions
00202     }
00203   }
00204 
00205 };
00206 
00207 
00208 
00209 
00210 
00211 } } } // namespace boost::threadpool::detail
00212 
00213 #endif // THREADPOOL_DETAIL_FUTURE_IMPL_HPP_INCLUDED
00214 
00215 


obj_rec_gui
Author(s): AGAS/agas@uni-koblenz.de
autogenerated on Mon Oct 6 2014 02:53:43