2018-12-31 20:04:05 +01:00
|
|
|
//
|
2024-01-01 01:07:21 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
|
2018-12-31 20:04:05 +01:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "td/actor/impl/Actor-decl.h"
|
|
|
|
#include "td/actor/impl/EventFull-decl.h"
|
|
|
|
#include "td/actor/impl/Scheduler-decl.h"
|
|
|
|
|
2019-02-12 22:26:36 +01:00
|
|
|
#include "td/utils/common.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
#include "td/utils/ObjectPool.h"
|
|
|
|
#include "td/utils/Slice.h"
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
namespace td {
|
2018-07-03 21:29:04 +02:00
|
|
|
|
2021-10-18 13:36:15 +02:00
|
|
|
inline Actor::Actor(Actor &&other) noexcept {
|
2018-12-31 20:04:05 +01:00
|
|
|
CHECK(info_.empty());
|
|
|
|
info_ = std::move(other.info_);
|
|
|
|
if (!empty()) {
|
|
|
|
info_->on_actor_moved(this);
|
|
|
|
}
|
|
|
|
}
|
2021-10-18 13:36:15 +02:00
|
|
|
inline Actor &Actor::operator=(Actor &&other) noexcept {
|
2018-12-31 20:04:05 +01:00
|
|
|
CHECK(info_.empty());
|
|
|
|
info_ = std::move(other.info_);
|
|
|
|
if (!empty()) {
|
|
|
|
info_->on_actor_moved(this);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void Actor::notify() {
|
|
|
|
yield();
|
|
|
|
}
|
|
|
|
|
|
|
|
// proxy to scheduler
|
|
|
|
inline void Actor::yield() {
|
|
|
|
Scheduler::instance()->yield_actor(this);
|
|
|
|
}
|
|
|
|
inline void Actor::stop() {
|
|
|
|
Scheduler::instance()->stop_actor(this);
|
|
|
|
}
|
|
|
|
inline void Actor::do_stop() {
|
|
|
|
Scheduler::instance()->do_stop_actor(this);
|
|
|
|
CHECK(empty());
|
|
|
|
}
|
|
|
|
inline bool Actor::has_timeout() const {
|
2021-10-18 18:26:14 +02:00
|
|
|
return get_info()->get_heap_node()->in_heap();
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2021-08-15 10:15:14 +02:00
|
|
|
inline double Actor::get_timeout() const {
|
|
|
|
return Scheduler::instance()->get_actor_timeout(this);
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
inline void Actor::set_timeout_in(double timeout_in) {
|
|
|
|
Scheduler::instance()->set_actor_timeout_in(this, timeout_in);
|
|
|
|
}
|
|
|
|
inline void Actor::set_timeout_at(double timeout_at) {
|
|
|
|
Scheduler::instance()->set_actor_timeout_at(this, timeout_at);
|
|
|
|
}
|
|
|
|
inline void Actor::cancel_timeout() {
|
|
|
|
Scheduler::instance()->cancel_actor_timeout(this);
|
|
|
|
}
|
|
|
|
inline void Actor::migrate(int32 sched_id) {
|
|
|
|
Scheduler::instance()->migrate_actor(this, sched_id);
|
|
|
|
}
|
|
|
|
inline void Actor::do_migrate(int32 sched_id) {
|
|
|
|
Scheduler::instance()->do_migrate_actor(this, sched_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ActorType>
|
|
|
|
std::enable_if_t<std::is_base_of<Actor, ActorType>::value> start_migrate(ActorType &obj, int32 sched_id) {
|
|
|
|
if (!obj.empty()) {
|
|
|
|
Scheduler::instance()->start_migrate_actor(&obj, sched_id);
|
|
|
|
}
|
|
|
|
}
|
2021-10-07 14:28:52 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ActorType>
|
|
|
|
std::enable_if_t<std::is_base_of<Actor, ActorType>::value> finish_migrate(ActorType &obj) {
|
|
|
|
if (!obj.empty()) {
|
|
|
|
Scheduler::instance()->finish_migrate_actor(&obj);
|
|
|
|
}
|
|
|
|
}
|
2021-10-07 14:28:52 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
inline uint64 Actor::get_link_token() {
|
|
|
|
return Scheduler::instance()->get_link_token(this);
|
|
|
|
}
|
2021-10-07 14:28:52 +02:00
|
|
|
|
|
|
|
inline std::weak_ptr<ActorContext> Actor::get_context_weak_ptr() const {
|
|
|
|
return info_->get_context_weak_ptr();
|
|
|
|
}
|
|
|
|
|
2019-04-23 10:56:32 +02:00
|
|
|
inline std::shared_ptr<ActorContext> Actor::set_context(std::shared_ptr<ActorContext> context) {
|
|
|
|
return info_->set_context(std::move(context));
|
|
|
|
}
|
2021-10-07 14:28:52 +02:00
|
|
|
|
2020-08-17 12:57:05 +02:00
|
|
|
inline string Actor::set_tag(string tag) {
|
|
|
|
auto *ctx = info_->get_context();
|
|
|
|
string old_tag;
|
|
|
|
if (ctx->tag_) {
|
|
|
|
old_tag = ctx->tag_;
|
2019-04-23 10:56:32 +02:00
|
|
|
}
|
2020-08-17 12:57:05 +02:00
|
|
|
ctx->set_tag(std::move(tag));
|
2018-12-31 20:04:05 +01:00
|
|
|
Scheduler::on_context_updated();
|
2019-04-23 10:56:32 +02:00
|
|
|
return old_tag;
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
2023-03-27 16:56:40 +02:00
|
|
|
inline void Actor::set_info(ObjectPool<ActorInfo>::OwnerPtr &&info) {
|
2018-12-31 20:04:05 +01:00
|
|
|
info_ = std::move(info);
|
|
|
|
}
|
2021-10-07 14:28:52 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
inline ActorInfo *Actor::get_info() {
|
|
|
|
return &*info_;
|
|
|
|
}
|
|
|
|
inline const ActorInfo *Actor::get_info() const {
|
|
|
|
return &*info_;
|
|
|
|
}
|
2021-10-07 14:28:52 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
inline ObjectPool<ActorInfo>::OwnerPtr Actor::clear() {
|
|
|
|
return std::move(info_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool Actor::empty() const {
|
|
|
|
return info_.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline ActorId<> Actor::actor_id() {
|
|
|
|
return actor_id(this);
|
|
|
|
}
|
|
|
|
template <class SelfT>
|
|
|
|
ActorId<SelfT> Actor::actor_id(SelfT *self) {
|
2019-02-12 22:26:36 +01:00
|
|
|
CHECK(static_cast<Actor *>(self) == this);
|
2018-12-31 20:04:05 +01:00
|
|
|
return ActorId<SelfT>(info_.get_weak());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class SelfT>
|
|
|
|
ActorShared<SelfT> Actor::actor_shared(SelfT *self, uint64 id) {
|
2019-02-12 22:26:36 +01:00
|
|
|
CHECK(static_cast<Actor *>(self) == this);
|
2020-09-24 18:15:42 +02:00
|
|
|
CHECK(id != 0);
|
2018-12-31 20:04:05 +01:00
|
|
|
return ActorShared<SelfT>(actor_id(self), id);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class FuncT, class... ArgsT>
|
2021-12-09 22:27:13 +01:00
|
|
|
auto Actor::self_closure(FuncT &&func, ArgsT &&...args) {
|
2018-12-31 20:04:05 +01:00
|
|
|
return self_closure(this, std::forward<FuncT>(func), std::forward<ArgsT>(args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class SelfT, class FuncT, class... ArgsT>
|
2021-12-09 22:27:13 +01:00
|
|
|
auto Actor::self_closure(SelfT *self, FuncT &&func, ArgsT &&...args) {
|
2018-12-31 20:04:05 +01:00
|
|
|
return EventCreator::closure(actor_id(self), std::forward<FuncT>(func), std::forward<ArgsT>(args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class LambdaT>
|
2024-01-20 10:54:17 +01:00
|
|
|
auto Actor::self_lambda(LambdaT &&func) {
|
|
|
|
return EventCreator::from_lambda(actor_id(), std::forward<LambdaT>(func));
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline Slice Actor::get_name() const {
|
|
|
|
return info_->get_name();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace td
|