Open GoogleCodeExporter opened 9 years ago
GUI Thread
Because no GUI interferes with the server logic (it receives reports from,
rather than interacts with, the server), each GUI can be run independently from
each other. However, access to it needs to be serialised. Therefore, I
propose the following rules (most of which are already kept)
# user_interface is granted access to the window's io_service.
# All access to the is performed by the user_interface's interface.
# All those accesses' functions are performed by using an io_service strand to
ensure that only one thread is active per GUI at a time.
Original comment by matthew....@gmail.com
on 21 Jul 2011 at 8:44
Accomplished a lot using strands. Added a new runtime option "-t <threads>"
which specifies the size of the thread pool. "Works", although there are
undoubtedly a few race conditions peppered around. The most obvious of these
should be hammered out before showtime.
Original comment by matthew....@gmail.com
on 31 Jan 2012 at 11:06
Observed a crash when a player was logging in.
Original comment by matthew....@gmail.com
on 19 Mar 2012 at 11:03
There may yet be issues between the IO and GUI strands of different clients.
For example, if a client logs in or out, then a message is broadcast to all
players. This broadcast could occur while another client is busy updating its
GUI. Since there is no locking in place, this could conceivably cause a
vector<> (say) to be reallocated while it is being read.
I suggest one of two strategies:
* All changes to GUI structures are scheduled on the GUI strand for that client.
* All changes to GUI structures are synchronised with locks.
The former is a more ideal solution, since it enables a lot of task parallelism
off the bat. E.g. a broadcast message such as above is simply strand.post()ed
to each client rather than locking each client sequentially (yes, this could be
parallelised at the source, but that's far more work than using strand.post()).
However, it's difficult to ship a client's GUI strand to *all* GUI components.
Therefore, the latter solution is the more simple solution.
Original comment by matthew....@gmail.com
on 21 Jun 2012 at 8:28
After some investigation, the above comment is somewhat obsolete. The
hugin::user_interface class already dispatches requests to add output text on
the client's GUI strand.
Original comment by matthew....@gmail.com
on 21 Jun 2012 at 9:26
[deleted comment]
[deleted comment]
The log-in crash seems to be due to timing issues between connecting, detecting
the terminal type, and constructing and displaying the UI.
Original comment by matthew....@gmail.com
on 22 Jun 2012 at 12:02
[deleted comment]
This may rely on/provide the basis for Issue #99, since the main multithreading
issue seems to be at log-on time: there appear to be race conditions between
setting up the UI and detecting the terminal type. Fully separating the two
would go a long way to sorting both these issues out.
Original comment by matthew....@gmail.com
on 27 Jun 2012 at 7:27
A good tool for detecting data races is valgrind, using --tool=drd (data race
detector) or --tool=helgrind. It looks to highlight a number of potential
issues, some of which may require quite some low-level redesign.
Original comment by matthew....@gmail.com
on 9 Oct 2012 at 7:21
Helgrind shows the following:
==16604== Possible data race during read of size 4 at 0x4302b18 by thread #2
==16604== at 0x80F8677: munin::basic_container::do_layout()
(basic_container.cpp:1049)
==16604== by 0x814AD0B: munin::window::impl::do_layout() (window.cpp:717)
==16604== by 0x8147DF2:
boost::asio::detail::completion_handler<boost::_bi::bind_t<void,
boost::_mfi::mf0<void, munin::window::impl>,
boost::_bi::list1<boost::_bi::value<boost::shared_ptr<munin::window::impl> > >
> >::do_complete(boost::asio::detail::task_io_service*,
boost::asio::detail::task_io_service_operation*, boost::system::error_code
const&, unsigned int) (mem_fn_template.hpp:40)
==16604== by 0x8059B7B:
boost::asio::detail::strand_service::do_complete(boost::asio::detail::task_io_se
rvice*, boost::asio::detail::task_io_service_operation*,
boost::system::error_code const&, unsigned int)
(task_io_service_operation.hpp:37)
==16604== by 0x80727D9:
boost::asio::detail::task_io_service::run(boost::system::error_code&)
(task_io_service_operation.hpp:37)
==16604== by 0x8062122: run_io_service(boost::asio::io_service&)
(io_service.ipp:59)
==16604== by 0x81EF08B: thread_proxy (in
/home/mach/code/para/paradice9/paradice.exe)
==16604== by 0x4026F60: mythread_wrapper (hg_intercepts.c:221)
==16604== by 0x404EE98: start_thread (pthread_create.c:304)
==16604== by 0x42619ED: clone (clone.S:130)
==16604== This conflicts with a previous write of size 4 by thread #3
==16604== at 0x80FDB16: std::vector<boost::shared_ptr<munin::component>,
std::allocator<boost::shared_ptr<munin::component> >
>::_M_insert_aux(__gnu_cxx::__normal_iterator<boost::shared_ptr<munin::component
>*, std::vector<boost::shared_ptr<munin::component>,
std::allocator<boost::shared_ptr<munin::component> > > >,
boost::shared_ptr<munin::component> const&) (vector.tcc:364)
==16604== by 0x80FAE0F:
munin::basic_container::do_add_component(boost::shared_ptr<munin::component>
const&, boost::any const&, unsigned int) (stl_vector.h:749)
==16604== by 0x811311E:
munin::container::add_component(boost::shared_ptr<munin::component> const&,
boost::any const&, unsigned int) (container.cpp:188)
==16604== by 0x807F25E:
paradice::client::impl::set_connection(boost::shared_ptr<paradice::connection>)
(client.cpp:258)
==16604== by 0x8075150:
paradice::client::set_connection(boost::shared_ptr<paradice::connection>
const&) (client.cpp:985)
==16604== by 0x8060510:
paradice9::impl::on_terminal_type(boost::weak_ptr<odin::net::socket>,
boost::weak_ptr<paradice::connection>, std::string const&) (paradice9.cpp:139)
==16604== by 0x805D00C:
boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void,
boost::_mfi::mf3<void, paradice9::impl, boost::weak_ptr<odin::net::socket>,
boost::weak_ptr<paradice::connection>, std::string const&>,
boost::_bi::list4<boost::_bi::value<paradice9::impl*>,
boost::_bi::value<boost::weak_ptr<odin::net::socket> >,
boost::_bi::value<boost::weak_ptr<paradice::connection> >, boost::arg<1> > >,
void, std::string>::invoke(boost::detail::function::function_buffer&,
std::string) (mem_fn_template.hpp:393)
==16604== by 0x808E5CC: paradice::connection::impl::announce_terminal_type()
(function_template.hpp:760)
In short, whereas the first call chain is protected by a strand, the second
(from client::set_connection down) is not. This may be the cause of one of the
primary MT problems.
Original comment by matthew....@gmail.com
on 15 Oct 2012 at 12:59
Confirmed -- at first glance, thunking set_connection out to be dispatched on
the GUI strand removes this error.
Original comment by matthew....@gmail.com
on 15 Oct 2012 at 1:10
Original comment by matthew....@gmail.com
on 5 Sep 2013 at 11:52
I just ran Paradice with Clang's thread sanitizer (-fsanitize=thread), and the
output from just one client logging in indicates that there's a lot to clean
up. This may require some serious restructuring post-C++11 conversion.
Here's the very first data race.
WARNING: ThreadSanitizer: data race (pid=20450)
Read of size 1 at 0x7d080000d3cc by thread T1:
#0 void boost::asio::detail::reactive_socket_service_base::async_send<boost::asio::mutable_buffers_1, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > >(boost::asio::detail::reactive_socket_service_base::base_implementation_type&, boost::asio::mutable_buffers_1 const&, int, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >) <null>:0 (paradice.exe+0x0000003f28a5)
#1 boost::asio::async_result<boost::asio::handler_type<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >, void (boost::system::error_code, unsigned long)>::type>::type boost::asio::stream_socket_service<boost::asio::ip::tcp>::async_send<boost::asio::mutable_buffers_1, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > >(boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>::implementation_type&, boost::asio::mutable_buffers_1 const&, int, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > const&) <null>:0 (paradice.exe+0x0000003f253b)
#2 boost::asio::async_result<boost::asio::handler_type<boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, void (boost::system::error_code, unsigned long)>::type>::type boost::asio::async_write<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&, boost::asio::mutable_buffers_1 const&, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > const&) <null>:0 (paradice.exe+0x0000003f186e)
#3 odin::net::socket::impl::write_first_request() <null>:0 (paradice.exe+0x0000003f151c)
#4 odin::net::socket::impl::async_write(std::vector<unsigned char, std::allocator<unsigned char> > const&, boost::function<void (unsigned long)> const&) <null>:0 (paradice.exe+0x0000003efaf5)
#5 non-virtual thunk to odin::net::socket::async_write(std::vector<unsigned char, std::allocator<unsigned char> > const&, boost::function<void (unsigned long)> const&) <null>:0 (paradice.exe+0x0000003ee5ef)
#6 odin::telnet::stream::impl::check_async_write_requests() <null>:0 (paradice.exe+0x0000004096f7)
#7 void boost::asio::asio_handler_invoke<boost::_bi::bind_t<void, boost::_mfi::mf0<void, odin::telnet::stream::impl>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<odin::telnet::stream::impl> > > > >(boost::_bi::bind_t<void, boost::_mfi::mf0<void, odin::telnet::stream::impl>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<odin::telnet::stream::impl> > > >, ...) <null>:0 (paradice.exe+0x0000004176bb)
#8 boost::asio::detail::completion_handler<boost::_bi::bind_t<void, boost::_mfi::mf0<void, odin::telnet::stream::impl>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<odin::telnet::stream::impl> > > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) <null>:0 (paradice.exe+0x0000004173d6)
#9 boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) <null>:0 (paradice.exe+0x00000023c167)
#10 boost::asio::detail::task_io_service::run(boost::system::error_code&) <null>:0 (paradice.exe+0x00000023b62f)
#11 run_io_service(boost::asio::io_service&) <null>:0 (paradice.exe+0x00000021de7d)
#12 boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(boost::asio::io_service&), boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > > >::run() <null>:0 (paradice.exe+0x0000002213d9)
#13 thread_proxy <null>:0 (libboost_thread.so.1.54.0+0x00000000c279)
Previous write of size 1 at 0x7d080000d3cc by thread T7:
#0 boost::asio::detail::reactive_socket_service_base::start_op(boost::asio::detail::reactive_socket_service_base::base_implementation_type&, int, boost::asio::detail::reactor_op*, bool, bool, bool) <null>:0 (paradice.exe+0x0000003f2af2)
#1 void boost::asio::detail::reactive_socket_service_base::async_receive<boost::asio::mutable_buffers_1, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > >(boost::asio::detail::reactive_socket_service_base::base_implementation_type&, boost::asio::mutable_buffers_1 const&, int, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >) <null>:0 (paradice.exe+0x0000003f4dd5)
#2 boost::asio::async_result<boost::asio::handler_type<boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >, void (boost::system::error_code, unsigned long)>::type>::type boost::asio::stream_socket_service<boost::asio::ip::tcp>::async_receive<boost::asio::mutable_buffers_1, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > >(boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>::implementation_type&, boost::asio::mutable_buffers_1 const&, int, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > const&) <null>:0 (paradice.exe+0x0000003f49bb)
#3 boost::asio::async_result<boost::asio::handler_type<boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, void (boost::system::error_code, unsigned long)>::type>::type boost::asio::async_read<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&, boost::asio::mutable_buffers_1 const&, boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > const&) <null>:0 (paradice.exe+0x0000003f3d0e)
#4 odin::net::socket::impl::async_read(unsigned long, boost::function<void (std::vector<unsigned char, std::allocator<unsigned char> >)> const&) <null>:0 (paradice.exe+0x0000003ef4fd)
#5 odin::net::socket::async_read(unsigned long, boost::function<void (std::vector<unsigned char, std::allocator<unsigned char> >)> const&) <null>:0 (paradice.exe+0x0000003ee36f)
#6 odin::telnet::stream::impl::check_async_read_requests() <null>:0 (paradice.exe+0x0000004184fe)
#7 void boost::asio::asio_handler_invoke<boost::_bi::bind_t<void, boost::_mfi::mf0<void, odin::telnet::stream::impl>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<odin::telnet::stream::impl> > > > >(boost::_bi::bind_t<void, boost::_mfi::mf0<void, odin::telnet::stream::impl>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<odin::telnet::stream::impl> > > >, ...) <null>:0 (paradice.exe+0x0000004176bb)
#8 boost::asio::detail::completion_handler<boost::_bi::bind_t<void, boost::_mfi::mf0<void, odin::telnet::stream::impl>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<odin::telnet::stream::impl> > > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) <null>:0 (paradice.exe+0x0000004173d6)
#9 boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) <null>:0 (paradice.exe+0x00000023c167)
#10 boost::asio::detail::task_io_service::run(boost::system::error_code&) <null>:0 (paradice.exe+0x00000023b62f)
#11 run_io_service(boost::asio::io_service&) <null>:0 (paradice.exe+0x00000021de7d)
#12 boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(boost::asio::io_service&), boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > > >::run() <null>:0 (paradice.exe+0x0000002213d9)
#13 thread_proxy <null>:0 (libboost_thread.so.1.54.0+0x00000000c279)
Location is heap block of size 32 at 0x7d080000d3c0 allocated by main thread:
#0 operator new(unsigned long) /home/chaplain/code/llvm/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:560 (paradice.exe+0x000000194479)
#1 odin::net::server::impl::schedule_accept() <null>:0 (paradice.exe+0x0000003e905a)
#2 odin::net::server::server(boost::asio::io_service&, unsigned short, boost::function<void (boost::shared_ptr<odin::net::socket>)> const&) <null>:0 (paradice.exe+0x0000003e8a28)
#3 paradice9::impl::impl(boost::asio::io_service&, boost::shared_ptr<boost::asio::io_service::work>, unsigned int) <null>:0 (paradice.exe+0x0000002127a6)
#4 paradice9::paradice9(boost::asio::io_service&, boost::shared_ptr<boost::asio::io_service::work>, unsigned int) <null>:0 (paradice.exe+0x0000002124cd)
#5 main <null>:0 (paradice.exe+0x00000021cbb9)
Thread T1 (tid=20454, running) created by main thread at:
#0 pthread_create /home/chaplain/code/llvm/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:877 (paradice.exe+0x00000019812b)
#1 boost::thread::start_thread_noexcept() <null>:0 (libboost_thread.so.1.54.0+0x00000000bdf6)
#2 boost::thread::thread<void (*)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service> >(void (*)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service>, boost::disable_if<boost::thread_detail::is_convertible<void (*&)(boost::asio::io_service&), boost::thread_attributes>, boost::thread::dummy*>::type) <null>:0 (paradice.exe+0x000000220405)
#3 boost::detail::sp_if_not_array<boost::thread>::type boost::make_shared<boost::thread, void (*)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service> >(void (* const&)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service> const&) <null>:0 (paradice.exe+0x00000021f350)
#4 main <null>:0 (paradice.exe+0x00000021cc7b)
Thread T7 (tid=20460, running) created by main thread at:
#0 pthread_create /home/chaplain/code/llvm/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:877 (paradice.exe+0x00000019812b)
#1 boost::thread::start_thread_noexcept() <null>:0 (libboost_thread.so.1.54.0+0x00000000bdf6)
#2 boost::thread::thread<void (*)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service> >(void (*)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service>, boost::disable_if<boost::thread_detail::is_convertible<void (*&)(boost::asio::io_service&), boost::thread_attributes>, boost::thread::dummy*>::type) <null>:0 (paradice.exe+0x000000220405)
#3 boost::detail::sp_if_not_array<boost::thread>::type boost::make_shared<boost::thread, void (*)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service> >(void (* const&)(boost::asio::io_service&), boost::reference_wrapper<boost::asio::io_service> const&) <null>:0 (paradice.exe+0x00000021f350)
#4 main <null>:0 (paradice.exe+0x00000021cc7b)
SUMMARY: ThreadSanitizer: data race ??:0 void
boost::asio::detail::reactive_socket_service_base::async_send<boost::asio::mutab
le_buffers_1,
boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::
tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >,
boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t,
boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl,
boost::system::error_code const&, unsigned long>,
boost::_bi::list3<boost::_bi::value<boost::shared_ptr<odin::net::socket::impl>
>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >
>(boost::asio::detail::reactive_socket_service_base::base_implementation_type&,
boost::asio::mutable_buffers_1 const&, int,
boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::
tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >,
boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t,
boost::_bi::bind_t<void, boost::_mfi::mf2<void, odin::net::socket::impl, boost::
Original comment by matthew....@gmail.com
on 2 Dec 2013 at 8:01
Original issue reported on code.google.com by
matthew....@gmail.com
on 20 Jan 2011 at 11:51