//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
// 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/utils/common.h"
namespace td {
namespace actor2 {
class ActorSignals {
public:
ActorSignals() = default;
uint32 raw() const {
return raw_;
}
bool empty() const {
return raw_ == 0;
bool has_signal(uint32 signal) const {
return (raw_ & (1u << signal)) != 0;
void add_signal(uint32 signal) {
raw_ |= (1u << signal);
void add_signals(ActorSignals signals) {
raw_ |= signals.raw();
void clear_signal(uint32 signal) {
raw_ &= ~(1u << signal);
uint32 first_signal() {
if (!raw_) {
return 0;
#if TD_MSVC
int res = 0;
int bit = 1;
while ((raw_ & bit) == 0) {
res++;
bit <<= 1;
return res;
#else
return __builtin_ctz(raw_);
#endif
enum Signal : uint32 {
// Signals in order of priority
Wakeup = 1,
Alarm = 2,
Kill = 3, // immediate kill
Io = 4, // move to io thread
Cpu = 5, // move to cpu thread
StartUp = 6,
TearDown = 7,
// Two signals for mpmc queue logic
// PopSignal is set after actor is popped from queue
// When processed it should set InQueue and Pause flags to false.
// MessagesSignal is set after new messages was added to actor
// If owner of actor wish to delay message handling, she should set InQueue flag to true and
// add actor into mpmc queue.
Pop = 8, // got popped from queue
Message = 9, // got new message
};
static ActorSignals one(uint32 signal) {
ActorSignals res;
res.add_signal(signal);
private:
uint32 raw_{0};
friend class ActorState;
explicit ActorSignals(uint32 raw) : raw_(raw) {
} // namespace actor2
} // namespace td