PageRenderTime 112ms CodeModel.GetById 23ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/thread/future.hpp

http://hadesmem.googlecode.com/
C++ Header | 1383 lines | 1166 code | 190 blank | 27 comment | 61 complexity | f96b20aff35d05ba065aca7abae43f40 MD5 | raw file
   1//  (C) Copyright 2008-10 Anthony Williams 
   2//
   3//  Distributed under the Boost Software License, Version 1.0. (See
   4//  accompanying file LICENSE_1_0.txt or copy at
   5//  http://www.boost.org/LICENSE_1_0.txt)
   6
   7#ifndef BOOST_THREAD_FUTURE_HPP
   8#define BOOST_THREAD_FUTURE_HPP
   9#include <stdexcept>
  10#include <boost/thread/detail/move.hpp>
  11#include <boost/thread/thread_time.hpp>
  12#include <boost/thread/mutex.hpp>
  13#include <boost/thread/condition_variable.hpp>
  14#include <boost/exception_ptr.hpp>
  15#include <boost/shared_ptr.hpp>
  16#include <boost/scoped_ptr.hpp>
  17#include <boost/type_traits/is_fundamental.hpp>
  18#include <boost/type_traits/is_convertible.hpp>
  19#include <boost/mpl/if.hpp>
  20#include <boost/config.hpp>
  21#include <boost/throw_exception.hpp>
  22#include <algorithm>
  23#include <boost/function.hpp>
  24#include <boost/bind.hpp>
  25#include <boost/ref.hpp>
  26#include <boost/scoped_array.hpp>
  27#include <boost/utility/enable_if.hpp>
  28#include <list>
  29#include <boost/next_prior.hpp>
  30#include <vector>
  31
  32namespace boost
  33{
  34    class future_uninitialized:
  35        public std::logic_error
  36    {
  37    public:
  38        future_uninitialized():
  39            std::logic_error("Future Uninitialized")
  40        {}
  41    };
  42    class broken_promise:
  43        public std::logic_error
  44    {
  45    public:
  46        broken_promise():
  47            std::logic_error("Broken promise")
  48        {}
  49    };
  50    class future_already_retrieved:
  51        public std::logic_error
  52    {
  53    public:
  54        future_already_retrieved():
  55            std::logic_error("Future already retrieved")
  56        {}
  57    };
  58    class promise_already_satisfied:
  59        public std::logic_error
  60    {
  61    public:
  62        promise_already_satisfied():
  63            std::logic_error("Promise already satisfied")
  64        {}
  65    };
  66
  67    class task_already_started:
  68        public std::logic_error
  69    {
  70    public:
  71        task_already_started():
  72            std::logic_error("Task already started")
  73        {}
  74    };
  75
  76    class task_moved:
  77        public std::logic_error
  78    {
  79    public:
  80        task_moved():
  81            std::logic_error("Task moved")
  82        {}
  83    };
  84
  85    namespace future_state
  86    {
  87        enum state { uninitialized, waiting, ready, moved };
  88    }
  89
  90    namespace detail
  91    {
  92        struct future_object_base
  93        {
  94            boost::exception_ptr exception;
  95            bool done;
  96            boost::mutex mutex;
  97            boost::condition_variable waiters;
  98            typedef std::list<boost::condition_variable_any*> waiter_list;
  99            waiter_list external_waiters;
 100            boost::function<void()> callback;
 101
 102            future_object_base():
 103                done(false)
 104            {}
 105            virtual ~future_object_base()
 106            {}
 107
 108            waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
 109            {
 110                boost::unique_lock<boost::mutex> lock(mutex);
 111                do_callback(lock);
 112                return external_waiters.insert(external_waiters.end(),&cv);
 113            }
 114            
 115            void remove_external_waiter(waiter_list::iterator it)
 116            {
 117                boost::lock_guard<boost::mutex> lock(mutex);
 118                external_waiters.erase(it);
 119            }
 120
 121            void mark_finished_internal()
 122            {
 123                done=true;
 124                waiters.notify_all();
 125                for(waiter_list::const_iterator it=external_waiters.begin(),
 126                        end=external_waiters.end();it!=end;++it)
 127                {
 128                    (*it)->notify_all();
 129                }
 130            }
 131
 132            struct relocker
 133            {
 134                boost::unique_lock<boost::mutex>& lock;
 135                
 136                relocker(boost::unique_lock<boost::mutex>& lock_):
 137                    lock(lock_)
 138                {
 139                    lock.unlock();
 140                }
 141                ~relocker()
 142                {
 143                    lock.lock();
 144                }
 145            private:
 146                relocker& operator=(relocker const&);
 147            };
 148
 149            void do_callback(boost::unique_lock<boost::mutex>& lock)
 150            {
 151                if(callback && !done)
 152                {
 153                    boost::function<void()> local_callback=callback;
 154                    relocker relock(lock);
 155                    local_callback();
 156                }
 157            }
 158            
 159
 160            void wait(bool rethrow=true)
 161            {
 162                boost::unique_lock<boost::mutex> lock(mutex);
 163                do_callback(lock);
 164                while(!done)
 165                {
 166                    waiters.wait(lock);
 167                }
 168                if(rethrow && exception)
 169                {
 170                    boost::rethrow_exception(exception);
 171                }
 172            }
 173
 174            bool timed_wait_until(boost::system_time const& target_time)
 175            {
 176                boost::unique_lock<boost::mutex> lock(mutex);
 177                do_callback(lock);
 178                while(!done)
 179                {
 180                    bool const success=waiters.timed_wait(lock,target_time);
 181                    if(!success && !done)
 182                    {
 183                        return false;
 184                    }
 185                }
 186                return true;
 187            }
 188            
 189            void mark_exceptional_finish_internal(boost::exception_ptr const& e)
 190            {
 191                exception=e;
 192                mark_finished_internal();
 193            }
 194            void mark_exceptional_finish()
 195            {
 196                boost::lock_guard<boost::mutex> lock(mutex);
 197                mark_exceptional_finish_internal(boost::current_exception());
 198            }
 199
 200            bool has_value()
 201            {
 202                boost::lock_guard<boost::mutex> lock(mutex);
 203                return done && !exception;
 204            }
 205            bool has_exception()
 206            {
 207                boost::lock_guard<boost::mutex> lock(mutex);
 208                return done && exception;
 209            }
 210
 211            template<typename F,typename U>
 212            void set_wait_callback(F f,U* u)
 213            {
 214                callback=boost::bind(f,boost::ref(*u));
 215            }
 216            
 217        private:
 218            future_object_base(future_object_base const&);
 219            future_object_base& operator=(future_object_base const&);
 220        };
 221
 222        template<typename T>
 223        struct future_traits
 224        {
 225            typedef boost::scoped_ptr<T> storage_type;
 226#ifndef BOOST_NO_RVALUE_REFERENCES
 227            typedef T const& source_reference_type;
 228            struct dummy;
 229            typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type;
 230            typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type;
 231#else
 232            typedef T& source_reference_type;
 233            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            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#endif
 236
 237            static void init(storage_type& storage,source_reference_type t)
 238            {
 239                storage.reset(new T(t));
 240            }
 241            
 242            static void init(storage_type& storage,rvalue_source_type t)
 243            {
 244                storage.reset(new T(static_cast<rvalue_source_type>(t)));
 245            }
 246
 247            static void cleanup(storage_type& storage)
 248            {
 249                storage.reset();
 250            }
 251        };
 252        
 253        template<typename T>
 254        struct future_traits<T&>
 255        {
 256            typedef T* storage_type;
 257            typedef T& source_reference_type;
 258            struct rvalue_source_type
 259            {};
 260            typedef T& move_dest_type;
 261
 262            static void init(storage_type& storage,T& t)
 263            {
 264                storage=&t;
 265            }
 266
 267            static void cleanup(storage_type& storage)
 268            {
 269                storage=0;
 270            }
 271        };
 272
 273        template<>
 274        struct future_traits<void>
 275        {
 276            typedef bool storage_type;
 277            typedef void move_dest_type;
 278
 279            static void init(storage_type& storage)
 280            {
 281                storage=true;
 282            }
 283
 284            static void cleanup(storage_type& storage)
 285            {
 286                storage=false;
 287            }
 288
 289        };
 290
 291        template<typename T>
 292        struct future_object:
 293            detail::future_object_base
 294        {
 295            typedef typename future_traits<T>::storage_type storage_type;
 296            typedef typename future_traits<T>::source_reference_type source_reference_type;
 297            typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;
 298            typedef typename future_traits<T>::move_dest_type move_dest_type;
 299            
 300            storage_type result;
 301
 302            future_object():
 303                result(0)
 304            {}
 305
 306            void mark_finished_with_result_internal(source_reference_type result_)
 307            {
 308                future_traits<T>::init(result,result_);
 309                mark_finished_internal();
 310            }
 311            void mark_finished_with_result_internal(rvalue_source_type result_)
 312            {
 313                future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
 314                mark_finished_internal();
 315            }
 316
 317            void mark_finished_with_result(source_reference_type result_)
 318            {
 319                boost::lock_guard<boost::mutex> lock(mutex);
 320                mark_finished_with_result_internal(result_);
 321            }
 322            void mark_finished_with_result(rvalue_source_type result_)
 323            {
 324                boost::lock_guard<boost::mutex> lock(mutex);
 325                mark_finished_with_result_internal(result_);
 326            }
 327
 328            move_dest_type get()
 329            {
 330                wait();
 331                return static_cast<move_dest_type>(*result);
 332            }
 333
 334            future_state::state get_state()
 335            {
 336                boost::lock_guard<boost::mutex> guard(mutex);
 337                if(!done)
 338                {
 339                    return future_state::waiting;
 340                }
 341                else
 342                {
 343                    return future_state::ready;
 344                }
 345            }
 346
 347        private:
 348            future_object(future_object const&);
 349            future_object& operator=(future_object const&);
 350        };
 351
 352        template<>
 353        struct future_object<void>:
 354            detail::future_object_base
 355        {
 356            future_object()
 357            {}
 358
 359            void mark_finished_with_result_internal()
 360            {
 361                mark_finished_internal();
 362            }
 363
 364            void mark_finished_with_result()
 365            {
 366                boost::lock_guard<boost::mutex> lock(mutex);
 367                mark_finished_with_result_internal();
 368            }
 369
 370            void get()
 371            {
 372                wait();
 373            }
 374            
 375            future_state::state get_state()
 376            {
 377                boost::lock_guard<boost::mutex> guard(mutex);
 378                if(!done)
 379                {
 380                    return future_state::waiting;
 381                }
 382                else
 383                {
 384                    return future_state::ready;
 385                }
 386            }
 387
 388        private:
 389            future_object(future_object const&);
 390            future_object& operator=(future_object const&);
 391        };
 392
 393        class future_waiter
 394        {
 395            struct registered_waiter;
 396            typedef std::vector<registered_waiter>::size_type count_type;
 397            
 398            struct registered_waiter
 399            {
 400                boost::shared_ptr<detail::future_object_base> future;
 401                detail::future_object_base::waiter_list::iterator wait_iterator;
 402                count_type index;
 403
 404                registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_,
 405                                  detail::future_object_base::waiter_list::iterator wait_iterator_,
 406                                  count_type index_):
 407                    future(future_),wait_iterator(wait_iterator_),index(index_)
 408                {}
 409
 410            };
 411            
 412            struct all_futures_lock
 413            {
 414                count_type count;
 415                boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
 416                
 417                all_futures_lock(std::vector<registered_waiter>& futures):
 418                    count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
 419                {
 420                    for(count_type i=0;i<count;++i)
 421                    {
 422                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex);
 423                    }
 424                }
 425                
 426                void lock()
 427                {
 428                    boost::lock(locks.get(),locks.get()+count);
 429                }
 430                
 431                void unlock()
 432                {
 433                    for(count_type i=0;i<count;++i)
 434                    {
 435                        locks[i].unlock();
 436                    }
 437                }
 438            };
 439            
 440            boost::condition_variable_any cv;
 441            std::vector<registered_waiter> futures;
 442            count_type future_count;
 443            
 444        public:
 445            future_waiter():
 446                future_count(0)
 447            {}
 448            
 449            template<typename F>
 450            void add(F& f)
 451            {
 452                if(f.future)
 453                {
 454                    futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count));
 455                }
 456                ++future_count;
 457            }
 458
 459            count_type wait()
 460            {
 461                all_futures_lock lk(futures);
 462                for(;;)
 463                {
 464                    for(count_type i=0;i<futures.size();++i)
 465                    {
 466                        if(futures[i].future->done)
 467                        {
 468                            return futures[i].index;
 469                        }
 470                    }
 471                    cv.wait(lk);
 472                }
 473            }
 474            
 475            ~future_waiter()
 476            {
 477                for(count_type i=0;i<futures.size();++i)
 478                {
 479                    futures[i].future->remove_external_waiter(futures[i].wait_iterator);
 480                }
 481            }
 482            
 483        };
 484        
 485    }
 486
 487    template <typename R>
 488    class unique_future;
 489
 490    template <typename R>
 491    class shared_future;
 492
 493    template<typename T>
 494    struct is_future_type
 495    {
 496        BOOST_STATIC_CONSTANT(bool, value=false);
 497    };
 498    
 499    template<typename T>
 500    struct is_future_type<unique_future<T> >
 501    {
 502        BOOST_STATIC_CONSTANT(bool, value=true);
 503    };
 504    
 505    template<typename T>
 506    struct is_future_type<shared_future<T> >
 507    {
 508        BOOST_STATIC_CONSTANT(bool, value=true);
 509    };
 510
 511    template<typename Iterator>
 512    typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
 513    {
 514        for(Iterator current=begin;current!=end;++current)
 515        {
 516            current->wait();
 517        }
 518    }
 519
 520    template<typename F1,typename F2>
 521    typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
 522    {
 523        f1.wait();
 524        f2.wait();
 525    }
 526
 527    template<typename F1,typename F2,typename F3>
 528    void wait_for_all(F1& f1,F2& f2,F3& f3)
 529    {
 530        f1.wait();
 531        f2.wait();
 532        f3.wait();
 533    }
 534    
 535    template<typename F1,typename F2,typename F3,typename F4>
 536    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
 537    {
 538        f1.wait();
 539        f2.wait();
 540        f3.wait();
 541        f4.wait();
 542    }
 543
 544    template<typename F1,typename F2,typename F3,typename F4,typename F5>
 545    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
 546    {
 547        f1.wait();
 548        f2.wait();
 549        f3.wait();
 550        f4.wait();
 551        f5.wait();
 552    }
 553
 554    template<typename Iterator>
 555    typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
 556    {
 557        if(begin==end)
 558            return end;
 559        
 560        detail::future_waiter waiter;
 561        for(Iterator current=begin;current!=end;++current)
 562        {
 563            waiter.add(*current);
 564        }
 565        return boost::next(begin,waiter.wait());
 566    }
 567
 568    template<typename F1,typename F2>
 569    typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2)
 570    {
 571        detail::future_waiter waiter;
 572        waiter.add(f1);
 573        waiter.add(f2);
 574        return waiter.wait();
 575    }
 576
 577    template<typename F1,typename F2,typename F3>
 578    unsigned wait_for_any(F1& f1,F2& f2,F3& f3)
 579    {
 580        detail::future_waiter waiter;
 581        waiter.add(f1);
 582        waiter.add(f2);
 583        waiter.add(f3);
 584        return waiter.wait();
 585    }
 586    
 587    template<typename F1,typename F2,typename F3,typename F4>
 588    unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
 589    {
 590        detail::future_waiter waiter;
 591        waiter.add(f1);
 592        waiter.add(f2);
 593        waiter.add(f3);
 594        waiter.add(f4);
 595        return waiter.wait();
 596    }
 597
 598    template<typename F1,typename F2,typename F3,typename F4,typename F5>
 599    unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
 600    {
 601        detail::future_waiter waiter;
 602        waiter.add(f1);
 603        waiter.add(f2);
 604        waiter.add(f3);
 605        waiter.add(f4);
 606        waiter.add(f5);
 607        return waiter.wait();
 608    }
 609    
 610    template <typename R>
 611    class promise;
 612
 613    template <typename R>
 614    class packaged_task;
 615
 616    template <typename R>
 617    class unique_future
 618    {
 619        unique_future(unique_future & rhs);// = delete;
 620        unique_future& operator=(unique_future& rhs);// = delete;
 621
 622        typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
 623        
 624        future_ptr future;
 625
 626        friend class shared_future<R>;
 627        friend class promise<R>;
 628        friend class packaged_task<R>;
 629        friend class detail::future_waiter;
 630
 631        typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
 632
 633        unique_future(future_ptr future_):
 634            future(future_)
 635        {}
 636
 637    public:
 638        typedef future_state::state state;
 639
 640        unique_future()
 641        {}
 642       
 643        ~unique_future()
 644        {}
 645
 646#ifndef BOOST_NO_RVALUE_REFERENCES
 647        unique_future(unique_future && other)
 648        {
 649            future.swap(other.future);
 650        }
 651        unique_future& operator=(unique_future && other)
 652        {
 653            future=other.future;
 654            other.future.reset();
 655            return *this;
 656        }
 657#else
 658        unique_future(boost::detail::thread_move_t<unique_future> other):
 659            future(other->future)
 660        {
 661            other->future.reset();
 662        }
 663
 664        unique_future& operator=(boost::detail::thread_move_t<unique_future> other)
 665        {
 666            future=other->future;
 667            other->future.reset();
 668            return *this;
 669        }
 670
 671        operator boost::detail::thread_move_t<unique_future>()
 672        {
 673            return boost::detail::thread_move_t<unique_future>(*this);
 674        }
 675#endif
 676
 677        void swap(unique_future& other)
 678        {
 679            future.swap(other.future);
 680        }
 681
 682        // retrieving the value
 683        move_dest_type get()
 684        {
 685            if(!future)
 686            {
 687                boost::throw_exception(future_uninitialized());
 688            }
 689
 690            return future->get();
 691        }
 692        
 693        // functions to check state, and wait for ready
 694        state get_state() const
 695        {
 696            if(!future)
 697            {
 698                return future_state::uninitialized;
 699            }
 700            return future->get_state();
 701        }
 702        
 703
 704        bool is_ready() const
 705        {
 706            return get_state()==future_state::ready;
 707        }
 708        
 709        bool has_exception() const
 710        {
 711            return future && future->has_exception();
 712        }
 713        
 714        bool has_value() const
 715        {
 716            return future && future->has_value();
 717        }
 718        
 719        void wait() const
 720        {
 721            if(!future)
 722            {
 723                boost::throw_exception(future_uninitialized());
 724            }
 725            future->wait(false);
 726        }
 727        
 728        template<typename Duration>
 729        bool timed_wait(Duration const& rel_time) const
 730        {
 731            return timed_wait_until(boost::get_system_time()+rel_time);
 732        }
 733        
 734        bool timed_wait_until(boost::system_time const& abs_time) const
 735        {
 736            if(!future)
 737            {
 738                boost::throw_exception(future_uninitialized());
 739            }
 740            return future->timed_wait_until(abs_time);
 741        }
 742        
 743    };
 744
 745    template <typename R>
 746    class shared_future
 747    {
 748        typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
 749        
 750        future_ptr future;
 751
 752//         shared_future(const unique_future<R>& other);
 753//         shared_future& operator=(const unique_future<R>& other);
 754
 755        friend class detail::future_waiter;
 756        friend class promise<R>;
 757        friend class packaged_task<R>;
 758        
 759        shared_future(future_ptr future_):
 760            future(future_)
 761        {}
 762
 763    public:
 764        shared_future(shared_future const& other):
 765            future(other.future)
 766        {}
 767
 768        typedef future_state::state state;
 769
 770        shared_future()
 771        {}
 772
 773        ~shared_future()
 774        {}
 775
 776        shared_future& operator=(shared_future const& other)
 777        {
 778            future=other.future;
 779            return *this;
 780        }
 781#ifndef BOOST_NO_RVALUE_REFERENCES
 782        shared_future(shared_future && other)
 783        {
 784            future.swap(other.future);
 785        }
 786        shared_future(unique_future<R> && other)
 787        {
 788            future.swap(other.future);
 789        }
 790        shared_future& operator=(shared_future && other)
 791        {
 792            future.swap(other.future);
 793            other.future.reset();
 794            return *this;
 795        }
 796        shared_future& operator=(unique_future<R> && other)
 797        {
 798            future.swap(other.future);
 799            other.future.reset();
 800            return *this;
 801        }
 802#else            
 803        shared_future(boost::detail::thread_move_t<shared_future> other):
 804            future(other->future)
 805        {
 806            other->future.reset();
 807        }
 808//         shared_future(const unique_future<R> &) = delete;
 809        shared_future(boost::detail::thread_move_t<unique_future<R> > other):
 810            future(other->future)
 811        {
 812            other->future.reset();
 813        }
 814        shared_future& operator=(boost::detail::thread_move_t<shared_future> other)
 815        {
 816            future.swap(other->future);
 817            other->future.reset();
 818            return *this;
 819        }
 820        shared_future& operator=(boost::detail::thread_move_t<unique_future<R> > other)
 821        {
 822            future.swap(other->future);
 823            other->future.reset();
 824            return *this;
 825        }
 826
 827        operator boost::detail::thread_move_t<shared_future>()
 828        {
 829            return boost::detail::thread_move_t<shared_future>(*this);
 830        }
 831
 832#endif
 833
 834        void swap(shared_future& other)
 835        {
 836            future.swap(other.future);
 837        }
 838
 839        // retrieving the value
 840        R get()
 841        {
 842            if(!future)
 843            {
 844                boost::throw_exception(future_uninitialized());
 845            }
 846
 847            return future->get();
 848        }
 849        
 850        // functions to check state, and wait for ready
 851        state get_state() const
 852        {
 853            if(!future)
 854            {
 855                return future_state::uninitialized;
 856            }
 857            return future->get_state();
 858        }
 859        
 860
 861        bool is_ready() const
 862        {
 863            return get_state()==future_state::ready;
 864        }
 865        
 866        bool has_exception() const
 867        {
 868            return future && future->has_exception();
 869        }
 870        
 871        bool has_value() const
 872        {
 873            return future && future->has_value();
 874        }
 875
 876        void wait() const
 877        {
 878            if(!future)
 879            {
 880                boost::throw_exception(future_uninitialized());
 881            }
 882            future->wait(false);
 883        }
 884        
 885        template<typename Duration>
 886        bool timed_wait(Duration const& rel_time) const
 887        {
 888            return timed_wait_until(boost::get_system_time()+rel_time);
 889        }
 890        
 891        bool timed_wait_until(boost::system_time const& abs_time) const
 892        {
 893            if(!future)
 894            {
 895                boost::throw_exception(future_uninitialized());
 896            }
 897            return future->timed_wait_until(abs_time);
 898        }
 899        
 900    };
 901
 902    template <typename R>
 903    class promise
 904    {
 905        typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
 906        
 907        future_ptr future;
 908        bool future_obtained;
 909        
 910        promise(promise & rhs);// = delete;
 911        promise & operator=(promise & rhs);// = delete;
 912
 913        void lazy_init()
 914        {
 915            if(!atomic_load(&future))
 916            {
 917                future_ptr blank;
 918                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>));
 919            }
 920        }
 921        
 922    public:
 923//         template <class Allocator> explicit promise(Allocator a);
 924
 925        promise():
 926            future(),future_obtained(false)
 927        {}
 928        
 929        ~promise()
 930        {
 931            if(future)
 932            {
 933                boost::lock_guard<boost::mutex> lock(future->mutex);
 934
 935                if(!future->done)
 936                {
 937                    future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));
 938                }
 939            }
 940        }
 941
 942        // Assignment
 943#ifndef BOOST_NO_RVALUE_REFERENCES
 944        promise(promise && rhs):
 945            future_obtained(rhs.future_obtained)
 946        {
 947            future.swap(rhs.future);
 948            rhs.future_obtained=false;
 949        }
 950        promise & operator=(promise&& rhs)
 951        {
 952            future.swap(rhs.future);
 953            future_obtained=rhs.future_obtained;
 954            rhs.future.reset();
 955            rhs.future_obtained=false;
 956            return *this;
 957        }
 958#else
 959        promise(boost::detail::thread_move_t<promise> rhs):
 960            future(rhs->future),future_obtained(rhs->future_obtained)
 961        {
 962            rhs->future.reset();
 963            rhs->future_obtained=false;
 964        }
 965        promise & operator=(boost::detail::thread_move_t<promise> rhs)
 966        {
 967            future=rhs->future;
 968            future_obtained=rhs->future_obtained;
 969            rhs->future.reset();
 970            rhs->future_obtained=false;
 971            return *this;
 972        }
 973
 974        operator boost::detail::thread_move_t<promise>()
 975        {
 976            return boost::detail::thread_move_t<promise>(*this);
 977        }
 978#endif   
 979        
 980        void swap(promise& other)
 981        {
 982            future.swap(other.future);
 983            std::swap(future_obtained,other.future_obtained);
 984        }
 985
 986        // Result retrieval
 987        unique_future<R> get_future()
 988        {
 989            lazy_init();
 990            if(future_obtained)
 991            {
 992                boost::throw_exception(future_already_retrieved());
 993            }
 994            future_obtained=true;
 995            return unique_future<R>(future);
 996        }
 997
 998        void set_value(typename detail::future_traits<R>::source_reference_type r)
 999        {
1000            lazy_init();
1001            boost::lock_guard<boost::mutex> lock(future->mutex);
1002            if(future->done)
1003            {
1004                boost::throw_exception(promise_already_satisfied());
1005            }
1006            future->mark_finished_with_result_internal(r);
1007        }
1008
1009//         void set_value(R && r);
1010        void set_value(typename detail::future_traits<R>::rvalue_source_type r)
1011        {
1012            lazy_init();
1013            boost::lock_guard<boost::mutex> lock(future->mutex);
1014            if(future->done)
1015            {
1016                boost::throw_exception(promise_already_satisfied());
1017            }
1018            future->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r));
1019        }
1020
1021        void set_exception(boost::exception_ptr p)
1022        {
1023            lazy_init();
1024            boost::lock_guard<boost::mutex> lock(future->mutex);
1025            if(future->done)
1026            {
1027                boost::throw_exception(promise_already_satisfied());
1028            }
1029            future->mark_exceptional_finish_internal(p);
1030        }
1031
1032        template<typename F>
1033        void set_wait_callback(F f)
1034        {
1035            lazy_init();
1036            future->set_wait_callback(f,this);
1037        }
1038        
1039    };
1040
1041    template <>
1042    class promise<void>
1043    {
1044        typedef boost::shared_ptr<detail::future_object<void> > future_ptr;
1045        
1046        future_ptr future;
1047        bool future_obtained;
1048        
1049        promise(promise & rhs);// = delete;
1050        promise & operator=(promise & rhs);// = delete;
1051
1052        void lazy_init()
1053        {
1054            if(!atomic_load(&future))
1055            {
1056                future_ptr blank;
1057                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>));
1058            }
1059        }
1060    public:
1061//         template <class Allocator> explicit promise(Allocator a);
1062
1063        promise():
1064            future(),future_obtained(false)
1065        {}
1066        
1067        ~promise()
1068        {
1069            if(future)
1070            {
1071                boost::lock_guard<boost::mutex> lock(future->mutex);
1072
1073                if(!future->done)
1074                {
1075                    future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));
1076                }
1077            }
1078        }
1079
1080        // Assignment
1081#ifndef BOOST_NO_RVALUE_REFERENCES
1082        promise(promise && rhs):
1083            future_obtained(rhs.future_obtained)
1084        {
1085            future.swap(rhs.future);
1086            rhs.future_obtained=false;
1087        }
1088        promise & operator=(promise&& rhs)
1089        {
1090            future.swap(rhs.future);
1091            future_obtained=rhs.future_obtained;
1092            rhs.future.reset();
1093            rhs.future_obtained=false;
1094            return *this;
1095        }
1096#else
1097        promise(boost::detail::thread_move_t<promise> rhs):
1098            future(rhs->future),future_obtained(rhs->future_obtained)
1099        {
1100            rhs->future.reset();
1101            rhs->future_obtained=false;
1102        }
1103        promise & operator=(boost::detail::thread_move_t<promise> rhs)
1104        {
1105            future=rhs->future;
1106            future_obtained=rhs->future_obtained;
1107            rhs->future.reset();
1108            rhs->future_obtained=false;
1109            return *this;
1110        }
1111
1112        operator boost::detail::thread_move_t<promise>()
1113        {
1114            return boost::detail::thread_move_t<promise>(*this);
1115        }
1116#endif
1117        
1118        void swap(promise& other)
1119        {
1120            future.swap(other.future);
1121            std::swap(future_obtained,other.future_obtained);
1122        }
1123
1124        // Result retrieval
1125        unique_future<void> get_future()
1126        {
1127            lazy_init();
1128            
1129            if(future_obtained)
1130            {
1131                boost::throw_exception(future_already_retrieved());
1132            }
1133            future_obtained=true;
1134            return unique_future<void>(future);
1135        }
1136
1137        void set_value()
1138        {
1139            lazy_init();
1140            boost::lock_guard<boost::mutex> lock(future->mutex);
1141            if(future->done)
1142            {
1143                boost::throw_exception(promise_already_satisfied());
1144            }
1145            future->mark_finished_with_result_internal();
1146        }
1147
1148        void set_exception(boost::exception_ptr p)
1149        {
1150            lazy_init();
1151            boost::lock_guard<boost::mutex> lock(future->mutex);
1152            if(future->done)
1153            {
1154                boost::throw_exception(promise_already_satisfied());
1155            }
1156            future->mark_exceptional_finish_internal(p);
1157        }
1158
1159        template<typename F>
1160        void set_wait_callback(F f)
1161        {
1162            lazy_init();
1163            future->set_wait_callback(f,this);
1164        }
1165        
1166    };
1167
1168    namespace detail
1169    {
1170        template<typename R>
1171        struct task_base:
1172            detail::future_object<R>
1173        {
1174            bool started;
1175
1176            task_base():
1177                started(false)
1178            {}
1179
1180            void run()
1181            {
1182                {
1183                    boost::lock_guard<boost::mutex> lk(this->mutex);
1184                    if(started)
1185                    {
1186                        boost::throw_exception(task_already_started());
1187                    }
1188                    started=true;
1189                }
1190                do_run();
1191            }
1192
1193            void owner_destroyed()
1194            {
1195                boost::lock_guard<boost::mutex> lk(this->mutex);
1196                if(!started)
1197                {
1198                    started=true;
1199                    this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()));
1200                }
1201            }
1202            
1203            
1204            virtual void do_run()=0;
1205        };
1206        
1207        
1208        template<typename R,typename F>
1209        struct task_object:
1210            task_base<R>
1211        {
1212            F f;
1213            task_object(F const& f_):
1214                f(f_)
1215            {}
1216            task_object(boost::detail::thread_move_t<F> f_):
1217                f(f_)
1218            {}
1219            
1220            void do_run()
1221            {
1222                try
1223                {
1224                    this->mark_finished_with_result(f());
1225                }
1226                catch(...)
1227                {
1228                    this->mark_exceptional_finish();
1229                }
1230            }
1231        };
1232
1233        template<typename F>
1234        struct task_object<void,F>:
1235            task_base<void>
1236        {
1237            F f;
1238            task_object(F const& f_):
1239                f(f_)
1240            {}
1241            task_object(boost::detail::thread_move_t<F> f_):
1242                f(f_)
1243            {}
1244            
1245            void do_run()
1246            {
1247                try
1248                {
1249                    f();
1250                    this->mark_finished_with_result();
1251                }
1252                catch(...)
1253                {
1254                    this->mark_exceptional_finish();
1255                }
1256            }
1257        };
1258
1259    }
1260    
1261
1262    template<typename R>
1263    class packaged_task
1264    {
1265        boost::shared_ptr<detail::task_base<R> > task;
1266        bool future_obtained;
1267
1268        packaged_task(packaged_task&);// = delete;
1269        packaged_task& operator=(packaged_task&);// = delete;
1270        
1271    public:
1272        packaged_task():
1273            future_obtained(false)
1274        {}
1275        
1276        // construction and destruction
1277        template <class F>
1278        explicit packaged_task(F const& f):
1279            task(new detail::task_object<R,F>(f)),future_obtained(false)
1280        {}
1281        explicit packaged_task(R(*f)()):
1282            task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
1283        {}
1284        
1285        template <class F>
1286        explicit packaged_task(boost::detail::thread_move_t<F> f):
1287            task(new detail::task_object<R,F>(f)),future_obtained(false)
1288        {}
1289
1290//         template <class F, class Allocator>
1291//         explicit packaged_task(F const& f, Allocator a);
1292//         template <class F, class Allocator>
1293//         explicit packaged_task(F&& f, Allocator a);
1294
1295
1296        ~packaged_task()
1297        {
1298            if(task)
1299            {
1300                task->owner_destroyed();
1301            }
1302        }
1303
1304        // assignment
1305#ifndef BOOST_NO_RVALUE_REFERENCES
1306        packaged_task(packaged_task&& other):
1307            future_obtained(other.future_obtained)
1308        {
1309            task.swap(other.task);
1310            other.future_obtained=false;
1311        }
1312        packaged_task& operator=(packaged_task&& other)
1313        {
1314            packaged_task temp(static_cast<packaged_task&&>(other));
1315            swap(temp);
1316            return *this;
1317        }
1318#else
1319        packaged_task(boost::detail::thread_move_t<packaged_task> other):
1320            future_obtained(other->future_obtained)
1321        {
1322            task.swap(other->task);
1323            other->future_obtained=false;
1324        }
1325        packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other)
1326        {
1327            packaged_task temp(other);
1328            swap(temp);
1329            return *this;
1330        }
1331        operator boost::detail::thread_move_t<packaged_task>()
1332        {
1333            return boost::detail::thread_move_t<packaged_task>(*this);
1334        }
1335#endif
1336
1337        void swap(packaged_task& other)
1338        {
1339            task.swap(other.task);
1340            std::swap(future_obtained,other.future_obtained);
1341        }
1342
1343        // result retrieval
1344        unique_future<R> get_future()
1345        {
1346            if(!task)
1347            {
1348                boost::throw_exception(task_moved());
1349            }
1350            else if(!future_obtained)
1351            {
1352                future_obtained=true;
1353                return unique_future<R>(task);
1354            }
1355            else
1356            {
1357                boost::throw_exception(future_already_retrieved());
1358            }
1359        }
1360        
1361
1362        // execution
1363        void operator()()
1364        {
1365            if(!task)
1366            {
1367                boost::throw_exception(task_moved());
1368            }
1369            task->run();
1370        }
1371
1372        template<typename F>
1373        void set_wait_callback(F f)
1374        {
1375            task->set_wait_callback(f,this);
1376        }
1377        
1378    };
1379
1380}
1381
1382
1383#endif