[ https://issues.apache.org/jira/browse/PROTON-1591?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Justin Ross updated PROTON-1591: -------------------------------- Fix Version/s: proton-c-0.18.0 > [proton-cpp] Scheduling task from a scheduled task will deadlock > ---------------------------------------------------------------- > > Key: PROTON-1591 > URL: https://issues.apache.org/jira/browse/PROTON-1591 > Project: Qpid Proton > Issue Type: Bug > Components: cpp-binding > Environment: commit 6a57a8c986fbf86ad8ad109d673a89a5ae84c544 > (upstream/master) > Author: Cliff Jansen <cliffjan...@apache.org> > Date: Thu Sep 14 23:29:14 2017 -0700 > PROTON-1349: completed and improved implementation, but still fails many > tests > Reporter: Jiri Danek > Assignee: Cliff Jansen > Fix For: proton-c-0.18.0 > > > Modify the {{cpp/simple_send.cpp}} example the following way > {code} > diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp > index a4c2272d..92e60ee0 100644 > --- a/examples/cpp/simple_send.cpp > +++ b/examples/cpp/simple_send.cpp > @@ -29,9 +29,11 @@ > #include <proton/messaging_handler.hpp> > #include <proton/tracker.hpp> > #include <proton/types.hpp> > +#include <proton/work_queue.hpp> > > #include <iostream> > #include <map> > +#include <functional> > > #include "fake_cpp11.hpp" > > @@ -45,15 +47,28 @@ class simple_send : public proton::messaging_handler { > int confirmed; > int total; > > + std::function<void()> callback; > + > public: > simple_send(const std::string &s, const std::string &u, const > std::string &p, int c) : > - url(s), user(u), password(p), sent(0), confirmed(0), total(c) {} > + url(s), user(u), password(p), sent(0), confirmed(0), total(c) { > + callback = [this]() { > + std::cout << "Entering callback" << std::endl; > +// TODO: uncomment one of the two commands below > +//**************************************************************************************************** > +// sender.container().stop(); > +// sender.container().schedule(1 * proton::duration::SECOND, > proton::work(callback)); > +//**************************************************************************************************** > + std::cout << "Leaving callback" << std::endl; > + }; > + } > > void on_container_start(proton::container &c) OVERRIDE { > proton::connection_options co; > if (!user.empty()) co.user(user); > if (!password.empty()) co.password(password); > sender = c.open_sender(url, co); > + c.schedule(1 * proton::duration::SECOND, proton::work(callback)); > } > > void on_sendable(proton::sender &s) OVERRIDE { > {code} > Now uncomment one of the two commented out commands. Either to stop the > container from the inside scheduled task, or to schedule new task from inside > the scheduled task. When executed, the program will deadlock. > {noformat} > Program received signal SIGINT, Interrupt. > 0x00007ffff68ef6dc in __lll_lock_wait () from > /nix/store/l48biijfr1j6d5kdg911051x2phfjrz7-glibc-2.25/lib/libpthread.so.0 > (gdb) bt > #0 0x00007ffff68ef6dc in __lll_lock_wait () from > /nix/store/l48biijfr1j6d5kdg911051x2phfjrz7-glibc-2.25/lib/libpthread.so.0 > #1 0x00007ffff68e88e5 in pthread_mutex_lock () from > /nix/store/l48biijfr1j6d5kdg911051x2phfjrz7-glibc-2.25/lib/libpthread.so.0 > #2 0x00007ffff7baf1e8 in __gthread_mutex_lock (__mutex=0x61e148) at > /nix/store/pdidaf83cvkrgx8xjgjdnl5m1naqjbfk-gcc-7.1.0/include/c++/7.1.0/x86_64-pc-linux-gnu/bits/gthr-default.h:748 > #3 std::mutex::lock (this=0x61e148) at > /nix/store/pdidaf83cvkrgx8xjgjdnl5m1naqjbfk-gcc-7.1.0/include/c++/7.1.0/bits/std_mutex.h:103 > #4 std::lock_guard<std::mutex>::lock_guard (__m=..., this=<synthetic > pointer>) at > /nix/store/pdidaf83cvkrgx8xjgjdnl5m1naqjbfk-gcc-7.1.0/include/c++/7.1.0/bits/std_mutex.h:162 > #5 proton::container::impl::schedule (this=this@entry=0x61e140, delay=..., > delay@entry=..., f=...) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:399 > #6 0x00007ffff7baccc8 in proton::container::schedule > (this=this@entry=0x7fffffffc668, d=..., f=...) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/container.cpp:109 > #7 0x00000000004065f9 in > simple_send::simple_send(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > const&, int)::{lambda()#1}::operator()() const > (__closure=<optimized out>) at > /home/jdanek/Work/repos/qpid-proton/examples/cpp/simple_send.cpp:58 > #8 std::_Function_handler<void (), > simple_send::simple_send(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > const&, int)::{lambda()#1}>::_M_invoke(std::_Any_data > const&) (__functor=...) at > /nix/store/pdidaf83cvkrgx8xjgjdnl5m1naqjbfk-gcc-7.1.0/include/c++/7.1.0/bits/std_function.h:316 > #9 0x00007ffff7baf706 in std::function<void ()>::operator()() const > (this=<optimized out>) at > /nix/store/pdidaf83cvkrgx8xjgjdnl5m1naqjbfk-gcc-7.1.0/include/c++/7.1.0/bits/std_function.h:706 > #10 proton::work::operator() (this=<optimized out>) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/include/proton/work_queue.hpp:59 > #11 proton::container::impl::run_timer_jobs (this=this@entry=0x61e140) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:439 > #12 0x00007ffff7bafe10 in proton::container::impl::handle > (this=this@entry=0x61e140, event=0x625590) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:478 > #13 0x00007ffff7baffeb in proton::container::impl::thread > (this=this@entry=0x61e140) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:613 > #14 0x00007ffff7bb0393 in proton::container::impl::run (this=0x61e140, > threads=threads@entry=1) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:651 > #15 0x00007ffff7bac74d in proton::container::run > (this=this@entry=0x7fffffffc668) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/container.cpp:83 > #16 0x0000000000404d2f in main (argc=<optimized out>, argv=<optimized out>) > at /home/jdanek/Work/repos/qpid-proton/examples/cpp/simple_send.cpp:115 > #17 0x00007ffff6b1d530 in __libc_start_main () from > /nix/store/l48biijfr1j6d5kdg911051x2phfjrz7-glibc-2.25/lib/libc.so.6 > #18 0x00000000004051aa in _start () at ../sysdeps/x86_64/start.S:120 > {noformat} > The lock was first acquired here > {noformat} > (gdb) frame 12 > #12 0x00007ffff7bafe10 in proton::container::impl::handle > (this=this@entry=0x61e140, event=0x625590) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:478 > 478 run_timer_jobs(); > (gdb) l > 473 > 474 case PN_PROACTOR_TIMEOUT: { > 475 GUARD(lock_); > 476 // Can get an immediate timeout, if we have a container event > loop inject > 477 if ( deferred_.size()>0 ) { > 478 run_timer_jobs(); > 479 } > 480 > 481 // Run every container event loop job > 482 // This is not at all efficient and single threads all these > jobs, but it does correctly > {noformat} > and the thread tries to reacquire it again here (this is the schedule task > from scheduled task case) > {noformat} > (gdb) frame 5 > #5 proton::container::impl::schedule (this=this@entry=0x61e140, delay=..., > delay@entry=..., f=...) at > /home/jdanek/Work/repos/qpid-proton/proton-c/bindings/cpp/src/proactor_container_impl.cpp:399 > 399 GUARD(lock_); > (gdb) l > 394 lc.listen_handler_ = &lh; > 395 return proton::listener(listener); > 396 } > 397 > 398 void container::impl::schedule(duration delay, work f) { > 399 GUARD(lock_); > 400 timestamp now = timestamp::now(); > 401 > 402 // Record timeout; Add callback to timeout sorted list > 403 scheduled s = {now+delay, f}; > {noformat} > This reproducer is based on larger application which was using the previous > version of the task scheduling API and which was now updated to compile with > Proton 0.18. -- This message was sent by Atlassian JIRA (v6.4.14#64029) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@qpid.apache.org For additional commands, e-mail: dev-h...@qpid.apache.org