Do not hold cs_vNodes when making ForEachNode Callbacks #10697

pull TheBlueMatt wants to merge 2 commits into bitcoin:master from TheBlueMatt:2017-06-cnodestateaccessors-5 changing 4 files +118 −57
  1. TheBlueMatt commented at 9:19 PM on June 28, 2017: contributor

    Generally holding locks while making callbacks is a bad idea, and for my eventual per-CNodeState locks. Also makes DEBUG_LOCKORDER more strict in a way that it assumes so best to enforce the requirement that locks are released in the order they are taken.

    These two commits were pulled out of #10652 as they were entirely unconnected from the rest. Note that there was already a comment on the ForEachNode commit there.

  2. TheBlueMatt cross-referenced this on Jun 28, 2017 from issue Small step towards demangling cs_main from CNodeState by TheBlueMatt
  3. gmaxwell commented at 10:37 PM on June 28, 2017: contributor

    hm this may require carefully auditing every use to determine if the code in question isn't being protected by an assumed holding of cs_vnodes.

  4. TheBlueMatt commented at 10:48 PM on June 28, 2017: contributor

    Indeed. I believe it is the case that none of them are needed, but I may be incorrect. Note that folks may want to hold off on review, @cfields indicated he may have a more complete solution to the general mess that is our manual CNode refcounting.

  5. fanquake added the label P2P on Jun 29, 2017
  6. fanquake added the label Refactoring on Jun 29, 2017
  7. theuni commented at 2:51 AM on June 29, 2017: member

    No, please go ahead and review. I've worked on this several times now and haven't come up with anything that could be considered an improvement. I'm currently taking another look, but that shouldn't block this unless I manage to come up with something in the next day or so.

  8. theuni cross-referenced this on Jul 4, 2017 from issue net: drop custom CNode refcounting in favor of smart pointers by theuni
  9. promag commented at 8:27 AM on October 28, 2017: member

    Ping @theuni @TheBlueMatt, are you working on this?

  10. in src/net.cpp:2866 in e4f477b6b0 outdated
    2856 | @@ -2857,12 +2857,96 @@ bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
    2857 |      for (auto&& pnode : vNodes) {
    2858 |          if(pnode->GetId() == id) {
    2859 |              found = pnode;
    2860 | +            found->AddRef();
    2861 |              break;
    2862 |          }
    2863 |      }
    2864 | -    return found != nullptr && NodeFullyConnected(found) && func(found);
    2865 | +    bool res = found != nullptr && NodeFullyConnected(found) && func(found);
    


    sipa commented at 9:26 AM on October 28, 2017:

    This still calls func while cs_vNodes is held. Is that intentional?

  11. in src/net.cpp:2883 in e4f477b6b0 outdated
    2877 | +            node->AddRef();
    2878 | +            vNodes_copy.push_back(node);
    2879 | +        }
    2880 | +    }
    2881 | +    for (CNode* node : vNodes_copy) {
    2882 | +        if (NodeFullyConnected(node))
    


    sipa commented at 9:27 AM on October 28, 2017:

    Nit: either { } around if body, or body on the same line (in multiple places).

  12. TheBlueMatt force-pushed on Oct 31, 2017
  13. TheBlueMatt commented at 3:51 PM on October 31, 2017: contributor

    Addressed @sipa's comments.

  14. TheBlueMatt force-pushed on Oct 31, 2017
  15. Dont let ForEachNode hold cs_vNodes while making callbacks cd6d27c944
  16. Improve LeaveCritical strictness 50ef0b0fbd
  17. TheBlueMatt force-pushed on Oct 31, 2017
  18. TheBlueMatt cross-referenced this on Nov 2, 2017 from issue Connect to a new outbound peer if our tip is stale by sdaftuar
  19. in src/net.cpp:2852 in cd6d27c944 outdated
    2853 |          }
    2854 |      }
    2855 | -    return found != nullptr && NodeFullyConnected(found) && func(found);
    2856 | +    bool res = false;
    2857 | +    if (found != nullptr) {
    2858 | +        res = NodeFullyConnected(found) && func(found);
    


    ryanofsky commented at 4:13 PM on November 3, 2017:

    This will leak reference count if func throws. Suggest using RAII helper to prevent this, see NodeRef in eeb85c63cf880bc7344413b266c3af793d5cb8d2. NodeRef also simplifies the ForEachNode implementations there.

  20. in src/net.cpp:2860 in cd6d27c944 outdated
    2861 | +    return res;
    2862 |  }
    2863 |  
    2864 | +void CConnman::ForEachNode(std::function<void (CNode* pnode)> func)
    2865 | +{
    2866 | +    std::vector<CNode*> vNodes_copy;
    


    ryanofsky commented at 4:14 PM on November 3, 2017:

    These should just call ForEachNodeThen with a null post functions so this code doesn't have to be repeated so many times. Again see eeb85c63cf880bc7344413b266c3af793d5cb8d2.

  21. in src/sync.h:188 in 50ef0b0fbd
     187 | -        (cs).unlock();             \
     188 | -        LeaveCritical();           \
     189 | +#define LEAVE_CRITICAL_SECTION(cs)   \
     190 | +    {                                \
     191 | +        (cs).unlock();               \
     192 | +        LeaveCritical((void*)(&cs)); \
    


    ryanofsky commented at 4:18 PM on November 3, 2017:

    This should just say LeaveCritical(&(cs)). cs should be parenthesized since it's a macro argument, and the cast is unneeded.

  22. ryanofsky commented at 4:23 PM on November 3, 2017: contributor

    utACK 50ef0b0fbd9e066286a33c44b879746a79be8e34

  23. TheBlueMatt cross-referenced this on Nov 4, 2017 from issue [net] Remove ForNode/ForEachNode by TheBlueMatt
  24. TheBlueMatt commented at 12:31 AM on November 4, 2017: contributor

    Superceded by #11604

  25. TheBlueMatt closed this on Nov 4, 2017

  26. bitcoin locked this on Sep 8, 2021

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:55 UTC