[Boost-bugs] [Boost C++ Libraries] #11053: The attached code results in a R6025 - pure virtual function call in run_thread_exit_callbacks

Subject: [Boost-bugs] [Boost C++ Libraries] #11053: The attached code results in a R6025 - pure virtual function call in run_thread_exit_callbacks
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-02-22 06:11:49


#11053: The attached code results in a R6025 - pure virtual function call in
run_thread_exit_callbacks
------------------------------+----------------------
 Reporter: swebb3@… | Owner: anthonyw
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: thread
  Version: Boost 1.55.0 | Severity: Problem
 Keywords: |
------------------------------+----------------------
 Caused when deallocating a thread specific pointer in a object that is
 inside thread specific data.
 I suggest changing the code in run_thread_exit_callbacks from

 {{{
 for(std::map<void const*,detail::tss_data_node>::iterator
 next=current_thread_data->tss_data.begin(),
     current,
     end=current_thread_data->tss_data.end();
     next!=end;)
 {
     current=next;
     ++next;
     if(current->second.func && (current->second.value!=0))
     {
         (*current->second.func)(current->second.value);
     }
     current_thread_data->tss_data.erase(current);
 }
 }}}
 to

 {{{
 while (!current_thread_data->tss_data.empty())
 {
     std::map<void const*,detail::tss_data_node>::iterator current
         = current_thread_data->tss_data.begin()
     if(current->second.func && (current->second.value!=0))
     {
         (*current->second.func)(current->second.value);
     }
     current_thread_data->tss_data.erase(current);
 }

 }}}

 Code to reproduce the problem:
 {{{
 #include <boost/thread.hpp>
 #include <boost/thread/tss.hpp>
 #include <boost/shared_ptr.hpp>
 #include <iostream>

 struct A
 {
     void DoWork()
     {
         std::cout << "A: doing work\n";
         if (!m_ptr.get())
             m_ptr.reset(new WorkSpace());
         // do not very much
         for (size_t i = 0; i < 10; ++i)
             m_ptr->a += 10;
     }

 private:
     struct WorkSpace
     {
         int a;
         WorkSpace() : a(0) {}
     };
     boost::thread_specific_ptr<WorkSpace> m_ptr;
 };

 struct B
 {
     void DoWork()
     {
         std::cout << "B: doing work\n";
         if (!m_ptr.get())
             m_ptr.reset(new A());
         m_ptr->DoWork();
     }
 private:
     boost::thread_specific_ptr<A> m_ptr;
 };

 struct C
 {
     void DoWork()
     {
         std::cout << "C: doing work\n";
         if (!m_ptr.get())
             m_ptr.reset(new B());
         m_ptr->DoWork();
     }
 private:
     boost::thread_specific_ptr<B> m_ptr;
 };

 int main(int ac, char** av)
 {
     std::cout << "test starting\n";
     boost::shared_ptr<C> p_C(new C);
     boost::thread cWorker(&C::DoWork, p_C);
     cWorker.join();
     std::cout << "test stopping\n";
 }
 }}}


 Compiler visual studio 2012

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11053>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:17 UTC