aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdactor/td/actor/impl/ActorInfo-decl.h
blob: 870e26dffd8315f9b2eb03945e4f92d2dcb02244 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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/ActorId-decl.h"
#include "td/actor/impl/Event.h"

#include "td/utils/common.h"
#include "td/utils/Heap.h"
#include "td/utils/List.h"
#include "td/utils/ObjectPool.h"
#include "td/utils/Slice.h"
#include "td/utils/StringBuilder.h"

#include <atomic>
#include <memory>
#include <utility>

namespace td {

class Actor;

class ActorContext {
 public:
  ActorContext() = default;
  ActorContext(const ActorContext &) = delete;
  ActorContext &operator=(const ActorContext &) = delete;
  ActorContext(ActorContext &&) = delete;
  ActorContext &operator=(ActorContext &&) = delete;
  virtual ~ActorContext() = default;

  virtual int32 get_id() const {
    return 0;
  }

  void set_tag(string tag) {
    tag_storage_ = std::move(tag);
    tag_ = tag_storage_.c_str();
  }

  const char *tag_ = nullptr;
  string tag_storage_;  // sometimes tag_ == tag_storage_.c_str()
  std::weak_ptr<ActorContext> this_ptr_;
};

class ActorInfo final
    : private ListNode
    , private HeapNode {
 public:
  enum class Deleter : uint8 { Destroy, None };

  ActorInfo() = default;
  ~ActorInfo() = default;

  ActorInfo(ActorInfo &&) = delete;
  ActorInfo &operator=(ActorInfo &&) = delete;

  ActorInfo(const ActorInfo &) = delete;
  ActorInfo &operator=(const ActorInfo &) = delete;

  void init(int32 sched_id, Slice name, ObjectPool<ActorInfo>::OwnerPtr &&this_ptr, Actor *actor_ptr, Deleter deleter,
            bool need_context, bool need_start_up);
  void on_actor_moved(Actor *actor_new_ptr);

  template <class ActorT>
  ActorOwn<ActorT> transfer_ownership_to_scheduler(unique_ptr<ActorT> actor);
  void clear();
  void destroy_actor();

  bool empty() const;
  void start_migrate(int32 to_sched_id);
  bool is_migrating() const;
  int32 migrate_dest() const;
  std::pair<int32, bool> migrate_dest_flag_atomic() const;

  void finish_migrate();

  ActorId<> actor_id();
  template <class SelfT>
  ActorId<SelfT> actor_id(SelfT *self);
  Actor *get_actor_unsafe();
  const Actor *get_actor_unsafe() const;

  std::shared_ptr<ActorContext> set_context(std::shared_ptr<ActorContext> context);
  std::weak_ptr<ActorContext> get_context_weak_ptr() const;
  ActorContext *get_context();
  const ActorContext *get_context() const;
  CSlice get_name() const;

  HeapNode *get_heap_node();
  const HeapNode *get_heap_node() const;
  static ActorInfo *from_heap_node(HeapNode *node);

  ListNode *get_list_node();
  const ListNode *get_list_node() const;
  static ActorInfo *from_list_node(ListNode *node);

  void start_run();
  bool is_running() const;
  void finish_run();

  vector<Event> mailbox_;

  bool need_context() const;
  bool need_start_up() const;

  void set_wait_generation(uint32 wait_generation);
  bool must_wait(uint32 wait_generation) const;

 private:
  Deleter deleter_ = Deleter::None;
  bool need_context_ = true;
  bool need_start_up_ = true;
  bool is_running_ = false;
  uint32 wait_generation_{0};

  std::atomic<int32> sched_id_{0};
  Actor *actor_ = nullptr;

#ifdef TD_DEBUG
  string name_;
#endif
  std::shared_ptr<ActorContext> context_;
};

StringBuilder &operator<<(StringBuilder &sb, const ActorInfo &info);

}  // namespace td