Ticket #2330: thread-interrupt.patch

File thread-interrupt.patch, 3.8 KB (added by Don Ward <don2387ward@…>, 14 years ago)

patch for thread::interrupt race condition

  • boost/thread/pthread/condition_variable.hpp

    old new  
    1414
    1515namespace boost
    1616{
    1717    inline void condition_variable::wait(unique_lock<mutex>& m)
    1818    {
    19         detail::interruption_checker check_for_interruption(&cond);
     19      detail::interruption_checker check_for_interruption(&cond,m.mutex()->native_handle());
    2020        BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle()));
    2121    }
    2222
    2323    inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
    2424    {
    25         detail::interruption_checker check_for_interruption(&cond);
     25      detail::interruption_checker check_for_interruption(&cond,m.mutex()->native_handle());
    2626        struct timespec const timeout=detail::get_timespec(wait_until);
    2727        int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout);
    2828        if(cond_res==ETIMEDOUT)
    2929        {
    3030            return false;
  • boost/thread/pthread/thread_data.hpp

    old new  
    4242            bool joined;
    4343            boost::detail::thread_exit_callback_node* thread_exit_callbacks;
    4444            boost::detail::tss_data_node* tss_data;
    4545            bool interrupt_enabled;
    4646            bool interrupt_requested;
     47            pthread_mutex_t* cond_mutex;
    4748            pthread_cond_t* current_cond;
    4849
    4950            thread_data_base():
    5051                done(false),join_started(false),joined(false),
    5152                thread_exit_callbacks(0),tss_data(0),
     
    7576                }
    7677            }
    7778           
    7879            void operator=(interruption_checker&);
    7980        public:
    80             explicit interruption_checker(pthread_cond_t* cond):
     81          explicit interruption_checker(pthread_cond_t* cond,
     82                                        pthread_mutex_t* m):
    8183                thread_info(detail::get_current_thread_data())
    8284            {
    8385                if(thread_info && thread_info->interrupt_enabled)
    8486                {
    8587                    lock_guard<mutex> guard(thread_info->data_mutex);
    8688                    check_for_interruption();
    8789                    thread_info->current_cond=cond;
     90                    thread_info->cond_mutex=m;
    8891                }
    8992            }
    9093            ~interruption_checker()
    9194            {
    9295                if(thread_info && thread_info->interrupt_enabled)
    9396                {
    9497                    lock_guard<mutex> guard(thread_info->data_mutex);
    9598                    thread_info->current_cond=NULL;
     99                    thread_info->cond_mutex=NULL;
    96100                    check_for_interruption();
    97101                }
    98102            }
    99103        };
    100104    }
  • libs/thread/src/pthread/thread.cpp

    old new  
    418418    void thread::interrupt()
    419419    {
    420420        detail::thread_data_ptr const local_thread_info=get_thread_info();
    421421        if(local_thread_info)
    422422        {
     423          pthread_cond_t* current_cond;
     424          pthread_mutex_t* cond_mutex;
     425          {
    423426            lock_guard<mutex> lk(local_thread_info->data_mutex);
    424427            local_thread_info->interrupt_requested=true;
    425             if(local_thread_info->current_cond)
    426             {
    427                 BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
    428             }
     428            current_cond = local_thread_info->current_cond;
     429            cond_mutex = local_thread_info->cond_mutex;
     430          }
     431          if(current_cond)
     432          {
     433            BOOST_VERIFY(!pthread_mutex_lock(cond_mutex));
     434            BOOST_VERIFY(!pthread_cond_broadcast(current_cond));
     435            BOOST_VERIFY(!pthread_mutex_unlock(cond_mutex));
     436          }
    429437        }
    430438    }
    431439
    432440    bool thread::interruption_requested() const
    433441    {