103 lines
3.3 KiB
C++
103 lines
3.3 KiB
C++
// 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
|