proxy: Name threads spawned by the event loop #324

pull ViniciusCestarii wants to merge 2 commits into bitcoin-core:master from ViniciusCestarii:rename-os-threads changing 6 files +101 −1
  1. ViniciusCestarii commented at 2:05 PM on July 31, 2026: contributor

    Threads spawned by makeThread(), makePool() and the async cleanup thread inherit the name of the thread that created them, so tooling and log lines can't distinguish them from it. This PR rename them at creation.

    bitcoin-node

    vinicius@archlinux ~> ps -T -p $(pidof bitcoin-node) -o tid,comm
        TID COMMAND
      35689 bitcoin-node
      35690 b-scheduler
      35692 b-capnp-loop
      35694 b-http.00
      35695 b-http.01
      ...
      35740 b-opencon
      35741 b-msghand
      36017 capnp-async -- (Before this would be named "b-capnp-loop")
    

    bitcoin-wallet

    vinicius@archlinux ~> ps -T -p $(pidof bitcoin-wallet) -o tid,comm
        TID COMMAND
      35691 bitcoin-wallet
      35693 capnp-worker -- (Before this would be named "bitcoin-wallet")
      35742 b-schedqueue
    

    Since ThreadName() reads the name back with pthread_getname_np(), log lines pick this up too:

    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Creating mp::ProxyServerBase<ipc::capnp::messages::Init, interfaces::Init> 0x7ff52c005430
    2026-07-31T13:56:55Z ipc: {bitcoin-node-43644/b-capnp-loop-43647} IPC server: socket connected.
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server recv request  [#68](/bitcoin-core-multiprocess/68/) Init.construct$Params
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server send response [#68](/bitcoin-core-multiprocess/68/) Init.construct$Results
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server recv request  [#69](/bitcoin-core-multiprocess/69/) Init.makeRpc$Params
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server post request  [#69](/bitcoin-core-multiprocess/69/) {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)}
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)} IPC server executing request [#69](/bitcoin-core-multiprocess/69/)
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Creating mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60403e928
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)} Creating mp::ProxyServerBase<ipc::capnp::messages::Rpc, interfaces::Rpc> 0x7ff52c0053b0
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Cleaning up mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60403e928
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Destroying mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60403e928
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server send response [#69](/bitcoin-core-multiprocess/69/) Init.makeRpc$Results
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server recv request  [#70](/bitcoin-core-multiprocess/70/) Rpc.executeRpc$Params
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server post request  [#70](/bitcoin-core-multiprocess/70/) {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)}
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)} IPC server executing request [#70](/bitcoin-core-multiprocess/70/)
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Creating mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff604017d48
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Creating mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60401b988
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Creating mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60401bf28
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)} IPC client send ActorCallback.call$Params
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/capnp-worker-43826 (from bitcoin-cli-43824/bitcoin-cli-43824)} IPC client recv ActorCallback.call$Results
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Cleaning up mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff604017d48
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Destroying mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff604017d48
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server send response [#70](/bitcoin-core-multiprocess/70/) Rpc.executeRpc$Results
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server destroy mp::ProxyServer<ipc::capnp::messages::Rpc>
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Cleaning up mp::ProxyServerBase<ipc::capnp::messages::Rpc, interfaces::Rpc> 0x7ff52c0053b0
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Destroying mp::ProxyServerBase<ipc::capnp::messages::Rpc, interfaces::Rpc> 0x7ff52c0053b0
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Cleaning up mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60401bf28
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Destroying mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60401bf28
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Cleaning up mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60401b988
    2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} Destroying mp::ProxyClientBase<mp::Thread, capnp::Void> 0x7ff60401b988
    2026-07-31T13:56:55Z ipc: {bitcoin-node-43644/b-capnp-loop-43647} IPC server: socket disconnected.
    
  2. DrahtBot commented at 2:05 PM on July 31, 2026: none

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    ACK ryanofsky
    Stale ACK enirox001

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #231 (Add windows support by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. in src/mp/util.cpp:83 in 61b6cd2577 outdated
      79 | @@ -74,6 +80,21 @@ template <std::size_t N>
      80 |  
      81 |  } // namespace
      82 |  
      83 | +void SetOsThreadName(const char* name)
    


    ryanofsky commented at 9:36 PM on August 3, 2026:

    In commit "proxy: Name threads spawned by the event loop" (61b6cd25776ea95a2d52910ba8799105d6cb838b)

    I'd find it useful to have a comment here like // Copied from https://github.com/bitcoin/bitcoin/blob/d3e40af2597/src/util/threadnames.cpp#L21-L36 so this can be kept in sync if it makes sense.


    ViniciusCestarii commented at 12:04 PM on August 4, 2026:

    I agree that It makes sense. Done on 67af01544af579d843eff13104654e5f8c73f7c9

  4. in src/mp/util.cpp:33 in 61b6cd2577
      28 | @@ -29,9 +29,15 @@
      29 |  #include <sys/syscall.h>
      30 |  #endif
      31 |  
      32 | -#ifdef HAVE_PTHREAD_GETTHREADID_NP
      33 | +
      34 | +#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
    


    ryanofsky commented at 9:48 PM on August 3, 2026:

    In commit "proxy: Name threads spawned by the event loop" (61b6cd25776ea95a2d52910ba8799105d6cb838b)

    Unclear why HAVE_PTHREAD_GETTHREADID_NP was removed here. It is still used another place below. Using HAVE_PTHREAD_GETTHREADID_NP does seem more reliable than checking for specific platforms.


    ViniciusCestarii commented at 12:04 PM on August 4, 2026:

    Ops yes I looked at it and it does make more sense to use HAVE_PTHREAD_GETTHREADID_NP. Done on 67af01544af579d843eff13104654e5f8c73f7c9

  5. in src/mp/util.cpp:88 in 61b6cd2577
      79 | @@ -74,6 +80,21 @@ template <std::size_t N>
      80 |  
      81 |  } // namespace
      82 |  
      83 | +void SetOsThreadName(const char* name)
      84 | +{
      85 | +#if defined(PR_SET_NAME)
      86 | +    // Only the first 15 characters are used (16 - NUL terminator)
      87 | +    ::prctl(PR_SET_NAME, name, 0, 0, 0);
      88 | +#elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
    


    ryanofsky commented at 9:49 PM on August 3, 2026:

    In commit "proxy: Name threads spawned by the event loop" (61b6cd25776ea95a2d52910ba8799105d6cb838b)

    Probably better to use HAVE_PTHREAD_GETTHREADID_NP here


    ViniciusCestarii commented at 12:04 PM on August 4, 2026:

    True, done on 67af01544af579d843eff13104654e5f8c73f7c9

  6. in src/mp/util.cpp:94 in 61b6cd2577 outdated
      89 | +    pthread_set_name_np(pthread_self(), name);
      90 | +#elif defined(__APPLE__)
      91 | +    pthread_setname_np(name);
      92 | +#else
      93 | +    // Prevent warnings for unused parameters...
      94 | +    (void)name;
    


    ryanofsky commented at 9:50 PM on August 3, 2026:

    In commit "proxy: Name threads spawned by the event loop" (61b6cd25776ea95a2d52910ba8799105d6cb838b)

    Note for followup probably will want to extend this to windows.


    ViniciusCestarii commented at 12:04 PM on August 4, 2026:

    I agree, for Bitcoin Core it would be useful too.


    ViniciusCestarii commented at 9:57 PM on August 4, 2026:
  7. ryanofsky commented at 9:55 PM on August 3, 2026: collaborator

    Code review 61b6cd25776ea95a2d52910ba8799105d6cb838b. Looks good and thread names should be helpful, but I think the include check was probably better off using HAVE_PTHREAD_GETTHREADID_NP

  8. ViniciusCestarii force-pushed on Aug 4, 2026
  9. ViniciusCestarii commented at 12:06 PM on August 4, 2026: contributor

    Thanks for the review @ryanofsky! I forced push 67af01544af579d843eff13104654e5f8c73f7c9 so now it uses the macro HAVE_PTHREAD_GETTHREADID_NP instead.

  10. enirox001 approved
  11. enirox001 commented at 4:20 PM on August 6, 2026: contributor

    ACK https://github.com/bitcoin-core/libmultiprocess/pull/324/changes/67af01544af579d843eff13104654e5f8c73f7c9#r3730102868

    This looks good, and i can think of usecases for development and debugging,

    But i wonder why no test covergae was added for this change? is there a reason for this? I think a simple test to test the behaviour of the method would be nice to have. Perhaps something like this?

    KJ_TEST("IPC worker has OS thread name")
      {
          TestSetup setup;
          ProxyClient<messages::FooInterface>* foo = setup.client.get();
          foo->initThreadMap();
          setup.server->m_impl->m_fn = [] {};
    
          EventLoop& loop = *setup.server->m_context.connection->m_loop;
          std::promise<std::string> thread_name;
          auto thread_name_future = thread_name.get_future();
    
          loop.testing_hook_makethread_created = [&] {
              thread_name.set_value(ThreadName(""));
          };
    
          foo->callFnAsync();
    
          const std::string name = thread_name_future.get();
          KJ_EXPECT(name.find("/capnp-worker-") != std::string::npos,
          name);
      }
    
  12. ViniciusCestarii commented at 5:55 PM on August 6, 2026: contributor

    But i wonder why no test covergae was added for this change? is there a reason for this? I think a simple test to test the behaviour of the method would be nice to have. Perhaps something like this?

    Thanks for reviewing! Good point. tbh I thought it wound't be worth it but since this changes visible behavior (logs append OS thread name) it does make sense to add tests.

    Pushed 56cac0daad2a9cf865d9461e73fa165c19dd3105: it adds tests under macro HAVE_PTHREAD_GETNAME_NP, so it only tests platforms that can get the thread OS name.

  13. ViniciusCestarii commented at 6:22 PM on August 6, 2026: contributor

    Just thinking out loud and out of scope here: it might be worth storing the thread name in a thread_local variable just like Bitcoin Core so the log string doesn't need to rely on platform specific get and set OS thread name and looks alike on every platform, while the OS thread naming itself stays as is for tools like ps/gdb, with support for other platforms added on demand.

  14. ryanofsky commented at 9:32 PM on August 10, 2026: collaborator

    Code review 56cac0daad2a9cf865d9461e73fa165c19dd3105. Note that tests seem to be failing currently on netbsd https://github.com/bitcoin-core/libmultiprocess/actions/runs/31124198769/job/93544439620?pr=324 https://github.com/bitcoin-core/libmultiprocess/actions/runs/31124198769/job/93544439676?pr=324 with errors like /home/runner/work/libmultiprocess/libmultiprocess/test/mp/test/test.cpp:566: failed: expected name.find("/capnp-worker-") != std::string::npos [18446744073709551615 != 18446744073709551615]; name = -29244/0x7d42c7699800

  15. ViniciusCestarii force-pushed on Aug 11, 2026
  16. proxy: Name threads spawned by the event loop 648a18589c
  17. test: Cover OS thread names for worker, pool, and async threads 9f25ffca5b
  18. ViniciusCestarii force-pushed on Aug 11, 2026
  19. ViniciusCestarii commented at 12:10 PM on August 11, 2026: contributor

    Forced push 9f25ffca5b0680db2c7f87cc5ab3a17aeadb815c. Added new macro HAVE_PTHREAD_SETNAME_NP_3ARG because NetBSD pthread_getname_np especifically only acepts 3 args: https://man.netbsd.org/pthread_getname_np.3. Now tests should pass.

    edit: netbsd CI failed: make: "/usr/pkgsrc/mk/compiler/gcc.mk" line 331: Could not find ../../lang/gcc16/version.mk

  20. hebasto commented at 4:38 PM on August 11, 2026: member

    edit: netbsd CI failed: make: "/usr/pkgsrc/mk/compiler/gcc.mk" line 331: Could not find ../../lang/gcc16/version.mk

    Fixed in #340.

  21. in src/mp/util.cpp:89 in 648a18589c
      84 | +#if defined(PR_SET_NAME)
      85 | +    // Only the first 15 characters are used (16 - NUL terminator)
      86 | +    ::prctl(PR_SET_NAME, name, 0, 0, 0);
      87 | +#elif defined(HAVE_PTHREAD_SETNAME_NP_3ARG)
      88 | +    pthread_setname_np(pthread_self(), "%s", const_cast<char*>(name));
      89 | +#elif defined(HAVE_PTHREAD_GETTHREADID_NP)
    


    ryanofsky commented at 7:33 PM on August 11, 2026:

    In commit "proxy: Name threads spawned by the event loop" (648a18589c45c953a498af40f2f3a384c407e18b)

    Would make sense to introduce a HAVE_PTHREAD_SET_NAME_NP macro here instead of using HAVE_PTHREAD_GETTHREADID_NP (which is for pthread_getthreadid_np)

  22. in src/mp/util.cpp:86 in 648a18589c
      77 | @@ -74,6 +78,24 @@ template <std::size_t N>
      78 |  
      79 |  } // namespace
      80 |  
      81 | +// Copied from https://github.com/bitcoin/bitcoin/blob/d3e40af2597/src/util/threadnames.cpp#L21-L36
      82 | +void SetOsThreadName(const char* name)
      83 | +{
      84 | +#if defined(PR_SET_NAME)
      85 | +    // Only the first 15 characters are used (16 - NUL terminator)
      86 | +    ::prctl(PR_SET_NAME, name, 0, 0, 0);
    


    ryanofsky commented at 7:38 PM on August 11, 2026:

    In commit "proxy: Name threads spawned by the event loop" (648a18589c45c953a498af40f2f3a384c407e18b)

    Could be nice for background to mention platforms being used in comments:

    prctl(PR_SET_NAME, name, 0, 0, 0); // Linux
    pthread_setname_np(pthread_self(), "%s", const_cast<char*>(name)); // NetBSD
    pthread_set_name_np(pthread_self(), name); // FreeBSD
    pthread_setname_np(name); // macOS
    
  23. ryanofsky approved
  24. ryanofsky commented at 7:42 PM on August 11, 2026: collaborator

    Code review ACK 9f25ffca5b0680db2c7f87cc5ab3a17aeadb815c. Looks good. I left some comments but they are not important, and looks like this could be merged after #340.

  25. DrahtBot requested review from enirox001 on Aug 11, 2026
  26. ryanofsky merged this on Aug 11, 2026
  27. ryanofsky closed this on Aug 11, 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-08-26 00:30 UTC

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