Skip to content

proxy: Name threads spawned by the event loop - #324

Open
ViniciusCestarii wants to merge 2 commits into
bitcoin-core:masterfrom
ViniciusCestarii:rename-os-threads
Open

proxy: Name threads spawned by the event loop#324
ViniciusCestarii wants to merge 2 commits into
bitcoin-core:masterfrom
ViniciusCestarii:rename-os-threads

Conversation

@ViniciusCestarii

Copy link
Copy Markdown
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 Init.construct$Params
2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server send response #68 Init.construct$Results
2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server recv request  #69 Init.makeRpc$Params
2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server post request  #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
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 Init.makeRpc$Results
2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server recv request  #70 Rpc.executeRpc$Params
2026-07-31T13:56:55Z [ipc] {bitcoin-node-43644/b-capnp-loop-43647} IPC server post request  #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
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 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.

@DrahtBot

DrahtBot commented Jul 31, 2026

Copy link
Copy Markdown

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

Reviews

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

Type Reviewers
Stale ACK enirox001

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

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.

@ryanofsky ryanofsky left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/mp/util.cpp
Comment thread src/mp/util.cpp Outdated
Comment thread src/mp/util.cpp Outdated
Comment thread src/mp/util.cpp
pthread_setname_np(name);
#else
// Prevent warnings for unused parameters...
(void)name;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened for bitcoin core: bitcoin/bitcoin#35884

@ViniciusCestarii

Copy link
Copy Markdown
Contributor Author

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

@DrahtBot DrahtBot mentioned this pull request Aug 5, 2026

@enirox001 enirox001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 67af015#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);
  }

@ViniciusCestarii

Copy link
Copy Markdown
Contributor Author

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 56cac0d: it adds tests under macro HAVE_PTHREAD_GETNAME_NP, so it only tests platforms that can get the thread OS name.

@ViniciusCestarii

Copy link
Copy Markdown
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants