#define FML_USED_ON_EMBEDDER
#include "base/include/fml/shared_thread_merger.h"
#include <algorithm>
#include <set>
#include "base/include/fml/macros.h"
namespace lynx {
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) {
std::scoped_lock lock(mutex_);
if (IsMergedUnSafe()) {
return true;
}
bool success = task_queues_->Merge(owner_, subsumed_);
LYNX_BASE_CHECK(success);
lease_term_by_caller_[caller] = lease_term;
return success;
}
bool SharedThreadMerger::UnMergeNowUnSafe() {
LYNX_BASE_CHECK(IsAllLeaseTermsZeroUnSafe());
bool success = task_queues_->Unmerge(owner_, subsumed_);
LYNX_BASE_CHECK(success);
return success;
}
bool SharedThreadMerger::UnMergeNowIfLastOne(RasterThreadMergerId caller) {
std::scoped_lock lock(mutex_);
lease_term_by_caller_.erase(caller);
if (!lease_term_by_caller_.empty()) {
return true;
}
return UnMergeNowUnSafe();
}
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;
LYNX_BASE_CHECK(lease_term_ref > 0);
lease_term_ref--;
} else {
}
if (IsAllLeaseTermsZeroUnSafe()) {
UnMergeNowUnSafe();
return true;
}
return false;
}
void SharedThreadMerger::ExtendLeaseTo(RasterThreadMergerId caller,
size_t lease_term) {
std::scoped_lock lock(mutex_);
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; });
}
}
}