wallet: fix UnloadWallet thread safety assumptions #30659

pull furszy wants to merge 4 commits into bitcoin:master from furszy:2024_wallet_shutdown changing 7 files +28 −30
  1. furszy commented at 7:16 pm on August 14, 2024: member

    Coming from #29073.

    Applied ryanofsky suggested changes on #29073 (comment) with few modifications coming from #18338 (comment).

    The only point I did not tackle from #18338 (comment) is:

    • Move log print and flush out of ReleaseWallet into CWallet destructor

    Because it would mean every CWallet object would flush data to disk during destruction. Which is not necessary for wallet tool utilities and unit tests.

  2. wallet: unload, notify GUI as soon as possible
    Releases wallet shared pointers prior to doing the
    final settings update and prevent GUI races trying
    to access a wallet that is no longer loaded.
    5d15485aaf
  3. wallet: rename UnloadWallet to WaitForDeleteWallet
    And update function's documentation.
    8872b4a6ca
  4. wallet: WaitForDeleteWallet, do not expect thread safety
    Multiple threads could try to delete the wallet at the same time.
    64e736d79e
  5. DrahtBot commented at 7:16 pm on August 14, 2024: contributor

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

    Code Coverage

    For detailed information about the code coverage, see the test coverage report.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK ryanofsky, ismaelsadeeq, achow101

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #30343 (wallet, logging: Replace WalletLogPrintf() with LogInfo() by ryanofsky)
    • #25722 (refactor: Use util::Result class for wallet loading 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.

  6. DrahtBot added the label Wallet on Aug 14, 2024
  7. achow101 added this to the milestone 28.0 on Aug 14, 2024
  8. in src/wallet/wallet.cpp:233 in 7a73b0b7d5 outdated
    226@@ -227,10 +227,10 @@ static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mu
    227 static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
    228 
    229 // Custom deleter for shared_ptr<CWallet>.
    230-static void ReleaseWallet(CWallet* wallet)
    231+static void FlushAndDelete(CWallet* wallet)
    232 {
    233     const std::string name = wallet->GetName();
    234-    wallet->WalletLogPrintf("Releasing wallet\n");
    235+    wallet->WalletLogPrintf("Releasing wallet %s..\n", name);
    


    ismaelsadeeq commented at 12:49 pm on August 15, 2024:
    nit: should this change be in its own commit? then you can use scripted diff for the rename.

    furszy commented at 2:35 pm on August 15, 2024:

    nit: should this change be in its own commit? then you can use scripted diff for the rename.

    Updated. Scripted both changes within the same commit.


    furszy commented at 2:57 pm on August 15, 2024:
    And.. reverted per #30659 (review).
  9. ismaelsadeeq commented at 1:00 pm on August 15, 2024: member
    Code review ACK 7a73b0b7d5e690235bcefca9b82f01442b37ad5e
  10. in src/wallet/wallet.cpp:230 in 7a73b0b7d5 outdated
    226@@ -227,10 +227,10 @@ static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mu
    227 static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
    228 
    229 // Custom deleter for shared_ptr<CWallet>.
    230-static void ReleaseWallet(CWallet* wallet)
    231+static void FlushAndDelete(CWallet* wallet)
    


    ryanofsky commented at 1:19 pm on August 15, 2024:

    In commit “wallet: rename ReleaseWallet to FlushAndDelete” (7a73b0b7d5e690235bcefca9b82f01442b37ad5e)

    Not important, but maybe this should be called FlushAndDeleteWallet to be consistent with WaitForDeleteWallet.


    furszy commented at 2:36 pm on August 15, 2024:
    Sure. Done.
  11. ryanofsky approved
  12. ryanofsky commented at 1:26 pm on August 15, 2024: contributor
    Code review ACK 7a73b0b7d5e690235bcefca9b82f01442b37ad5e. This is a much cleaner bugfix than I suggested in #29073. Moving the unload notification makes the shutdown sequence easier to understand, more efficient, and safe.
  13. furszy force-pushed on Aug 15, 2024
  14. Rename ReleaseWallet to FlushAndDeleteWallet
    To better describe the function's behavior.
    And add wallet name to logprint.
    f550a8e035
  15. in src/wallet/wallet.cpp:233 in e37e415ff9 outdated
    226@@ -227,10 +227,10 @@ static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mu
    227 static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
    228 
    229 // Custom deleter for shared_ptr<CWallet>.
    230-static void ReleaseWallet(CWallet* wallet)
    231+static void FlushAndDeleteWallet(CWallet* wallet)
    232 {
    233     const std::string name = wallet->GetName();
    234-    wallet->WalletLogPrintf("Releasing wallet\n");
    235+    wallet->WalletLogPrintf("Releasing wallet %s..\n", name);
    


    maflcko commented at 2:48 pm on August 15, 2024:
    Can you explain why a four-line diff requires a five-line scripted diff? Seems easier to just have a normal diff when the script is longer than the diff.

    furszy commented at 2:54 pm on August 15, 2024:
    I didn’t think much about it. Just made #30659 (review) happy while was tackling #30659 (review). Either way is fine for me.

    furszy commented at 2:57 pm on August 15, 2024:
    Done. Reverted.

    ryanofsky commented at 3:46 pm on August 15, 2024:

    re: #30659 (review)

    Can you explain why a four-line diff requires a five-line scripted diff? Seems easier to just have a normal diff when the script is longer than the diff.

    Agree that a manual change is fine here, but IMO unless a scripted diff is badly written or fragile (e.g. hardcoding line numbers), I’d always prefer it over a manual change because it:

    1. Documents and summarizes changes in a representation verified by CI.
    2. Helps with rebasing and cherrypicking. I often paste scripted diffs commands manually when I have a conflict to resolve, and have code which runs scripted-diffs automatically when cherrypicking.
    3. Helps verify changes are complete. For example in rename commits, can verify there are not code comments referring to the old name.
    4. Can prevent silent conflicts because of the checking done by CI.

    maflcko commented at 4:49 pm on August 15, 2024:

    IMO unless a scripted diff is badly written or fragile (e.g. hardcoding line numbers), I’d always prefer it over a manual change because it:

    I understand why scripted-diffs are useful. However, you forgot to mention the risks and downsides:

    • A script in the scripted-diff must be reviewed.
    • Otherwise, it can accidentally or intentionally modify files that are not tracked by git (Which has happened in the past).
    • Failing statements in the scripted-diff won’t cause the CI to fail, which is another way in which reviewers could be accidentally or intentionally tricked to think a script has executed when it did not, and they may miss a bug.
    • Seeing a scripted-diff could encourage reviewers to skip or skim over the actual diff, missing bugs.

    Also, the diff contained a statement, which looks like it shouldn’t be part of it, because it applies to one line of code. (sed -i 's/WalletLogPrintf("Releasing wallet\\n"/WalletLogPrintf("Releasing wallet %s..\\n", name/g' $(git grep -l '"Releasing wallet\\n"' ./src/wallet/wallet.cpp)). I don’t see any benefit in putting that into a scripted-diff, which is why I mentioned it (and also left my comment on this line).

    Obviously the rest of the script was fine, but personally just calling a single time git grep $old_value is faster than to type ./test/lint/commit-script-check.sh HEAD~$N..HEAD (or rely on the CI).

  16. furszy force-pushed on Aug 15, 2024
  17. ryanofsky approved
  18. ryanofsky commented at 3:54 pm on August 15, 2024: contributor
    Code review ACK f550a8e035b4603787273ea250f403f6f0be453f. Just a simple rename since last review
  19. DrahtBot requested review from ismaelsadeeq on Aug 15, 2024
  20. ismaelsadeeq approved
  21. ismaelsadeeq commented at 4:03 pm on August 15, 2024: member
    Re-ACK f550a8e035b4603787273ea250f403f6f0be453f
  22. achow101 commented at 5:12 pm on August 15, 2024: member
    ACK f550a8e035b4603787273ea250f403f6f0be453f
  23. achow101 merged this on Aug 15, 2024
  24. achow101 closed this on Aug 15, 2024

  25. furszy deleted the branch on Aug 16, 2024

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: 2024-12-21 15:12 UTC

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