refactor: replace RecursiveMutex `m_most_recent_block_mutex` with Mutex #24062

pull theStack wants to merge 2 commits into bitcoin:master from theStack:202201-refactor_replace_recursive_mutex_cs_last_block changing 1 files +6 −5
  1. theStack commented at 1:53 AM on January 14, 2022: contributor

    This PR is related to #19303 and gets rid of the RecursiveMutex m_most_recent_block_mutex. All of the critical sections (5 in total) only directly access the guarded elements, i.e. it is not possible that within one section another one is called, and we can use a regular Mutex:

    https://github.com/bitcoin/bitcoin/blob/b019cdc036343a437fd7ced85467bd95f48d84c4/src/net_processing.cpp#L1650-L1655

    https://github.com/bitcoin/bitcoin/blob/b019cdc036343a437fd7ced85467bd95f48d84c4/src/net_processing.cpp#L1861-L1865

    https://github.com/bitcoin/bitcoin/blob/b019cdc036343a437fd7ced85467bd95f48d84c4/src/net_processing.cpp#L3149-L3152

    https://github.com/bitcoin/bitcoin/blob/b019cdc036343a437fd7ced85467bd95f48d84c4/src/net_processing.cpp#L3201-L3206

    https://github.com/bitcoin/bitcoin/blob/b019cdc036343a437fd7ced85467bd95f48d84c4/src/net_processing.cpp#L4763-L4769

    The scope of the last critical section is reduced in the first commit, in order to avoid calling the non-trivial method CConnman::PushMessage while the lock is held.

  2. DrahtBot commented at 2:24 AM on January 14, 2022: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    No conflicts as of last run.

  3. DrahtBot added the label P2P on Jan 14, 2022
  4. DrahtBot added the label Refactoring on Jan 14, 2022
  5. hebasto commented at 8:02 AM on January 14, 2022: member

    Concept ACK. Thanks!

  6. hebasto cross-referenced this on Jan 14, 2022 from issue Replace all of the RecursiveMutex instances with the Mutex ones by hebasto
  7. in src/net_processing.cpp:4708 in cac83660c0 outdated
    4703 | @@ -4704,7 +4704,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
    4704 |  
    4705 |                      bool fGotBlockFromCache = false;
    4706 |                      {
    4707 | -                        LOCK(cs_most_recent_block);
    4708 | +                        LOCK(most_recent_block_mutex);
    


    hebasto commented at 8:22 AM on January 14, 2022:

    ... it is not possible that within one section another one is called...

    It is not obvious where functions with a non-trivial body--like PushMessage--are called. Even everything is correct now, there is a possibility to introduce a recursion in the future by modifying the PushMessage function or other functions been called from within it.

    Could we just call PushMessage without holding most_recent_block_mutex?


    theStack commented at 12:35 PM on January 14, 2022:

    Fair enough, will take a deeper look.

  8. hebasto commented at 8:23 AM on January 14, 2022: member

    Approach ACK cac83660c07568820dcd0cd9cc71548bf05857c3.

  9. DrahtBot cross-referenced this on Jan 14, 2022 from issue net processing: Only support version 2 compact blocks by jnewbery
  10. theStack force-pushed on Jan 25, 2022
  11. theStack commented at 3:16 PM on January 25, 2022: contributor

    Added another commit which reduces the scope of the lock most_recent_block_mutex, as suggested by [@hebasto](/github-metadata-backup-bitcoin-bitcoin/contributor/hebasto/). Rather than calling the non-trivial method CConnman::PushMessage immediately, only the (cached) cmpctblock message is now assembled and sent after, outside of the critical section.

  12. DrahtBot cross-referenced this on Mar 12, 2022 from issue net processing: Move remaining globals into PeerManagerImpl by dergoegge
  13. DrahtBot added the label Needs rebase on Apr 30, 2022
  14. theStack renamed this:
    refactor: replace RecursiveMutex `cs_most_recent_block` with Mutex (and rename)
    refactor: replace RecursiveMutex `m_most_recent_block` with Mutex
    on May 1, 2022
  15. theStack force-pushed on May 1, 2022
  16. theStack renamed this:
    refactor: replace RecursiveMutex `m_most_recent_block` with Mutex
    refactor: replace RecursiveMutex `m_most_recent_block_mutex` with Mutex
    on May 1, 2022
  17. theStack commented at 11:58 PM on May 1, 2022: contributor

    Rebased on master. Note that the scripted-diff renaming commit (getting rid of the lock's cs_ prefix) was dropped as this was already resolved in the recently merged PR #24543. Also updated the PR title and description accordingly with the current critical section code snippets.

  18. DrahtBot removed the label Needs rebase on May 2, 2022
  19. DrahtBot added the label Needs rebase on May 16, 2022
  20. refactor: reduce scope of lock `m_most_recent_block_mutex`
    This avoids calling the non-trivial method
    `CConnman::PushMessage` within the critical section.
    8edd0d31ac
  21. refactor: replace RecursiveMutex `m_most_recent_block_mutex` with Mutex
    In each of the critical sections, only the the guarded variables are
    accessed, without any chance that within one section another one is
    called.  Hence, we can use an ordinary Mutex instead of RecursiveMutex.
    83003ffe04
  22. theStack force-pushed on May 16, 2022
  23. theStack commented at 1:35 PM on May 16, 2022: contributor

    Rebased on master, updated the PR description with the current critical section code snippets (shorter after #20799 has been merged). The boolean variable fGotBlockFromCache is now removed in the first commit and a std::optional on the cached message is used instead, which I think is a bit more elegant.

  24. in src/net_processing.cpp:4770 in 83003ffe04
    4769 | +                            cached_cmpctblock_msg = msgMaker.Make(NetMsgType::CMPCTBLOCK, *m_most_recent_compact_block);
    4770 |                          }
    4771 |                      }
    4772 | -                    if (!fGotBlockFromCache) {
    4773 | +                    if (cached_cmpctblock_msg.has_value()) {
    4774 | +                        m_connman.PushMessage(pto, std::move(cached_cmpctblock_msg.value()));
    


    furszy commented at 1:43 PM on May 16, 2022:

    As std::optional default value is nullopt. Could write it as:

    if (cached_cmpctblock_msg) {
        m_connman.PushMessage(pto, std::move(*cached_cmpctblock_msg));
    }
    

    MarcoFalke commented at 7:50 AM on May 17, 2022:

    Just realized, all of this could be written as:

    if (WITH_LOCK(m_most_recent_block_mutex, return m_most_recent_block_hash == pBestIndex->GetBlockHash())) {
        m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, *m_most_recent_compact_block));
    

    hebasto commented at 9:55 AM on May 17, 2022:

    m_most_recent_compact_block should also be accessed from within a critical section.

  25. furszy approved
  26. furszy commented at 2:06 PM on May 16, 2022: member

    Code ACK 83003ffe with a small comment.

  27. DrahtBot removed the label Needs rebase on May 16, 2022
  28. hebasto approved
  29. hebasto commented at 7:36 PM on May 16, 2022: member

    ACK 83003ffe049a432f6fa4127e054f073127e70b90

  30. w0xlt approved
  31. MarcoFalke merged this on May 17, 2022
  32. MarcoFalke closed this on May 17, 2022

  33. theStack deleted the branch on May 17, 2022
  34. hebasto cross-referenced this on May 20, 2022 from issue refactor: Improve thread safety analysis by propagating some negative capabilities by hebasto
  35. hebasto cross-referenced this on May 20, 2022 from issue Strengthen thread safety assertions by ajtowns
  36. MarcoFalke referenced this in commit aac99faa66 on May 20, 2022
  37. sidhujag referenced this in commit b1ab840410 on May 28, 2022
  38. bitcoin locked this on May 17, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-20 06:53 UTC