bugfix: Make CCheckQueue RAII-styled (attempt 2)#26762
bugfix: Make CCheckQueue RAII-styled (attempt 2)#26762achow101 merged 6 commits intobitcoin:masterfrom
CCheckQueue RAII-styled (attempt 2)#26762Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
| void StopWorkerThreads() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) | ||
| ~CCheckQueue() | ||
| { | ||
| WITH_LOCK(m_mutex, m_request_stop = true); |
There was a problem hiding this comment.
clang turns off thread safety analysis in constructors and destructors, so I think if locking is needed it would be better to keep a separate (private?) function, that the destructor calls when necessary to maximise compile time checking.
| // CScheduler/checkqueue, scheduler and load block thread. | ||
| if (node.scheduler) node.scheduler->stop(); | ||
| if (node.chainman && node.chainman->m_load_block.joinable()) node.chainman->m_load_block.join(); | ||
| StopScriptCheckWorkerThreads(); |
There was a problem hiding this comment.
I don't think this change makes anything worse, but Shutdown() is pretty fragile.
|
|
||
| //! Create a new check queue | ||
| explicit CCheckQueue(unsigned int nBatchSizeIn) | ||
| : nBatchSize(nBatchSizeIn) |
There was a problem hiding this comment.
FWIW, I would probably have broken this up into multiple commits:
- refactor/behaviour change: move the global
scriptcheckqueueinto a class (and move its params out of init.cpp) - possible behaviour change: move all the
StopWorkerThreads()calls to wherever the queue goes out of scope (~ChainStateManager?) - refactor: add a constructor that accepts
worker_threads_numand just callsStartWorkerThreads() - refactor: replace all the calls to
StartWorkerThreadswith the new constructor - refactor: call
StopWorkerThreads()from the destructor only
There was a problem hiding this comment.
Thanks! Broken into a few commits in way to assure each commit passes tests.
src/validation.cpp
Outdated
| ChainstateManager& chainman, | ||
| std::optional<uint256> from_snapshot_blockhash) | ||
| : m_mempool(mempool), | ||
| m_script_check_queue{std::make_unique<CCheckQueue<CScriptCheck>>(/*batch_size=*/128, chainman.m_options.worker_threads_num)}, |
There was a problem hiding this comment.
This seems to be doubling the number of script check workers if the assumeutxo snapshot chainstate is allocated; shouldn't m_script_check_queue be part of ChainstateManager instead, so it remains a single global queue?
| } | ||
|
|
||
| CCheckQueue(const CCheckQueue&) = delete; | ||
| CCheckQueue& operator=(const CCheckQueue&) = delete; |
There was a problem hiding this comment.
Should apply rule-of-5 and default the move operations, no?
(EDIT: also, move the explanation of why these are deleted from the commit message into the file itself?)
|
Updated 2d248d6 -> 5a19c39 (pr26762.01 -> pr26762.02, diff):
|
|
Rebased 5a19c39 -> f020924 (pr26762.02 -> pr26762.03) due to the conflict with #26251. |
|
utACK f020924 Seems reasonable to me. Not 100% confident over delaying stopping the threads until the destructor; but also about equally unsure about how it works now... |
src/validation.cpp
Outdated
| : m_script_check_queue{/*nBatchSizeIn=*/128}, | ||
| m_options{Flatten(std::move(options))} | ||
| { | ||
| m_script_check_queue.StartWorkerThreads(m_options.worker_threads_num); |
There was a problem hiding this comment.
Previously this was conditional on worker_threads_num > 0 (since StartScriptCheckWorkerThreads would not be called unless script_threads >= 1). I think this is okay, since in that case the function only sets some variables that will never be used and skips over a loop.
There was a problem hiding this comment.
This code will gone in the "refactor: Make CCheckQueue constructor start worker threads" commit.
|
Updated f020924 -> 5a7932f (pr26762.03 -> pr26762.04, diff):
Actually, it is how the #25448 has been fixed now. |
Yikes. Work on adding reACK 5a7932f |
src/node/chainstatemanager_args.cpp
Outdated
|
|
||
| if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value}; | ||
|
|
||
| int par_value = args.GetIntArg("-par", DEFAULT_SCRIPTCHECK_THREADS); |
There was a problem hiding this comment.
This is not consistent with how the other options are handled. This overrides the value of the passed in option even if no argument was passed in. I would handle this the same way as max_tip_age and also move the MAX_SCRIPTCHECK_THREADS to chainstatemanager_opts.h.
There was a problem hiding this comment.
This is not consistent with how the other options are handled. This overrides the value of the passed in option even if no argument was passed in. I would handle this the same way as
max_tip_age...
I'm not sure about this change considering this PR scope. The semantic of the "-par" and "-maxtipage" options are quite different.
... and also move the
MAX_SCRIPTCHECK_THREADStochainstatemanager_opts.h.
Thanks! Updated.
Well, it fires too many false warnings for our code base (for example, for |
|
Rebased 2235765 -> 5b3ea5f (pr26762.14 -> pr26762.15) due to the conflict with #27596. |
|
|
||
| #include <common/system.h> | ||
| #include <interfaces/node.h> | ||
| #include <node/chainstatemanager_args.h> |
|
ACK 5b3ea5f |
|
ACK 5b3ea5f |
| BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) | ||
| { | ||
| auto queue = std::make_unique<Standard_Queue>(QUEUE_BATCH_SIZE); | ||
| auto queue = std::make_unique<Standard_Queue>(QUEUE_BATCH_SIZE, SCRIPT_CHECK_THREADS); |
There was a problem hiding this comment.
This is a change in behavior for the test in 9cf89f7?
| #include <node/chainstatemanager_args.h> | ||
| #include <txdb.h> // for -dbcache defaults | ||
| #include <util/string.h> | ||
| #include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS |
This PR:
CCheckQueueRAII-styledscriptcheckqueueThe previous attempt was in #18731.