SAGA C++ API 1.6
task.cpp
Go to the documentation of this file.
00001 //  Copyright (c) 2005-2007 Andre Merzky (andre@merzky.net)
00002 //  Copyright (c) 2005-2009 Hartmut Kaiser
00003 // 
00004 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
00005 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00006 
00007 #include <utility>
00008 #include <vector>
00009 #include <string>
00010 
00011 #include <boost/assert.hpp>
00012 
00013 #include <saga/saga/adaptors/task.hpp>
00014 #include <saga/saga/url.hpp>
00015 
00016 #include <saga/impl/task.hpp>    // include the task implementation we want to use
00017 
00018 #include <saga/saga/detail/task_get_result_impl.hpp>
00019 #include <saga/saga/detail/monitorable_impl.hpp>
00020 
00022 namespace saga 
00023 {
00024   task::task()
00025   {
00026   }
00027 
00028   task::task (saga::task_base::state s)
00029     : saga::object (new saga::impl::dummy_task(s))
00030   {
00031   }
00032 
00033   task::task (saga::impl::object * init)
00034     : saga::object (init)
00035   {
00036   }
00037 
00038   task::task (saga::object const& o)
00039     : saga::object (o)
00040   {
00041   }
00042 
00043   task::~task (void)
00044   {
00045   }
00046   
00047   task &task::operator= (saga::object const& o)
00048   {
00049       return saga::object::operator=(o), *this;
00050   }
00051 
00052   saga::impl::task_interface* task::get_task_if (void) 
00053   { 
00054     return this->saga::object::get_impl()->get_task_interface();
00055   }
00056   saga::impl::task_interface const* task::get_task_if (void) const
00057   { 
00058     return this->saga::object::get_impl()->get_task_interface();
00059   }
00060 
00062   saga::impl::task_base* task::get_impl (void) const
00063   {
00064       return static_cast<saga::impl::task_base*>(this->object::get_impl());
00065   }
00066 
00067   TR1::shared_ptr <saga::impl::task_base> task::get_impl_sp(void) const
00068   {
00069       return TR1::static_pointer_cast<saga::impl::task_base>(
00070           this->object::get_impl_sp());
00071   }
00072 
00074   bool operator== (task const & lhs, task const & rhs)
00075   {
00076     return lhs.get_task_if() == rhs.get_task_if();
00077   }
00078 
00080   bool operator< (task const & lhs, task const & rhs)
00081   {
00082     return lhs.get_id() < rhs.get_id();
00083   }
00085 
00086   void task::run (void)
00087   {
00088     get_task_if()->run();
00089   }
00090 
00091   void task::cancel (void)
00092   {
00093     get_task_if()->cancel();
00094   }
00095 
00096   bool task::wait (double timeout)
00097   {
00098     return get_task_if()->wait (timeout);
00099 //     bool result = false;
00100 //     while (!result) {
00101 //       result = get_task_if()->wait (timeout);
00102 // 
00103 //       // we retry on any encountered error
00104 //       saga::task_base::state s = get_task_if()->get_state();
00105 //       if (result && saga::task_base::Failed == s)
00106 //       {
00107 //         // throws if no other adaptors are available
00108 //         if (!get_task_if()->restart()) 
00109 //         {
00110 //           get_task_if()->rethrow();
00111 //         }
00112 //         result = false;           // need to retry
00113 //       }
00114 // 
00115 //       // exit, if this wait should not block
00116 //       if (timeout >= 0)
00117 //         break;
00118 //     }
00119 //     return result;
00120   }
00121 
00122   task::state task::get_state (void)
00123   {
00124     return get_task_if()->get_state();
00125 //     task::state s = get_task_if()->get_state();
00126 //     if (saga::task_base::Failed == s)
00127 //     {
00128 //       get_task_if()->restart();
00129 //       s = get_task_if()->get_state();
00130 //     }
00131 //     return s;
00132   }
00133 
00134   void task::rethrow() 
00135   {
00136     if (saga::task_base::Failed == get_task_if()->get_state())
00137     {
00138       get_task_if()->rethrow();                         // must throw
00139 //       // throws if no other adaptors are available
00140 //       get_task_if()->restart();
00141 //       BOOST_ASSERT(saga::task_base::Failed != get_state());
00142     }
00143   }
00144 
00145   saga::object task::get_object() const
00146   {
00147     return get_task_if()->get_object();
00148   }
00149 
00151   //  implement the monitorable functions (we need to explicitly specialize 
00152   //  the template because the functions are not implemented inline)
00153   template struct saga::detail::monitorable<task>;
00154 
00156   //  implement all task::get_result<> functions needed in engine module
00158   namespace detail
00159   {
00160       hold_any& get_task_result(saga::task t)
00161       {
00162           return saga::impl::runtime::get_impl(t)->get_result();
00163       }
00164   }
00166 
00167   // native types
00168   template SAGA_EXPORT std::string&                    task::get_result<std::string>();
00169   template SAGA_EXPORT std::string const&              task::get_result<std::string>() const;
00170   
00171   template SAGA_EXPORT std::vector<std::string>&       task::get_result<std::vector<std::string> >();
00172   template SAGA_EXPORT std::vector<std::string> const& task::get_result<std::vector<std::string> >() const;
00173   
00174   template SAGA_EXPORT bool&                           task::get_result<bool>();
00175   template SAGA_EXPORT bool const&                     task::get_result<bool>() const;
00176   
00177   template SAGA_EXPORT int&                            task::get_result<int>();
00178   template SAGA_EXPORT int const&                      task::get_result<int>() const;
00179   
00180 #if ! defined (SAGA_TYPE_LONG_IS_INT)
00181   template SAGA_EXPORT long&                           task::get_result<long>();
00182   template SAGA_EXPORT long const&                     task::get_result<long>() const;
00183 #endif
00184   
00185 #if ! defined (SAGA_TYPE_LONGLONG_IS_INT) \
00186  && ! defined (SAGA_TYPE_LONGLONG_IS_LONG)
00187   template SAGA_EXPORT long long&                      task::get_result<long long>();
00188   template SAGA_EXPORT long long const&                task::get_result<long long>() const;
00189 #endif
00190   
00191   // saga types
00192 #if ! defined (SAGA_TYPE_SIZE_IS_INT) \
00193  && ! defined (SAGA_TYPE_SIZE_IS_LONG) \
00194  && ! defined (SAGA_TYPE_SIZE_IS_LONGLONG)
00195   template SAGA_EXPORT saga::size_t&                   task::get_result<saga::size_t>();
00196   template SAGA_EXPORT saga::size_t const&             task::get_result<saga::size_t>() const;
00197 #endif
00198 
00199 #if ! defined (SAGA_TYPE_SSIZE_IS_INT)      \
00200  && ! defined (SAGA_TYPE_SSIZE_IS_LONG)     \
00201  && ! defined (SAGA_TYPE_SSIZE_IS_LONGLONG) \
00202  && ! defined (SAGA_TYPE_SSIZE_IS_SIZE)
00203   template SAGA_EXPORT saga::ssize_t&                  task::get_result<saga::ssize_t>();
00204   template SAGA_EXPORT saga::ssize_t const&            task::get_result<saga::ssize_t>() const;
00205 #endif
00206   
00207 #if ! defined (SAGA_TYPE_OFF_IS_INT)      \
00208  && ! defined (SAGA_TYPE_OFF_IS_LONG)     \
00209  && ! defined (SAGA_TYPE_OFF_IS_LONGLONG) \
00210  && ! defined (SAGA_TYPE_OFF_IS_SIZE)     \
00211  && ! defined (SAGA_TYPE_OFF_IS_SSIZE)
00212   template SAGA_EXPORT saga::off_t&                    task::get_result<saga::off_t>();
00213   template SAGA_EXPORT saga::off_t const&              task::get_result<saga::off_t>() const;
00214 #endif
00215 
00216 
00217   // saga classes (no packages)
00218   template SAGA_EXPORT saga::context&                  task::get_result<saga::context>(); 
00219   template SAGA_EXPORT saga::context const&            task::get_result<saga::context>() const;
00220 
00221   template SAGA_EXPORT saga::url&                      task::get_result<saga::url>(); 
00222   template SAGA_EXPORT saga::url const&                task::get_result<saga::url>() const;
00223 
00224   template SAGA_EXPORT std::vector<saga::url>&         task::get_result<std::vector<saga::url> >();
00225   template SAGA_EXPORT std::vector<saga::url> const&   task::get_result<std::vector<saga::url> >() const;
00226 
00227   SAGA_EXPORT void task::get_result()
00228   {
00229       if (saga::task_base::Failed == get_task_if()->get_state())
00230       {
00231           get_task_if()->rethrow();     // must throw
00232       }
00233       get_task_result(*this);   // do synchronization only
00234   }
00235 
00236   SAGA_EXPORT void task::get_result() const
00237   {
00238       if (saga::task_base::Failed == get_task_if()->get_state())
00239       {
00240           get_task_if()->rethrow();     // must throw
00241       }
00242       get_task_result(*this);   // do synchronization only
00243   }
00244 
00245   namespace detail 
00246   {
00248     void set_selector_state(saga::task t,  
00249         TR1::shared_ptr<impl::adaptor_selector_state> state)
00250     {
00251         impl::runtime::get_impl(t)->set_selector_state(state);
00252     }
00253 
00254     // store an exception in a task instance
00255     saga::task set_task_exception(saga::task t, saga::impl::object const *obj,
00256         saga::impl::exception_list const& l, saga::error e)
00257     {
00258         impl::runtime::get_impl(t)->set_task_exception(obj, l, e);
00259         return t;
00260     }
00261 
00262   }
00263 
00265 } // namespace saga
00266 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines