-
Couldn't load subscription status.
- Fork 38.1k
bugfix: Make CCheckQueue RAII-styled (attempt 2)
#26762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach ACK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
| void StopWorkerThreads() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) | ||
| ~CCheckQueue() | ||
| { | ||
| WITH_LOCK(m_mutex, m_request_stop = true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Updated.
| // 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Updated.
| } | ||
|
|
||
| CCheckQueue(const CCheckQueue&) = delete; | ||
| CCheckQueue& operator=(const CCheckQueue&) = delete; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Done.
|
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 5b3ea5f
|
|
||
| #include <common/system.h> | ||
| #include <interfaces/node.h> | ||
| #include <node/chainstatemanager_args.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: fix include order.
|
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5b3ea5f: Comment is now wrong, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This PR:
CCheckQueueRAII-styledscriptcheckqueueThe previous attempt was in #18731.