Ticket #5990: 5590_5531.diff
File 5590_5531.diff, 7.7 KB (added by , 11 years ago) |
---|
-
future.hpp
6 6 7 7 #ifndef BOOST_THREAD_FUTURE_HPP 8 8 #define BOOST_THREAD_FUTURE_HPP 9 9 10 #include <stdexcept> 10 11 #include <boost/thread/detail/move.hpp> 11 12 #include <boost/thread/thread_time.hpp> … … 93 94 { 94 95 boost::exception_ptr exception; 95 96 bool done; 97 bool thread_was_interrupted; 96 98 boost::mutex mutex; 97 99 boost::condition_variable waiters; 98 100 typedef std::list<boost::condition_variable_any*> waiter_list; … … 100 102 boost::function<void()> callback; 101 103 102 104 future_object_base(): 103 done(false) 105 done(false), 106 thread_was_interrupted(false) 104 107 {} 105 108 virtual ~future_object_base() 106 109 {} … … 165 168 { 166 169 waiters.wait(lock); 167 170 } 171 if(rethrow && thread_was_interrupted) 172 { 173 throw boost::thread_interrupted(); 174 } 168 175 if(rethrow && exception) 169 176 { 170 177 boost::rethrow_exception(exception); … … 196 203 boost::lock_guard<boost::mutex> lock(mutex); 197 204 mark_exceptional_finish_internal(boost::current_exception()); 198 205 } 199 206 void mark_interrupted_finish() 207 { 208 boost::lock_guard<boost::mutex> lock(mutex); 209 thread_was_interrupted=true; 210 mark_finished_internal(); 211 } 200 212 bool has_value() 201 213 { 202 214 boost::lock_guard<boost::mutex> lock(mutex); 203 return done && ! exception;215 return done && !(exception || thread_was_interrupted); 204 216 } 205 217 bool has_exception() 206 218 { 207 219 boost::lock_guard<boost::mutex> lock(mutex); 208 return done && exception;220 return done && (exception || thread_was_interrupted); 209 221 } 210 222 211 223 template<typename F,typename U> … … 233 245 typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type; 234 246 typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T>::type move_dest_type; 235 247 #endif 248 typedef const T& shared_future_get_result_type; 236 249 237 250 static void init(storage_type& storage,source_reference_type t) 238 251 { … … 258 271 struct rvalue_source_type 259 272 {}; 260 273 typedef T& move_dest_type; 274 typedef T& shared_future_get_result_type; 261 275 262 276 static void init(storage_type& storage,T& t) 263 277 { … … 275 289 { 276 290 typedef bool storage_type; 277 291 typedef void move_dest_type; 292 typedef void shared_future_get_result_type; 278 293 279 294 static void init(storage_type& storage) 280 295 { … … 296 311 typedef typename future_traits<T>::source_reference_type source_reference_type; 297 312 typedef typename future_traits<T>::rvalue_source_type rvalue_source_type; 298 313 typedef typename future_traits<T>::move_dest_type move_dest_type; 314 typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type; 299 315 300 316 storage_type result; 301 317 … … 331 347 return static_cast<move_dest_type>(*result); 332 348 } 333 349 350 shared_future_get_result_type get_sh() 351 { 352 wait(); 353 return static_cast<shared_future_get_result_type>(*result); 354 } 355 334 356 future_state::state get_state() 335 357 { 336 358 boost::lock_guard<boost::mutex> guard(mutex); … … 353 375 struct future_object<void>: 354 376 detail::future_object_base 355 377 { 356 typedef void move_dest_type;378 typedef void shared_future_get_result_type; 357 379 358 380 future_object() 359 381 {} … … 373 395 { 374 396 wait(); 375 397 } 376 398 void get_sh() 399 { 400 wait(); 401 } 377 402 future_state::state get_state() 378 403 { 379 404 boost::lock_guard<boost::mutex> guard(mutex); … … 413 438 414 439 struct all_futures_lock 415 440 { 416 #ifdef _MANAGED 417 typedef std::ptrdiff_t count_type_portable; 418 #else 419 typedef count_type count_type_portable; 420 #endif 421 count_type_portable count; 422 441 count_type count; 423 442 boost::scoped_array<boost::unique_lock<boost::mutex> > locks; 424 443 425 444 all_futures_lock(std::vector<registered_waiter>& futures): 426 445 count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count]) 427 446 { 428 for(count_type _portablei=0;i<count;++i)447 for(count_type i=0;i<count;++i) 429 448 { 430 449 #if defined __DECCXX || defined __SUNPRO_CC 431 450 locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex).move(); … … 442 461 443 462 void unlock() 444 463 { 445 for(count_type _portablei=0;i<count;++i)464 for(count_type i=0;i<count;++i) 446 465 { 447 466 locks[i].unlock(); 448 467 } … … 849 868 } 850 869 851 870 // retrieving the value 852 //typename detail::future_object<R>::move_dest_type get()853 R get()871 typename detail::future_object<R>::shared_future_get_result_type get() 872 //R get() 854 873 { 855 874 if(!future) 856 875 { 857 876 boost::throw_exception(future_uninitialized()); 858 877 } 859 878 860 return future->get ();879 return future->get_sh(); 861 880 } 862 881 863 882 // functions to check state, and wait for ready … … 1235 1254 f(f_) 1236 1255 {} 1237 1256 #endif 1238 1239 1257 void do_run() 1240 1258 { 1241 1259 try 1242 1260 { 1243 1261 this->mark_finished_with_result(f()); 1244 1262 } 1263 catch(thread_interrupted& it) 1264 { 1265 this->mark_interrupted_finish(); 1266 } 1245 1267 catch(...) 1246 1268 { 1247 1269 this->mark_exceptional_finish(); … … 1266 1288 f(f_) 1267 1289 {} 1268 1290 #endif 1269 1270 1291 void do_run() 1271 1292 { 1272 1293 try … … 1274 1295 f(); 1275 1296 this->mark_finished_with_result(); 1276 1297 } 1298 catch(thread_interrupted& it) 1299 { 1300 this->mark_interrupted_finish(); 1301 } 1277 1302 catch(...) 1278 1303 { 1279 1304 this->mark_exceptional_finish(); … … 1318 1343 task(new detail::task_object<R,F>(f)),future_obtained(false) 1319 1344 {} 1320 1345 #endif 1321 1322 1346 // template <class F, class Allocator> 1323 1347 // explicit packaged_task(F const& f, Allocator a); 1324 1348 // template <class F, class Allocator> … … 1335 1359 1336 1360 // assignment 1337 1361 #ifndef BOOST_NO_RVALUE_REFERENCES 1362 1338 1363 packaged_task(packaged_task&& other): 1339 1364 future_obtained(other.future_obtained) 1340 1365 { … … 1366 1391 } 1367 1392 #endif 1368 1393 1369 void swap(packaged_task& other)1394 void swap(packaged_task& other) 1370 1395 { 1371 1396 task.swap(other.task); 1372 1397 std::swap(future_obtained,other.future_obtained);