mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Unmerge threads if the current merger is the only one that's merged. (flutter/engine#43652)
`UnMergeNowIfLastOne` is called during shell destruction. When there are other shells with threads unmerged and the current destroying shell with thread merged. `UnMergeNowIfLastOne` should unmerge the threads. This PR Make `UnMergeNowIfLastOne` not only unmerge if the current merger is the last merger, but also unmerge if the current merger is the last merger that is merged. Fixes https://github.com/flutter/flutter/issues/127168 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
6fdde7e901
commit
4e696fc84d
@ -53,10 +53,10 @@ class RasterThreadMerger
|
||||
TaskQueueId platform_id,
|
||||
TaskQueueId raster_id);
|
||||
|
||||
// Un-merges the threads now if current caller is the last merge caller,
|
||||
// and it resets the lease term to 0, otherwise it will remove the caller
|
||||
// record and return. The multiple caller records were recorded after
|
||||
// |MergeWithLease| or |ExtendLeaseTo| method.
|
||||
// Un-merges the threads now if current caller is the last merged caller,
|
||||
// and it resets the lease term to 0, otherwise it will remove
|
||||
// the caller record and return. The multiple caller records were recorded
|
||||
// after |MergeWithLease| or |ExtendLeaseTo| method.
|
||||
//
|
||||
// Must be executed on the raster task runner.
|
||||
//
|
||||
|
||||
@ -594,6 +594,42 @@ TEST(RasterThreadMerger, TheLastCallerOfMultipleMergersCanUnmergeNow) {
|
||||
ASSERT_FALSE(raster_thread_merger2->IsMerged());
|
||||
}
|
||||
|
||||
TEST(RasterThreadMerger, TheLastMergedCallerOfMultipleMergersCanUnmergeNow) {
|
||||
TaskQueueWrapper queue1;
|
||||
TaskQueueWrapper queue2;
|
||||
fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
|
||||
fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
|
||||
// Two mergers will share one same inner merger
|
||||
const auto raster_thread_merger1 =
|
||||
fml::RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
|
||||
|
||||
const size_t kNumFramesMerged = 1;
|
||||
ASSERT_FALSE(raster_thread_merger1->IsMerged());
|
||||
|
||||
// Merge using the mergers
|
||||
raster_thread_merger1->MergeWithLease(kNumFramesMerged);
|
||||
ASSERT_TRUE(raster_thread_merger1->IsMerged());
|
||||
|
||||
for (size_t i = 0; i < kNumFramesMerged; i++) {
|
||||
// Un-merge thread merger 1.
|
||||
raster_thread_merger1->DecrementLease();
|
||||
}
|
||||
ASSERT_FALSE(raster_thread_merger1->IsMerged());
|
||||
|
||||
const auto raster_thread_merger2 =
|
||||
fml::RasterThreadMerger::CreateOrShareThreadMerger(raster_thread_merger1,
|
||||
qid1, qid2);
|
||||
ASSERT_FALSE(raster_thread_merger2->IsMerged());
|
||||
raster_thread_merger2->MergeWithLease(kNumFramesMerged);
|
||||
ASSERT_TRUE(raster_thread_merger2->IsMerged());
|
||||
|
||||
// One caller state becomes no callers left.
|
||||
raster_thread_merger2->UnMergeNowIfLastOne();
|
||||
// Check if unmerged
|
||||
ASSERT_FALSE(raster_thread_merger1->IsMerged());
|
||||
ASSERT_FALSE(raster_thread_merger2->IsMerged());
|
||||
}
|
||||
|
||||
/// This case tests multiple standalone engines using independent merger to
|
||||
/// merge two different raster threads into the same platform thread.
|
||||
TEST(RasterThreadMerger,
|
||||
|
||||
@ -44,10 +44,10 @@ bool SharedThreadMerger::UnMergeNowUnSafe() {
|
||||
bool SharedThreadMerger::UnMergeNowIfLastOne(RasterThreadMergerId caller) {
|
||||
std::scoped_lock lock(mutex_);
|
||||
lease_term_by_caller_.erase(caller);
|
||||
if (!lease_term_by_caller_.empty()) {
|
||||
return true;
|
||||
if (lease_term_by_caller_.empty() || IsAllLeaseTermsZeroUnSafe()) {
|
||||
return UnMergeNowUnSafe();
|
||||
}
|
||||
return UnMergeNowUnSafe();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedThreadMerger::DecrementLease(RasterThreadMergerId caller) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user