Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit db59354

Browse files
authored
Avoid deadlock while creating platform views with multiple engines. (#28224)
1 parent e3d19b3 commit db59354

File tree

6 files changed

+51
-14
lines changed

6 files changed

+51
-14
lines changed

fml/raster_thread_merger.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ RasterThreadMerger::RasterThreadMerger(
2323
fml::TaskQueueId gpu_queue_id)
2424
: platform_queue_id_(platform_queue_id),
2525
gpu_queue_id_(gpu_queue_id),
26-
shared_merger_(shared_merger),
27-
enabled_(true) {}
26+
shared_merger_(shared_merger) {}
2827

2928
void RasterThreadMerger::SetMergeUnmergeCallback(const fml::closure& callback) {
3029
merge_unmerge_callback_ = callback;
@@ -119,12 +118,12 @@ bool RasterThreadMerger::IsMerged() {
119118

120119
void RasterThreadMerger::Enable() {
121120
std::scoped_lock lock(mutex_);
122-
enabled_ = true;
121+
shared_merger_->SetEnabledUnSafe(true);
123122
}
124123

125124
void RasterThreadMerger::Disable() {
126125
std::scoped_lock lock(mutex_);
127-
enabled_ = false;
126+
shared_merger_->SetEnabledUnSafe(false);
128127
}
129128

130129
bool RasterThreadMerger::IsEnabled() {
@@ -133,7 +132,7 @@ bool RasterThreadMerger::IsEnabled() {
133132
}
134133

135134
bool RasterThreadMerger::IsEnabledUnSafe() const {
136-
return enabled_;
135+
return shared_merger_->IsEnabledUnSafe();
137136
}
138137

139138
bool RasterThreadMerger::IsMergedUnSafe() const {

fml/raster_thread_merger.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ class RasterThreadMerger
127127
std::condition_variable merged_condition_;
128128
std::mutex mutex_;
129129
fml::closure merge_unmerge_callback_;
130-
bool enabled_;
131130

132131
bool IsMergedUnSafe() const;
133132

fml/raster_thread_merger_unittests.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,27 @@ TEST(RasterThreadMerger, IsEnabled) {
361361
ASSERT_TRUE(raster_thread_merger->IsEnabled());
362362
}
363363

364+
TEST(RasterThreadMerger, TwoMergersWithSameThreadPairShareEnabledState) {
365+
TaskQueueWrapper queue1;
366+
TaskQueueWrapper queue2;
367+
fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
368+
fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
369+
const auto merger1 =
370+
RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
371+
const auto merger2 =
372+
RasterThreadMerger::CreateOrShareThreadMerger(merger1, qid1, qid2);
373+
ASSERT_TRUE(merger1->IsEnabled());
374+
ASSERT_TRUE(merger2->IsEnabled());
375+
376+
merger1->Disable();
377+
ASSERT_FALSE(merger1->IsEnabled());
378+
ASSERT_FALSE(merger2->IsEnabled());
379+
380+
merger2->Enable();
381+
ASSERT_TRUE(merger1->IsEnabled());
382+
ASSERT_TRUE(merger2->IsEnabled());
383+
}
384+
364385
TEST(RasterThreadMerger, RunExpiredTasksWhileFirstTaskMergesThreads) {
365386
fml::MessageLoop* loop_platform = nullptr;
366387
fml::AutoResetWaitableEvent latch1;

fml/shared_thread_merger.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ SharedThreadMerger::SharedThreadMerger(fml::TaskQueueId owner,
1414
fml::TaskQueueId subsumed)
1515
: owner_(owner),
1616
subsumed_(subsumed),
17-
task_queues_(fml::MessageLoopTaskQueues::GetInstance()) {}
17+
task_queues_(fml::MessageLoopTaskQueues::GetInstance()),
18+
enabled_(true) {}
1819

1920
bool SharedThreadMerger::MergeWithLease(RasterThreadMergerId caller,
2021
size_t lease_term) {
@@ -85,6 +86,14 @@ bool SharedThreadMerger::IsMergedUnSafe() const {
8586
return !IsAllLeaseTermsZeroUnSafe();
8687
}
8788

89+
bool SharedThreadMerger::IsEnabledUnSafe() const {
90+
return enabled_;
91+
}
92+
93+
void SharedThreadMerger::SetEnabledUnSafe(bool enabled) {
94+
enabled_ = enabled;
95+
}
96+
8897
bool SharedThreadMerger::IsAllLeaseTermsZeroUnSafe() const {
8998
return std::all_of(lease_term_by_caller_.begin(), lease_term_by_caller_.end(),
9099
[&](const auto& item) { return item.second == 0; });

fml/shared_thread_merger.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ class SharedThreadMerger
4242
// See the doc of |RasterThreadMerger::IsMergedUnSafe|.
4343
bool IsMergedUnSafe() const;
4444

45+
// It's called by |RasterThreadMerger::IsEnabledUnSafe|.
46+
// See the doc of |RasterThreadMerger::IsEnabledUnSafe|.
47+
bool IsEnabledUnSafe() const;
48+
49+
// It's called by |RasterThreadMerger::Enable| or
50+
// |RasterThreadMerger::Disable|.
51+
void SetEnabledUnSafe(bool enabled);
52+
4553
// It's called by |RasterThreadMerger::DecrementLease|.
4654
// See the doc of |RasterThreadMerger::DecrementLease|.
4755
bool DecrementLease(RasterThreadMergerId caller);
@@ -51,6 +59,7 @@ class SharedThreadMerger
5159
fml::TaskQueueId subsumed_;
5260
fml::RefPtr<fml::MessageLoopTaskQueues> task_queues_;
5361
std::mutex mutex_;
62+
bool enabled_;
5463

5564
/// The |MergeWithLease| or |ExtendLeaseTo| method will record the caller
5665
/// into this lease_term_by_caller_ map, |UnMergeNowIfLastOne|

shell/common/shell.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -709,17 +709,17 @@ void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
709709
//
710710
// This prevents false positives such as this method starts assuming that the
711711
// raster and platform queues have a given thread configuration, but then the
712-
// configuration is changed by a task, and the asumption is not longer true.
712+
// configuration is changed by a task, and the assumption is no longer true.
713713
//
714-
// This incorrect assumption can lead to dead lock.
714+
// This incorrect assumption can lead to deadlock.
715715
// See `should_post_raster_task` for more.
716716
rasterizer_->DisableThreadMergerIfNeeded();
717717

718718
// The normal flow executed by this method is that the platform thread is
719719
// starting the sequence and waiting on the latch. Later the UI thread posts
720720
// raster_task to the raster thread which signals the latch. If the raster and
721721
// the platform threads are the same this results in a deadlock as the
722-
// raster_task will never be posted to the plaform/raster thread that is
722+
// raster_task will never be posted to the platform/raster thread that is
723723
// blocked on a latch. To avoid the described deadlock, if the raster and the
724724
// platform threads are the same, should_post_raster_task will be false, and
725725
// then instead of posting a task to the raster thread, the ui thread just
@@ -818,18 +818,18 @@ void Shell::OnPlatformViewDestroyed() {
818818
//
819819
// This prevents false positives such as this method starts assuming that the
820820
// raster and platform queues have a given thread configuration, but then the
821-
// configuration is changed by a task, and the asumption is not longer true.
821+
// configuration is changed by a task, and the assumption is no longer true.
822822
//
823-
// This incorrect assumption can lead to dead lock.
823+
// This incorrect assumption can lead to deadlock.
824824
// See `should_post_raster_task` for more.
825825
rasterizer_->DisableThreadMergerIfNeeded();
826826

827827
// The normal flow executed by this method is that the platform thread is
828828
// starting the sequence and waiting on the latch. Later the UI thread posts
829829
// raster_task to the raster thread triggers signaling the latch(on the IO
830830
// thread). If the raster and the platform threads are the same this results
831-
// in a deadlock as the raster_task will never be posted to the plaform/raster
832-
// thread that is blocked on a latch. To avoid the described deadlock, if the
831+
// in a deadlock as the raster_task will never be posted to platform/raster
832+
// thread that is blocked on a latch. To avoid the described deadlock, if the
833833
// raster and the platform threads are the same, should_post_raster_task will
834834
// be false, and then instead of posting a task to the raster thread, the ui
835835
// thread just signals the latch and the platform/raster thread follows with

0 commit comments

Comments
 (0)