Commit 7deb370f authored by Dominik Charousset's avatar Dominik Charousset

Add a meta objects guard to the actor system

parent 4e70994d
......@@ -85,20 +85,6 @@ std::string get_rtti_from_mpi() {
namespace caf {
/// An opaque type for shared object lifetime management of the global meta
/// objects table.
using global_meta_objects_guard_type = intrusive_ptr<ref_counted>;
// Note: for technical reasons (dependencies), `global_meta_objects_guard` is
// implemented in src/detail/meta_object.cpp.
/// Returns a shared ownership wrapper for global state to manage meta objects.
/// Any thread that accesses the actor system should participate in the lifetime
/// management of the global state by using a meta objects guard.
/// @warning The guard does *not* extend the lifetime of the actor system.
/// @relates actor_system
CAF_CORE_EXPORT global_meta_objects_guard_type global_meta_objects_guard();
/// Actor environment including scheduler, registry, and optional components
/// such as a middleman.
class CAF_CORE_EXPORT actor_system {
......@@ -569,7 +555,11 @@ public:
f();
thread_terminates();
};
return std::thread{std::move(body), global_meta_objects_guard()};
return std::thread{std::move(body), meta_objects_guard_};
}
auto meta_objects_guard() const noexcept {
return meta_objects_guard_;
}
const auto& metrics_actors_includes() const noexcept {
......@@ -751,6 +741,9 @@ private:
/// Manages threads for detached actors.
detail::private_thread_pool private_threads_;
/// Ties the lifetime of the meta objects table to the actor system.
detail::global_meta_objects_guard_type meta_objects_guard_;
};
} // namespace caf
......@@ -240,9 +240,18 @@ struct IUnknown;
// Convenience macros.
#define CAF_IGNORE_UNUSED(x) static_cast<void>(x)
/// Prints `error` to `stderr` and aborts program execution.
#define CAF_CRITICAL(error) \
do { \
fprintf(stderr, "[FATAL] %s:%u: critical error: '%s'\n", __FILE__, \
fprintf(stderr, "[FATAL] critical error (%s:%d): %s\n", __FILE__, \
__LINE__, error); \
::abort(); \
} while (false)
/// Prints `error` to `stderr` and aborts program execution.
#define CAF_CRITICAL_FMT(fmt_str, ...) \
do { \
fprintf(stderr, "[FATAL] critical error (%s:%d): " fmt_str "\n", __FILE__, \
__LINE__, __VA_ARGS__); \
::abort(); \
} while (false)
......@@ -51,6 +51,15 @@ struct meta_object {
void (*stringify)(std::string&, const void*);
};
/// An opaque type for shared object lifetime management of the global meta
/// objects table.
using global_meta_objects_guard_type = intrusive_ptr<ref_counted>;
/// Returns a shared ownership wrapper for global state to manage meta objects.
/// Any thread that accesses the actor system should participate in the lifetime
/// management of the global state by using a meta objects guard.
CAF_CORE_EXPORT global_meta_objects_guard_type global_meta_objects_guard();
/// Returns the global storage for all meta objects. The ::type_id of an object
/// is the index for accessing the corresonding meta object.
CAF_CORE_EXPORT span<const meta_object> global_meta_objects();
......
......@@ -361,6 +361,8 @@ CAF_CORE_EXPORT void intrusive_ptr_release(const dynamic_message_data*);
CAF_CORE_EXPORT dynamic_message_data*
intrusive_cow_ptr_unshare(dynamic_message_data*&);
using global_meta_objects_guard_type = intrusive_ptr<ref_counted>;
} // namespace detail
// -- weak pointer aliases -----------------------------------------------------
......
......@@ -277,6 +277,9 @@ actor_system::actor_system(actor_system_config& cfg)
tracing_context_(cfg.tracing_context),
private_threads_(this) {
CAF_SET_LOGGER_SYS(this);
meta_objects_guard_ = detail::global_meta_objects_guard();
if (!meta_objects_guard_)
CAF_CRITICAL("unable to obtain the global meta objects guard");
for (auto& hook : cfg.thread_hooks_)
hook->init(*this);
// Cache some configuration parameters for faster lookups at runtime.
......
......@@ -21,13 +21,7 @@
#include "caf/serializer.hpp"
#include "caf/span.hpp"
namespace caf {
#define fatal(str) \
do { \
fprintf(stderr, "FATAL: " str "\n"); \
abort(); \
} while (false)
namespace caf::detail {
namespace {
......@@ -53,10 +47,6 @@ global_meta_objects_guard_type global_meta_objects_guard() {
return cleanup_helper;
}
} // namespace caf
namespace caf::detail {
span<const meta_object> global_meta_objects() {
return {meta_objects, meta_objects_size};
}
......@@ -79,8 +69,8 @@ void clear_global_meta_objects() {
span<meta_object> resize_global_meta_objects(size_t size) {
if (size <= meta_objects_size)
fatal("resize_global_meta_objects called with a new size that does not "
"grow the array");
CAF_CRITICAL("resize_global_meta_objects called with a new size that does "
"not grow the array");
auto new_storage = new meta_object[size];
std::copy(meta_objects, meta_objects + meta_objects_size, new_storage);
delete[] meta_objects;
......@@ -93,7 +83,7 @@ void set_global_meta_objects(type_id_t first_id, span<const meta_object> xs) {
auto new_size = first_id + xs.size();
if (first_id < meta_objects_size) {
if (new_size > meta_objects_size)
fatal("set_global_meta_objects called with "
CAF_CRITICAL("set_global_meta_objects called with "
"'first_id < meta_objects_size' and "
"'new_size > meta_objects_size'");
auto out = meta_objects + first_id;
......@@ -108,12 +98,10 @@ void set_global_meta_objects(type_id_t first_id, span<const meta_object> xs) {
// Get null-terminated strings.
auto name1 = to_string(out->type_name);
auto name2 = to_string(x.type_name);
fprintf(stderr,
"FATAL: type ID %d already assigned to %s (tried to override "
"with %s)\n",
CAF_CRITICAL_FMT("type ID %d already assigned to %s "
"(tried to override with %s)",
static_cast<int>(std::distance(meta_objects, out)),
name1.c_str(), name2.c_str());
abort();
}
++out;
}
......
......@@ -20,6 +20,7 @@
#include "caf/config.hpp"
#include "caf/defaults.hpp"
#include "caf/detail/get_process_id.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/detail/pretty_type_name.hpp"
#include "caf/detail/set_thread_name.hpp"
#include "caf/intrusive/task_result.hpp"
......@@ -651,7 +652,7 @@ void logger::start() {
this->run();
this->system_.thread_terminates();
};
thread_ = std::thread{f, global_meta_objects_guard()};
thread_ = std::thread{f, detail::global_meta_objects_guard()};
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment