C++ Actor Framework 1.0.0
|
Actors are always allocated with a control block that stores its identity as well as strong and weak reference counts to it. More...
#include <actor_control_block.hpp>
Public Types | |
using | data_destructor = void (*)(abstract_actor*) |
using | block_destructor = void (*)(actor_control_block*) |
Public Member Functions | |
actor_control_block (actor_id x, node_id &y, actor_system *sys, data_destructor ddtor, block_destructor bdtor) | |
actor_control_block (const actor_control_block &)=delete | |
actor_control_block & | operator= (const actor_control_block &)=delete |
abstract_actor * | get () |
Returns a pointer to the actual actor instance. | |
Static Public Member Functions | |
static actor_control_block * | from (const abstract_actor *ptr) |
Returns a pointer to the control block that stores identity and reference counts for this actor. | |
Public Attributes | |
std::atomic< size_t > | strong_refs |
std::atomic< size_t > | weak_refs |
const actor_id | aid |
const node_id | nid |
actor_system *const | home_system |
const data_destructor | data_dtor |
const block_destructor | block_dtor |
Related Symbols | |
(Note that these are not member symbols.) | |
using | strong_actor_ptr = intrusive_ptr<actor_control_block> |
using | weak_actor_ptr = weak_intrusive_ptr<actor_control_block> |
CAF_CORE_EXPORT bool | intrusive_ptr_upgrade_weak (actor_control_block *x) |
void | intrusive_ptr_add_weak_ref (actor_control_block *x) |
CAF_CORE_EXPORT void | intrusive_ptr_release_weak (actor_control_block *x) |
void | intrusive_ptr_add_ref (actor_control_block *x) |
CAF_CORE_EXPORT void | intrusive_ptr_release (actor_control_block *x) |
Actors are always allocated with a control block that stores its identity as well as strong and weak reference counts to it.
Unlike "common" weak pointer designs, the goal is not to allocate the data separately. Instead, the only goal is to break cycles. For example, linking two actors automatically creates a cycle when using strong reference counts only.
When allocating a new actor, CAF will always embed the user-defined actor in an actor_storage
with the control block prefixing the actual actor type, as shown below.
+----------------------------------------+ | actor_storage<T> | +----------------------------------------+ | +-----------------+------------------+ | | | control block | actor data (T) | | | +-----------------+------------------+ | | | ref count | mailbox | | | | weak ref count | . | | | | actor ID | . | | | | node ID | . | | | +-----------------+------------------+ | +----------------------------------------+
Actors start with a strong reference count of 1. This count is transferred to the first actor
or typed_actor
handle used to store the actor. Actors will also start with a weak reference count of 1. This count is decremenated once the strong reference count drops to 0.
The data block is destructed by calling the destructor of T
when the last strong reference expires. The storage itself is destroyed when the last weak reference expires.