qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Justin Ross (JIRA)" <j...@apache.org>
Subject [jira] [Assigned] (PROTON-1591) [proton-cpp] Scheduling task from a scheduled task will deadlock
Date Thu, 28 Sep 2017 23:05:00 GMT

     [ https://issues.apache.org/jira/browse/PROTON-1591?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Justin Ross reassigned PROTON-1591:
-----------------------------------

    Assignee: Alan Conway  (was: Andrew Stitcher)

> [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 <cliffjansen@apache.org>
> Date:   Thu Sep 14 23:29:14 2017 -0700
>     PROTON-1349: completed and improved implementation, but still fails many tests
>            Reporter: Jiri Daněk
>            Assignee: Alan Conway
>             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-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Mime
View raw message