SAGA Adaptor CPI v.1.0
|
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