2009d58f6a
GitOrigin-RevId: 15dc5e63afa4c0d08f911101eaa78513df6aebc5
160 lines
4.3 KiB
C++
160 lines
4.3 KiB
C++
//
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
|
|
//
|
|
// 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"
|
|
|
|
#include "td/utils/common.h"
|
|
#include "td/utils/ObjectPool.h"
|
|
#include "td/utils/Slice.h"
|
|
|
|
#include <memory>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
namespace td {
|
|
|
|
inline Actor::Actor(Actor &&other) {
|
|
CHECK(info_.empty());
|
|
info_ = std::move(other.info_);
|
|
if (!empty()) {
|
|
info_->on_actor_moved(this);
|
|
}
|
|
}
|
|
inline Actor &Actor::operator=(Actor &&other) {
|
|
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 {
|
|
return Scheduler::instance()->has_actor_timeout(this);
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
inline uint64 Actor::get_link_token() {
|
|
return Scheduler::instance()->get_link_token(this);
|
|
}
|
|
inline std::shared_ptr<ActorContext> Actor::set_context(std::shared_ptr<ActorContext> context) {
|
|
return info_->set_context(std::move(context));
|
|
}
|
|
inline string Actor::set_tag(string tag) {
|
|
auto *ctx = info_->get_context();
|
|
string old_tag;
|
|
if (ctx->tag_) {
|
|
old_tag = ctx->tag_;
|
|
}
|
|
ctx->set_tag(std::move(tag));
|
|
Scheduler::on_context_updated();
|
|
return old_tag;
|
|
}
|
|
|
|
inline void Actor::init(ObjectPool<ActorInfo>::OwnerPtr &&info) {
|
|
info_ = std::move(info);
|
|
}
|
|
inline ActorInfo *Actor::get_info() {
|
|
return &*info_;
|
|
}
|
|
inline const ActorInfo *Actor::get_info() const {
|
|
return &*info_;
|
|
}
|
|
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) {
|
|
CHECK(static_cast<Actor *>(self) == this);
|
|
return ActorId<SelfT>(info_.get_weak());
|
|
}
|
|
|
|
template <class SelfT>
|
|
ActorShared<SelfT> Actor::actor_shared(SelfT *self, uint64 id) {
|
|
CHECK(static_cast<Actor *>(self) == this);
|
|
// TODO replace with CHECK
|
|
LOG_IF(ERROR, id == 0) << "ActorShared with token 0 must not be created";
|
|
return ActorShared<SelfT>(actor_id(self), id);
|
|
}
|
|
|
|
template <class FuncT, class... ArgsT>
|
|
auto Actor::self_closure(FuncT &&func, ArgsT &&... args) {
|
|
return self_closure(this, std::forward<FuncT>(func), std::forward<ArgsT>(args)...);
|
|
}
|
|
|
|
template <class SelfT, class FuncT, class... ArgsT>
|
|
auto Actor::self_closure(SelfT *self, FuncT &&func, ArgsT &&... args) {
|
|
return EventCreator::closure(actor_id(self), std::forward<FuncT>(func), std::forward<ArgsT>(args)...);
|
|
}
|
|
|
|
template <class LambdaT>
|
|
auto Actor::self_lambda(LambdaT &&lambda) {
|
|
return EventCreator::lambda(actor_id(), std::forward<LambdaT>(lambda));
|
|
}
|
|
|
|
inline Slice Actor::get_name() const {
|
|
return info_->get_name();
|
|
}
|
|
|
|
inline void Actor::always_wait_for_mailbox() {
|
|
info_->always_wait_for_mailbox();
|
|
}
|
|
|
|
} // namespace td
|