2024-02-23 18:07:37 +08:00
|
|
|
/**
|
|
|
|
* @file : pending_task_safety_flag
|
|
|
|
* @created : Wednesday Feb 14, 2024 17:55:39 CST
|
|
|
|
* @license : MIT
|
|
|
|
**/
|
|
|
|
|
2024-03-01 14:50:55 +08:00
|
|
|
#ifndef SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H
|
|
|
|
#define SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H
|
2024-02-23 18:07:37 +08:00
|
|
|
|
2024-03-23 09:03:00 +08:00
|
|
|
#pragma once
|
2024-05-01 14:14:57 +08:00
|
|
|
#include "sled/meta/type_traits.h"
|
2024-02-23 18:07:37 +08:00
|
|
|
#include "sled/ref_counted_base.h"
|
|
|
|
#include "sled/scoped_refptr.h"
|
2024-03-23 09:03:00 +08:00
|
|
|
#include "sled/synchronization/sequence_checker.h"
|
2024-03-19 15:12:26 +08:00
|
|
|
#include <functional>
|
2024-02-23 18:07:37 +08:00
|
|
|
|
|
|
|
namespace sled {
|
|
|
|
|
2024-03-19 15:12:26 +08:00
|
|
|
class PendingTaskSafetyFlag final : public sled::RefCountedNonVirtual<PendingTaskSafetyFlag> {
|
2024-02-23 18:07:37 +08:00
|
|
|
public:
|
|
|
|
static sled::scoped_refptr<PendingTaskSafetyFlag> Create();
|
|
|
|
static sled::scoped_refptr<PendingTaskSafetyFlag> CreateDetached();
|
|
|
|
static sled::scoped_refptr<PendingTaskSafetyFlag> CreateDetachedInactive();
|
|
|
|
|
|
|
|
~PendingTaskSafetyFlag() = default;
|
|
|
|
void SetNotAlive();
|
|
|
|
void SetAlive();
|
|
|
|
bool alive() const;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
explicit PendingTaskSafetyFlag(bool alive) : alive_(alive) {}
|
|
|
|
|
|
|
|
private:
|
2024-03-19 15:12:26 +08:00
|
|
|
static sled::scoped_refptr<PendingTaskSafetyFlag> CreateInternal(bool alive);
|
2024-02-23 18:07:37 +08:00
|
|
|
bool alive_ = true;
|
2024-03-23 09:03:00 +08:00
|
|
|
SequenceChecker main_sequence_;
|
2024-02-23 18:07:37 +08:00
|
|
|
};
|
|
|
|
|
2024-03-19 15:12:26 +08:00
|
|
|
class ScopedTaskSafety final {
|
|
|
|
public:
|
|
|
|
ScopedTaskSafety() = default;
|
|
|
|
|
|
|
|
explicit ScopedTaskSafety(scoped_refptr<PendingTaskSafetyFlag> flag) : flag_(std::move(flag)) {}
|
|
|
|
|
|
|
|
~ScopedTaskSafety() { flag_->SetNotAlive(); }
|
|
|
|
|
|
|
|
void reset(scoped_refptr<PendingTaskSafetyFlag> new_flag = PendingTaskSafetyFlag::Create())
|
|
|
|
{
|
|
|
|
flag_->SetNotAlive();
|
|
|
|
flag_ = std::move(new_flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
scoped_refptr<PendingTaskSafetyFlag> flag_;
|
|
|
|
};
|
|
|
|
|
2024-05-01 14:14:57 +08:00
|
|
|
template<typename F, typename... Args, typename = EnableIfT<!std::is_void<InvokeResultT<F, Args...>>::value>>
|
|
|
|
std::function<InvokeResultT<F, Args...>(Args &&...)>
|
|
|
|
SafeTask(scoped_refptr<PendingTaskSafetyFlag> flag, F &&f)
|
|
|
|
{
|
|
|
|
return [flag, f](Args &&...args) mutable -> InvokeResultT<F, Args...> {
|
|
|
|
if (flag->alive()) { return f(std::forward<Args>(args)...); }
|
|
|
|
return {};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename F, typename... Args, typename = EnableIfT<std::is_void<InvokeResultT<F, Args...>>::value>>
|
|
|
|
std::function<void(Args &&...)>
|
|
|
|
SafeTask(scoped_refptr<PendingTaskSafetyFlag> flag, F &&f)
|
2024-03-19 15:12:26 +08:00
|
|
|
{
|
2024-05-01 14:14:57 +08:00
|
|
|
return [flag, f](Args &&...args) mutable -> void {
|
|
|
|
if (flag->alive()) { f(std::forward<Args>(args)...); }
|
2024-03-19 15:12:26 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-02-23 18:07:37 +08:00
|
|
|
}// namespace sled
|
|
|
|
|
2024-03-01 14:50:55 +08:00
|
|
|
#endif// SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H
|