fix: EventLoop::post() deadlocks when posted function throws #260

pull hulxv wants to merge 1 commits into bitcoin-core:master from hulxv:fix/deadlock-on-exception changing 1 files +3 −1
  1. hulxv commented at 7:55 pm on March 19, 2026: none
    Fix #259
  2. DrahtBot commented at 7:55 pm on March 19, 2026: none

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

  3. fix: `EventLoop::post()` deadlocks when posted function throws 5cf327871f
  4. in src/mp/proxy.cpp:250 in c6ad6057f0
    244@@ -239,13 +245,26 @@ void EventLoop::loop()
    245     kj::Own<kj::AsyncIoStream> wait_stream{
    246         m_io_context.lowLevelProvider->wrapSocketFd(m_wait_fd, kj::LowLevelAsyncIoProvider::TAKE_OWNERSHIP)};
    247     int post_fd{m_post_fd};
    248+    KJ_DEFER({
    249+        Lock lock(m_mutex);
    250+        m_cv.wait(lock.m_lock, [this]() MP_REQUIRES(m_mutex) { return m_num_clients == 0; });
    


    ryanofsky commented at 6:53 pm on March 23, 2026:

    In commit “fix: EventLoop::post() deadlocks when posted function throws” (c6ad6057f0ce488f483f2b00a8af7a15e3a73787)

    It seems like waiting for clients to be released here might just replace one deadlock with another deadlock in the general case m_post_fn throws and there is not just a single client.

    I tend to think if m_post_fn is going to throws, reasonable things to do might be:

    • Abort so this is detected as a bug
    • Or keep executing the event loop, but log an error
    • Or let the exception immediately propagate to the caller like happens currently.

    Trying to propagate the exception, but waiting for resources to be freed and possibly hanging seems like it adds more complexity without providing a reliable benefit


    hulxv commented at 6:41 am on March 27, 2026:

    oh ok, I didn’t notice that. thanks for catching it.

    I tend to think if m_post_fn is going to throws, reasonable things to do might be:

    * Abort so this is detected as a bug
    
    * Or keep executing the event loop, but log an error
    
    * Or let the exception immediately propagate to the caller like happens currently.
    

    I think the best and simplest solution here is keeping the executing of the event loop and just log an error. what do you think?


    ryanofsky commented at 9:14 am on March 27, 2026:

    re: #260 (review)

    I think the best and simplest solution here is keeping the executing of the event loop and just log an error. what do you think?

    Yes I think logging the exception here would be a simple improvement that should help debugging. Would recommend kj::runCatchingExceptions for that and kj::str() to turn the exception into a string.

    Using catch (...) { eptr = std::current_exception(); } to catch the exception in the event loop thread and std::rethrow_exception(eptr); to rethrow it EventLoop::post() could be a different improvement that would help debugging, but I don’t know if it would add too much complexity.

    Keeping the event loop running after the exception is thrown should also be an improvement.


    hulxv commented at 7:54 pm on March 27, 2026:
    done
  5. hulxv force-pushed on Mar 27, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/libmultiprocess. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-03-29 21:30 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me