Ticket #5990: 5590_5531.diff

File 5590_5531.diff, 7.7 KB (added by viboes, 11 years ago)

Could you try the attached patch for this and #5531?

  • future.hpp

     
    66
    77#ifndef BOOST_THREAD_FUTURE_HPP
    88#define BOOST_THREAD_FUTURE_HPP
     9
    910#include <stdexcept>
    1011#include <boost/thread/detail/move.hpp>
    1112#include <boost/thread/thread_time.hpp>
     
    9394        {
    9495            boost::exception_ptr exception;
    9596            bool done;
     97            bool thread_was_interrupted;
    9698            boost::mutex mutex;
    9799            boost::condition_variable waiters;
    98100            typedef std::list<boost::condition_variable_any*> waiter_list;
     
    100102            boost::function<void()> callback;
    101103
    102104            future_object_base():
    103                 done(false)
     105                done(false),
     106                thread_was_interrupted(false)
    104107            {}
    105108            virtual ~future_object_base()
    106109            {}
     
    165168                {
    166169                    waiters.wait(lock);
    167170                }
     171                if(rethrow && thread_was_interrupted)
     172                {
     173                    throw boost::thread_interrupted();
     174                }
    168175                if(rethrow && exception)
    169176                {
    170177                    boost::rethrow_exception(exception);
     
    196203                boost::lock_guard<boost::mutex> lock(mutex);
    197204                mark_exceptional_finish_internal(boost::current_exception());
    198205            }
    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            }
    200212            bool has_value()
    201213            {
    202214                boost::lock_guard<boost::mutex> lock(mutex);
    203                 return done && !exception;
     215                return done && !(exception || thread_was_interrupted);
    204216            }
    205217            bool has_exception()
    206218            {
    207219                boost::lock_guard<boost::mutex> lock(mutex);
    208                 return done && exception;
     220                return done && (exception || thread_was_interrupted);
    209221            }
    210222
    211223            template<typename F,typename U>
     
    233245            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;
    234246            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;
    235247#endif
     248            typedef const T& shared_future_get_result_type;
    236249
    237250            static void init(storage_type& storage,source_reference_type t)
    238251            {
     
    258271            struct rvalue_source_type
    259272            {};
    260273            typedef T& move_dest_type;
     274            typedef T& shared_future_get_result_type;
    261275
    262276            static void init(storage_type& storage,T& t)
    263277            {
     
    275289        {
    276290            typedef bool storage_type;
    277291            typedef void move_dest_type;
     292            typedef void shared_future_get_result_type;
    278293
    279294            static void init(storage_type& storage)
    280295            {
     
    296311            typedef typename future_traits<T>::source_reference_type source_reference_type;
    297312            typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;
    298313            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;
    299315
    300316            storage_type result;
    301317
     
    331347                return static_cast<move_dest_type>(*result);
    332348            }
    333349
     350            shared_future_get_result_type get_sh()
     351            {
     352                wait();
     353                return static_cast<shared_future_get_result_type>(*result);
     354            }
     355
    334356            future_state::state get_state()
    335357            {
    336358                boost::lock_guard<boost::mutex> guard(mutex);
     
    353375        struct future_object<void>:
    354376            detail::future_object_base
    355377        {
    356           typedef void move_dest_type;
     378          typedef void shared_future_get_result_type;
    357379
    358380            future_object()
    359381            {}
     
    373395            {
    374396                wait();
    375397            }
    376 
     398            void get_sh()
     399            {
     400                wait();
     401            }
    377402            future_state::state get_state()
    378403            {
    379404                boost::lock_guard<boost::mutex> guard(mutex);
     
    413438
    414439            struct all_futures_lock
    415440            {
    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;
    423442                boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
    424443
    425444                all_futures_lock(std::vector<registered_waiter>& futures):
    426445                    count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
    427446                {
    428                     for(count_type_portable i=0;i<count;++i)
     447                    for(count_type i=0;i<count;++i)
    429448                    {
    430449#if defined __DECCXX || defined __SUNPRO_CC
    431450                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex).move();
     
    442461
    443462                void unlock()
    444463                {
    445                     for(count_type_portable i=0;i<count;++i)
     464                    for(count_type i=0;i<count;++i)
    446465                    {
    447466                        locks[i].unlock();
    448467                    }
     
    849868        }
    850869
    851870        // 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()
    854873        {
    855874            if(!future)
    856875            {
    857876                boost::throw_exception(future_uninitialized());
    858877            }
    859878
    860             return future->get();
     879            return future->get_sh();
    861880        }
    862881
    863882        // functions to check state, and wait for ready
     
    12351254                f(f_)
    12361255            {}
    12371256#endif
    1238 
    12391257            void do_run()
    12401258            {
    12411259                try
    12421260                {
    12431261                    this->mark_finished_with_result(f());
    12441262                }
     1263                catch(thread_interrupted& it)
     1264                {
     1265                    this->mark_interrupted_finish();
     1266                }
    12451267                catch(...)
    12461268                {
    12471269                    this->mark_exceptional_finish();
     
    12661288                f(f_)
    12671289            {}
    12681290#endif
    1269 
    12701291            void do_run()
    12711292            {
    12721293                try
     
    12741295                    f();
    12751296                    this->mark_finished_with_result();
    12761297                }
     1298                catch(thread_interrupted& it)
     1299                {
     1300                    this->mark_interrupted_finish();
     1301                }
    12771302                catch(...)
    12781303                {
    12791304                    this->mark_exceptional_finish();
     
    13181343            task(new detail::task_object<R,F>(f)),future_obtained(false)
    13191344        {}
    13201345#endif
    1321 
    13221346//         template <class F, class Allocator>
    13231347//         explicit packaged_task(F const& f, Allocator a);
    13241348//         template <class F, class Allocator>
     
    13351359
    13361360        // assignment
    13371361#ifndef BOOST_NO_RVALUE_REFERENCES
     1362
    13381363        packaged_task(packaged_task&& other):
    13391364            future_obtained(other.future_obtained)
    13401365        {
     
    13661391        }
    13671392#endif
    13681393
    1369     void swap(packaged_task& other)
     1394        void swap(packaged_task& other)
    13701395        {
    13711396            task.swap(other.task);
    13721397            std::swap(future_obtained,other.future_obtained);