Ticket #7413: 7413_7575.patch
File 7413_7575.patch, 20.3 KB (added by , 10 years ago) |
---|
-
boost/thread/pthread/condition_variable.hpp
289 289 } 290 290 291 291 template <class lock_type> 292 inline voidwait_until(292 cv_status wait_until( 293 293 lock_type& lk, 294 294 chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) 295 295 { … … 299 299 seconds s = duration_cast<seconds>(d); 300 300 ts.tv_sec = static_cast<long>(s.count()); 301 301 ts.tv_nsec = static_cast<long>((d - s).count()); 302 do_timed_wait(lk, ts); 302 if (do_timed_wait(lk, ts)) return cv_status::no_timeout; 303 else return cv_status::timeout; 303 304 } 304 305 #endif 305 306 -
boost/thread/pthread/condition_variable_fwd.hpp
212 212 void notify_all() BOOST_NOEXCEPT; 213 213 214 214 #ifdef BOOST_THREAD_USES_CHRONO 215 inline voidwait_until(215 inline cv_status wait_until( 216 216 unique_lock<mutex>& lk, 217 217 chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) 218 218 { … … 222 222 seconds s = duration_cast<seconds>(d); 223 223 ts.tv_sec = static_cast<long>(s.count()); 224 224 ts.tv_nsec = static_cast<long>((d - s).count()); 225 do_timed_wait(lk, ts); 225 if (do_timed_wait(lk, ts)) return cv_status::no_timeout; 226 else return cv_status::timeout; 226 227 } 227 228 #endif 228 229 //private: // used by boost::thread::try_join_until -
boost/thread/future.hpp
18 18 #include <boost/detail/scoped_enum_emulation.hpp> 19 19 #include <stdexcept> 20 20 #include <boost/thread/detail/move.hpp> 21 #include <boost/thread/detail/async_func.hpp> 21 22 #include <boost/thread/thread_time.hpp> 22 23 #include <boost/thread/mutex.hpp> 23 24 #include <boost/thread/condition_variable.hpp> … … 42 43 #include <list> 43 44 #include <boost/next_prior.hpp> 44 45 #include <vector> 46 45 47 #include <boost/system/error_code.hpp> 46 48 #ifdef BOOST_THREAD_USES_CHRONO 47 49 #include <boost/chrono/system_clocks.hpp> … … 206 208 207 209 namespace future_state 208 210 { 209 enum state { uninitialized, waiting, ready, moved };211 enum state { uninitialized, waiting, ready, moved, deferred }; 210 212 } 211 213 212 214 namespace detail … … 259 261 { 260 262 boost::exception_ptr exception; 261 263 bool done; 264 bool is_deferred; 262 265 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 263 266 bool thread_was_interrupted; 264 267 #endif … … 273 276 274 277 future_object_base(): 275 278 done(false), 279 is_deferred(false) 276 280 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 277 thread_was_interrupted(false)281 , thread_was_interrupted(false) 278 282 #endif 279 283 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 280 284 , continuation_ptr() … … 283 287 virtual ~future_object_base() 284 288 {} 285 289 290 void set_deferred() {is_deferred = true;} 291 286 292 waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv) 287 293 { 288 294 boost::unique_lock<boost::mutex> lock(mutex); … … 342 348 343 349 void wait_internal(boost::unique_lock<boost::mutex> &lock, bool rethrow=true) 344 350 { 345 do_callback(lock); 346 while(!done) 351 do_callback(lock); 352 //if (!done) 353 { 354 if (is_deferred) 347 355 { 348 waiters.wait(lock); 356 is_deferred=false; 357 execute(lock); 358 //lock.unlock(); 349 359 } 360 else 361 { 362 while(!done) 363 { 364 waiters.wait(lock); 365 } 350 366 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 351 if(rethrow && thread_was_interrupted)352 {353 throw boost::thread_interrupted();354 }367 if(rethrow && thread_was_interrupted) 368 { 369 throw boost::thread_interrupted(); 370 } 355 371 #endif 356 if(rethrow && exception) 357 { 358 boost::rethrow_exception(exception); 372 if(rethrow && exception) 373 { 374 boost::rethrow_exception(exception); 375 } 359 376 } 360 377 } 361 378 } 362 379 void wait(bool rethrow=true) 363 380 { … … 369 386 bool timed_wait_until(boost::system_time const& target_time) 370 387 { 371 388 boost::unique_lock<boost::mutex> lock(mutex); 389 if (is_deferred) 390 return false; 391 372 392 do_callback(lock); 373 393 while(!done) 374 394 { … … 388 408 wait_until(const chrono::time_point<Clock, Duration>& abs_time) 389 409 { 390 410 boost::unique_lock<boost::mutex> lock(mutex); 411 if (is_deferred) 412 return future_status::deferred; 391 413 do_callback(lock); 392 414 while(!done) 393 415 { … … 434 456 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 435 457 || thread_was_interrupted 436 458 #endif 437 );459 ); 438 460 } 439 461 440 462 template<typename F,typename U> … … 442 464 { 443 465 callback=boost::bind(f,boost::ref(*u)); 444 466 } 467 virtual void execute(boost::unique_lock<boost::mutex>&) {} 445 468 446 469 private: 447 470 future_object_base(future_object_base const&); … … 649 672 future_object& operator=(future_object const&); 650 673 }; 651 674 675 /// future_async_object 676 template<typename Rp, typename Fp> 677 struct future_async_object: future_object<Rp> 678 { 679 typedef future_object<Rp> base_type; 680 Fp func_; 681 boost::thread thr_; 682 683 public: 684 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 685 explicit future_async_object(Fp&& f) 686 : func_(boost::forward<Fp>(f)) 687 #else 688 explicit future_async_object(Fp f) 689 : func_(f) 690 #endif 691 , thr_(&future_async_object::execute, *this) 692 { 693 } 694 695 ~future_async_object() 696 { 697 thr_.join(); 698 } 699 700 virtual void execute(boost::unique_lock<boost::mutex>& lock) { 701 try 702 { 703 this->mark_finished_with_result_internal(func_(), lock); 704 } 705 catch (...) 706 { 707 this->mark_exceptional_finish_internal(current_exception(), lock); 708 } 709 710 } 711 712 }; 713 714 template<typename Fp> 715 struct future_async_object<void, Fp>: public future_object<void> 716 { 717 typedef future_object<void> base_type; 718 Fp func_; 719 boost::thread thr_; 720 721 public: 722 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 723 explicit future_async_object(Fp&& f) 724 : func_(boost::forward<Fp>(f)) 725 #else 726 explicit future_async_object(Fp f) 727 : func_(f) 728 #endif 729 , thr_(&future_async_object::execute, *this) 730 { 731 } 732 733 ~future_async_object() 734 { 735 thr_.join(); 736 } 737 738 virtual void execute(boost::unique_lock<boost::mutex>& lock) { 739 try 740 { 741 func_(); 742 this->mark_finished_with_result_internal(lock); 743 } 744 catch (...) 745 { 746 this->mark_exceptional_finish_internal(current_exception(), lock); 747 } 748 749 } 750 751 }; 752 /// future_deferred_object 753 template<typename Rp, typename Fp> 754 struct future_deferred_object: future_object<Rp> 755 { 756 typedef future_object<Rp> base_type; 757 Fp func_; 758 759 public: 760 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 761 explicit future_deferred_object(Fp&& f) 762 : func_(boost::forward<Fp>(f)) 763 #else 764 explicit future_deferred_object(Fp f) 765 : func_(f) 766 #endif 767 { 768 this->set_deferred(); 769 } 770 771 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 772 try 773 { 774 this->mark_finished_with_result_internal(func_(), lck); 775 } 776 catch (...) 777 { 778 this->mark_exceptional_finish_internal(current_exception(), lck); 779 } 780 } 781 }; 782 783 template<typename Fp> 784 struct future_deferred_object<void,Fp>: future_object<void> 785 { 786 typedef future_object<void> base_type; 787 Fp func_; 788 789 public: 790 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 791 explicit future_deferred_object(Fp&& f) 792 : func_(boost::forward<Fp>(f)) 793 #else 794 explicit future_deferred_object(Fp f) 795 : func_(f) 796 #endif 797 { 798 this->set_deferred(); 799 } 800 801 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 802 try 803 { 804 func_(); 805 this->mark_finished_with_result_internal(lck); 806 } 807 catch (...) 808 { 809 this->mark_exceptional_finish_internal(current_exception(), lck); 810 } 811 } 812 }; 813 652 814 // template<typename T, typename Allocator> 653 815 // struct future_object_alloc: public future_object<T> 654 816 // { … … 1019 1181 } // detail 1020 1182 BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END 1021 1183 1184 namespace detail 1185 { 1186 template <class Rp, class Fp> 1187 BOOST_THREAD_FUTURE<Rp> 1188 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 1189 make_future_async_object(Fp&& f); 1190 #else 1191 make_future_async_object(Fp f); 1192 #endif 1193 1194 template <class Rp, class Fp> 1195 BOOST_THREAD_FUTURE<Rp> 1196 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 1197 make_future_deferred_object(Fp&& f); 1198 #else 1199 make_future_deferred_object(Fp f); 1200 #endif 1201 } 1202 1022 1203 template <typename R> 1023 1204 class BOOST_THREAD_FUTURE : public detail::basic_future<R> 1024 1205 { … … 1039 1220 #endif 1040 1221 friend class detail::future_waiter; 1041 1222 1223 template <class Rp, class Fp> 1224 friend BOOST_THREAD_FUTURE<Rp> 1225 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 1226 detail::make_future_async_object(Fp&& f); 1227 #else 1228 detail::make_future_async_object(Fp f); 1229 #endif 1230 1231 template <class Rp, class Fp> 1232 friend BOOST_THREAD_FUTURE<Rp> 1233 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 1234 detail::make_future_deferred_object(Fp&& f); 1235 #else 1236 detail::make_future_deferred_object(Fp f); 1237 #endif 1238 1042 1239 typedef typename detail::future_traits<R>::move_dest_type move_dest_type; 1043 1240 1044 1241 BOOST_THREAD_FUTURE(future_ptr a_future): … … 2094 2291 2095 2292 BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END 2096 2293 2294 namespace detail 2295 { 2296 //////////////////////////////// 2297 // make_future_deferred_object 2298 //////////////////////////////// 2299 template <class Rp, class Fp> 2300 BOOST_THREAD_FUTURE<Rp> 2301 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 2302 make_future_deferred_object(Fp&& f) 2303 #else 2304 make_future_deferred_object(Fp f) 2305 #endif 2306 { 2307 shared_ptr<future_deferred_object<Rp, Fp> > 2308 h(new future_deferred_object<Rp, Fp>(boost::forward<Fp>(f))); 2309 return BOOST_THREAD_FUTURE<Rp>(h); 2310 } 2311 2312 //////////////////////////////// 2313 // make_future_async_object 2314 //////////////////////////////// 2315 template <class Rp, class Fp> 2316 BOOST_THREAD_FUTURE<Rp> 2317 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 2318 make_future_async_object(Fp&& f) 2319 #else 2320 make_future_async_object(Fp f) 2321 #endif 2322 { 2323 shared_ptr<future_async_object<Rp, Fp> > 2324 h(new future_async_object<Rp, Fp>(boost::forward<Fp>(f))); 2325 return BOOST_THREAD_FUTURE<Rp>(h); 2326 } 2327 2328 } 2329 2330 //////////////////////////////// 2331 // template <class F, class... ArgTypes> 2332 // future<R> async(F&&, ArgTypes&&...); 2333 //////////////////////////////// 2334 2097 2335 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR 2098 2336 2099 2337 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK … … 2164 2402 typename decay<ArgTypes>::type... 2165 2403 )>::type R; 2166 2404 typedef packaged_task<R(ArgTypes...)> packaged_task_type; 2405 2406 typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF; 2407 typedef typename BF::result_type Rp; 2408 2167 2409 #else 2168 2410 template <class F> 2169 2411 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> … … 2171 2413 { 2172 2414 typedef typename boost::result_of<typename decay<F>::type()>::type R; 2173 2415 typedef packaged_task<R()> packaged_task_type; 2416 2417 typedef detail::async_func<typename decay<F>::type> BF; 2418 typedef typename BF::result_type Rp; 2419 2174 2420 #endif 2175 2421 #else 2176 2422 template <class F> … … 2179 2425 { 2180 2426 typedef typename boost::result_of<typename decay<F>::type()>::type R; 2181 2427 typedef packaged_task<R> packaged_task_type; 2428 2429 typedef detail::async_func<typename decay<F>::type> BF; 2430 typedef typename BF::result_type Rp; 2182 2431 #endif 2183 2432 2184 2433 if (int(policy) & int(launch::async)) … … 2195 2444 } 2196 2445 else if (int(policy) & int(launch::deferred)) 2197 2446 { 2198 packaged_task_type pt( boost::forward<F>(f) ); 2447 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2448 return boost::detail::make_future_deferred_object<Rp>( 2449 BF( 2450 thread_detail::decay_copy(boost::forward<F>(f)) 2451 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))... 2452 ) 2453 ); 2454 #else 2455 BOOST_THREAD_FUTURE<R> ret; 2456 return ::boost::move(ret); 2457 // return boost::detail::make_future_deferred_object<Rp>( 2458 // BF( 2459 // thread_detail::decay_copy(boost::forward<F>(f)) 2460 // ) 2461 // ); 2462 #endif 2199 2463 2200 BOOST_THREAD_FUTURE<R> ret = pt.get_future();2201 return ::boost::move(ret);2202 2464 } else { 2203 2465 BOOST_THREAD_FUTURE<R> ret; 2204 2466 return ::boost::move(ret); … … 2211 2473 return async(launch::any, boost::forward<F>(f)); 2212 2474 } 2213 2475 2476 2477 //////////////////////////////// 2478 // make_future 2479 //////////////////////////////// 2214 2480 template <typename T> 2215 2481 BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) 2216 2482 { … … 2228 2494 2229 2495 } 2230 2496 2497 //////////////////////////////// 2498 // make_shared_future 2499 //////////////////////////////// 2231 2500 template <typename T> 2232 2501 shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) 2233 2502 { … … 2245 2514 2246 2515 } 2247 2516 2517 //////////////////////////////// 2518 // detail::future_continuation 2519 //////////////////////////////// 2248 2520 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 2249 2521 namespace detail 2250 2522 { … … 2318 2590 #endif 2319 2591 } 2320 2592 2321 // template<typename F> 2322 // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>; 2593 //////////////////////////////// 2594 // template<typename F> 2595 // auto future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>; 2596 //////////////////////////////// 2323 2597 2324 2598 template <typename R> 2325 2599 template <typename F> -
boost/thread/detail/move.hpp
230 230 231 231 232 232 233 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES234 233 namespace boost 235 234 { namespace thread_detail 236 235 { 236 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 237 237 template <class T> 238 238 typename decay<T>::type 239 239 decay_copy(T&& t) 240 240 { 241 241 return boost::forward<T>(t); 242 242 } 243 #else 244 template <class T> 245 typename decay<T>::type 246 decay_copy(BOOST_THREAD_FWD_REF(T) t) 247 { 248 return boost::forward<T>(t); 243 249 } 250 #endif 251 } 244 252 } 245 #endif246 253 247 254 #include <boost/config/abi_suffix.hpp> 248 255 -
libs/thread/test/sync/futures/async/async_pass.cpp
145 145 Clock::time_point t1 = Clock::now(); 146 146 BOOST_TEST(t1 - t0 < ms(100)); 147 147 } 148 // { 149 // boost::future<int> f = boost::async(boost::launch::deferred, f0); 150 // boost::this_thread::sleep_for(ms(300)); 151 // Clock::time_point t0 = Clock::now(); 152 // BOOST_TEST(f.get() == 3); 153 // Clock::time_point t1 = Clock::now(); 154 // BOOST_TEST(t1 - t0 > ms(100)); 155 // } 156 // 148 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 157 149 { 150 boost::future<int> f = boost::async(boost::launch::deferred, f0); 151 boost::this_thread::sleep_for(ms(300)); 152 Clock::time_point t0 = Clock::now(); 153 BOOST_TEST(f.get() == 3); 154 Clock::time_point t1 = Clock::now(); 155 BOOST_TEST(t1 - t0 > ms(100)); 156 } 157 #endif 158 { 158 159 boost::future<int&> f = boost::async(f1); 159 160 boost::this_thread::sleep_for(ms(300)); 160 161 Clock::time_point t0 = Clock::now(); … … 178 179 Clock::time_point t1 = Clock::now(); 179 180 BOOST_TEST(t1 - t0 < ms(100)); 180 181 } 181 // { 182 // boost::future<int&> f = boost::async(boost::launch::deferred, f1); 183 // boost::this_thread::sleep_for(ms(300)); 184 // Clock::time_point t0 = Clock::now(); 185 // BOOST_TEST(&f.get() == &i); 186 // Clock::time_point t1 = Clock::now(); 187 // BOOST_TEST(t1 - t0 > ms(100)); 188 // } 189 // 182 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 190 183 { 184 boost::future<int&> f = boost::async(boost::launch::deferred, f1); 185 boost::this_thread::sleep_for(ms(300)); 186 Clock::time_point t0 = Clock::now(); 187 BOOST_TEST(&f.get() == &i); 188 Clock::time_point t1 = Clock::now(); 189 BOOST_TEST(t1 - t0 > ms(100)); 190 } 191 #endif 192 { 191 193 boost::future<void> f = boost::async(f2); 192 194 boost::this_thread::sleep_for(ms(300)); 193 195 Clock::time_point t0 = Clock::now(); … … 211 213 Clock::time_point t1 = Clock::now(); 212 214 BOOST_TEST(t1 - t0 < ms(100)); 213 215 } 214 // { 215 // boost::future<void> f = boost::async(boost::launch::deferred, f2); 216 // boost::this_thread::sleep_for(ms(300)); 217 // Clock::time_point t0 = Clock::now(); 218 // f.get(); 219 // Clock::time_point t1 = Clock::now(); 220 // BOOST_TEST(t1 - t0 > ms(100)); 221 // } 216 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 217 { 218 boost::future<void> f = boost::async(boost::launch::deferred, f2); 219 boost::this_thread::sleep_for(ms(300)); 220 Clock::time_point t0 = Clock::now(); 221 f.get(); 222 Clock::time_point t1 = Clock::now(); 223 BOOST_TEST(t1 - t0 > ms(100)); 224 } 225 #endif 226 227 // todo fixme 222 228 #if 0 && defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 223 229 { 224 230 boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f3, 3); … … 230 236 } 231 237 #endif 232 238 239 // todo fixme 233 240 #if 0 && defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 234 241 { 235 242 boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));