* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <mc/exception.h>
#include <mc/futures/state.h>
namespace mc::futures {
state_base::state_base(executor_type executor, destory_type destory, int value_size) noexcept
: m_executor(std::move(executor)),
m_destory(std::move(destory)),
m_value_size(value_size) {
}
state_base::~state_base() {
}
void state_base::set_executor(executor_type executor) noexcept {
m_executor = std::move(executor);
}
void state_base::reset() {
m_ready.store(false);
m_bound.store(false);
m_cancelled.store(false);
m_policy = launch::async;
m_continuations.clear();
m_cancel_callbacks.clear();
m_executor = executor_type{};
m_exception = nullptr;
m_destory = nullptr;
}
void state_base::reuse_impl() {
}
void state_base::mark_ready() {
callback_list callbacks;
callback_list cancel_callbacks;
{
std::lock_guard<std::mutex> lock(m_mutex);
m_ready.store(true, std::memory_order_release);
m_continuations.swap(callbacks);
m_cancel_callbacks.swap(cancel_callbacks);
}
m_cv.notify_all();
callbacks.execute_and_clear();
cancel_callbacks.clear();
}
void state_base::cancel() {
if (m_ready.load()) {
return;
}
bool expected = false;
if (!m_cancelled.compare_exchange_strong(expected, true)) {
return;
}
callback_list callbacks;
{
std::lock_guard<std::mutex> lock(m_mutex);
m_cancel_callbacks.swap(callbacks);
}
callbacks.execute_and_clear();
bool need_ready = false;
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_ready.load()) {
set_exception(std::make_exception_ptr(mc::canceled_exception()));
need_ready = true;
m_ready.store(true, std::memory_order_release);
}
}
if (need_ready) {
this->mark_ready();
}
}
void state_base::add_cancel_callback(callback_type callback) {
if (!m_ready.load() && !m_cancelled.load()) {
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_ready.load() && !m_cancelled.load()) {
m_cancel_callbacks.push_back(std::move(callback));
return;
}
}
if (m_cancelled.load()) {
safe_invoke(std::move(callback));
}
}
void state_base::destory() {
if (m_destory) {
m_destory(this);
}
reset();
}
}