forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shared_thread_merger.cc
103 lines (88 loc) · 3.31 KB
/
shared_thread_merger.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define FML_USED_ON_EMBEDDER
#include "flutter/fml/shared_thread_merger.h"
#include <algorithm>
#include <set>
namespace fml {
SharedThreadMerger::SharedThreadMerger(fml::TaskQueueId owner,
fml::TaskQueueId subsumed)
: owner_(owner),
subsumed_(subsumed),
task_queues_(fml::MessageLoopTaskQueues::GetInstance()),
enabled_(true) {}
bool SharedThreadMerger::MergeWithLease(RasterThreadMergerId caller,
size_t lease_term) {
FML_DCHECK(lease_term > 0) << "lease_term should be positive.";
std::scoped_lock lock(mutex_);
if (IsMergedUnSafe()) {
return true;
}
bool success = task_queues_->Merge(owner_, subsumed_);
FML_CHECK(success) << "Unable to merge the raster and platform threads.";
// Save the lease term
lease_term_by_caller_[caller] = lease_term;
return success;
}
bool SharedThreadMerger::UnMergeNowUnSafe() {
FML_CHECK(IsAllLeaseTermsZeroUnSafe())
<< "all lease term records must be zero before calling "
"UnMergeNowUnSafe()";
bool success = task_queues_->Unmerge(owner_, subsumed_);
FML_CHECK(success) << "Unable to un-merge the raster and platform threads.";
return success;
}
bool SharedThreadMerger::UnMergeNowIfLastOne(RasterThreadMergerId caller) {
std::scoped_lock lock(mutex_);
lease_term_by_caller_.erase(caller);
if (lease_term_by_caller_.empty() || IsAllLeaseTermsZeroUnSafe()) {
return UnMergeNowUnSafe();
}
return true;
}
bool SharedThreadMerger::DecrementLease(RasterThreadMergerId caller) {
std::scoped_lock lock(mutex_);
auto entry = lease_term_by_caller_.find(caller);
bool exist = entry != lease_term_by_caller_.end();
if (exist) {
std::atomic_size_t& lease_term_ref = entry->second;
FML_CHECK(lease_term_ref > 0)
<< "lease_term should always be positive when merged, lease_term="
<< lease_term_ref;
lease_term_ref--;
} else {
FML_LOG(WARNING) << "The caller does not exist when calling "
"DecrementLease(), ignored. This may happens after "
"caller is erased in UnMergeNowIfLastOne(). caller="
<< caller;
}
if (IsAllLeaseTermsZeroUnSafe()) {
// Unmerge now because lease_term_ decreased to zero.
UnMergeNowUnSafe();
return true;
}
return false;
}
void SharedThreadMerger::ExtendLeaseTo(RasterThreadMergerId caller,
size_t lease_term) {
FML_DCHECK(lease_term > 0) << "lease_term should be positive.";
std::scoped_lock lock(mutex_);
FML_DCHECK(IsMergedUnSafe())
<< "should be merged state when calling this method";
lease_term_by_caller_[caller] = lease_term;
}
bool SharedThreadMerger::IsMergedUnSafe() const {
return !IsAllLeaseTermsZeroUnSafe();
}
bool SharedThreadMerger::IsEnabledUnSafe() const {
return enabled_;
}
void SharedThreadMerger::SetEnabledUnSafe(bool enabled) {
enabled_ = enabled;
}
bool SharedThreadMerger::IsAllLeaseTermsZeroUnSafe() const {
return std::all_of(lease_term_by_caller_.begin(), lease_term_by_caller_.end(),
[&](const auto& item) { return item.second == 0; });
}
} // namespace fml