
I am experiencing core-dumps when sharing a boost::promise between two threads. Full core-dump at the bottom. My guess: When one thread does promise.set_value(), I found that the set_value() function of the promise class will execute lazy_init() and then lock a guard. The other tread at the same time might execute promise.get_future() which will also do a lazy_init(). It seems this introduces a race-condition between the get_future() call and the set_value() call: the local future_ptr in the promise class might be reset() while it's being used? This has resulted in some coredumps (. If I change /usr/local/boost_1_43_0/boost/thread/future.hpp to call lazy_init() in the constructor of promise (around line 919, though it will not be lazy anymore), the crashes disappear. What's the right solution to this? Is it a bug in boost::promise or do I use it wrong? My use case: I am writing an asynchronous library to be used inside synchronous code. I use Boost.Asio + Boost.Thread futures/promises. One thread (Asio) sends + receives packets. It will return a boost::shared_ptr<packet_promise> where packet_promise is a boost::promise<PacketType> when doing a write. When the Asio thread receives, I do a set_value() to the promise. The main thread, the one that did the request, will receive the shared_ptr to the packet_promise and then execute get_value() on the promise. My system: Boost 1.43.0. Linux 2.6.16.21-0.8 g++ (GCC) 4.1.0 (SUSE Linux) ======================= full core-dump without calling the lazy_init() inside the promise's constructor: #0 0xffffe410 in __kernel_vsyscall () #1 0xb7c377d0 in raise () from /lib/libc.so.6 #2 0xb7c38ea3 in abort () from /lib/libc.so.6 #3 0xb7c3101b in __assert_fail () from /lib/libc.so.6 #4 0x080f68b3 in ~mutex (this=0x81c8090) at /usr/local/boost_1_43_0/boost/thread/pthread/mutex.hpp:46 #5 0x080fc375 in ~future_object_base (this=0x81c8080) at /usr/local/boost_1_43_0/boost/thread/future.hpp:104 #6 0x080fc44c in ~future_object (this=0x81c8080) at /usr/local/boost_1_43_0/boost/thread/future.hpp:290 #7 0x080cbd62 in boost::checked_delete<boost::detail::future_object<lib_async::CQunPacket<lib_async::CQunEnvelope, lib_async::CQunHeader, lib_async::CQunBody> > > (x=0x81c8080) at /usr/local/boost_1_43_0/boost/checked_delete.hpp:34 #8 0x080cf724 in boost::detail::sp_counted_impl_p<boost::detail::future_object<lib_async::CQunPacket<lib_async::CQunEnvelope, lib_async::CQunHeader, lib_async::CQunBody> > >::dispose (this=0x81a2f40) at /usr/local/boost_1_43_0/boost/smart_ptr/detail/sp_counted_impl.hpp:78 #9 0x080c4586 in boost::detail::sp_counted_base::release (this=0x81a2f40) at /usr/local/boost_1_43_0/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145 #10 0x080c45cc in ~shared_count (this=0xb4bc5b94) at /usr/local/boost_1_43_0/boost/smart_ptr/detail/shared_count.hpp:217 #11 0x080c56cc in ~shared_ptr (this=0xb4bc5b90) at /usr/local/boost_1_43_0/boost/smart_ptr/shared_ptr.hpp:169 #12 0x080d87c5 in boost::shared_ptr<boost::detail::future_object<lib_async::CQunPacket<lib_async::CQunEnvelope, lib_async::CQunHeader, lib_async::CQunBody> >
::reset<boost::detail::future_object<lib_async::CQunPacket<lib_async::CQunEnvelope, lib_async::CQunHeader, lib_async::CQunBody> > > (this=0x8250230, p=0x823c780) at /usr/local/boost_1_43_0/boost/smart_ptr/shared_ptr.hpp:392 #13 0x080fc8cf in boost::promise<lib_async::CQunPacket<lib_async::CQunEnvelope, lib_async::CQunHeader, lib_async::CQunBody> >::lazy_init ( this=0x8250230) at /usr/local/boost_1_43_0/boost/thread/future.hpp:909 #14 0x080fc908 in boost::promise<lib_async::CQunPacket<lib_async::CQunEnvelope, lib_async::CQunHeader, lib_async::CQunBody> >::get_future (this=0x8250230) at /usr/local/boost_1_43_0/boost/thread/future.hpp:978 #15 0x080fd38e in SQunSession::recvAll (this=0xb4bc62dc, error=@0xb4bc618e, TimeoutMs=500) at /data/home/thijs/git/yaaf/public/libasync/worker_async_demo.cpp:101 #16 0x080fd828 in AsyncDemoWorker::do_my_special_thing (this=0x81b2080, session=@0xb4bc62dc) at /data/home/thijs/git/yaaf/public/libasync/worker_async_demo.cpp:240 #17 0x080fe7d6 in AsyncDemoWorker::onRequest (this=0x81b2080, sock=@0x819e3f8) at /data/home/thijs/git/yaaf/public/libasync/worker_async_demo.cpp:189 #18 0xb7f61da8 in yaaf::BaseWorker::run (this=0x81b2080) at /data/home/thijs/git/yaaf/public/libyaaf/yaaf_worker.cpp:68 #19 0xb7f5d8cf in yaaf::Context::thread_entry_point (ctx=0x81b2088) at /data/home/thijs/git/yaaf/public/libyaaf/yaaf_context.cpp:287 #20 0xb7f7934b in start_thread () from /lib/libpthread.so.0 #21 0xb7ccc65e in clone () from /lib/libc.so.6
line 101 in worker_async_demo.cpp looks like this: 100: packet_promise_ptr ppp_temp = (*it).first; //copy of shared pointer, stored in a map 101: packet_future pf = ppp_temp->get_future(); //core-dump here Thijs