feat: BREAKING force all zig actors to declare a destructor
Actors may be destroyed without ever calling their receivers. This is regular behavior when an actor is killed by an exit message. C++ actors cleanup automatically via their destructors. Up to now zig actor had to enable trapping and cleanup on the exit message. This was a big foot gun and cumbersome. Now all zig actors are required to pass a deinit function to thespian.receive. This simplifies clean up and prevents the foot gun entirely.
This commit is contained in:
parent
b16a47efae
commit
5a729b6d06
3 changed files with 34 additions and 19 deletions
|
|
@ -7,11 +7,19 @@ using std::string_view;
|
|||
|
||||
extern "C" {
|
||||
|
||||
void thespian_receive(thespian_receiver r, thespian_behaviour_state s) {
|
||||
thespian::receive([r, s](auto from, cbor::buffer msg) -> thespian::result {
|
||||
void thespian_receive(thespian_receiver r, thespian_behaviour_state s,
|
||||
thespian_receiver_dtor dtor) {
|
||||
struct receiver_wrapper {
|
||||
thespian_receiver r;
|
||||
thespian_behaviour_state s;
|
||||
thespian_receiver_dtor dtor;
|
||||
~receiver_wrapper() { dtor(s); }
|
||||
};
|
||||
auto wrapper = std::make_shared<receiver_wrapper>(r, s, dtor);
|
||||
thespian::receive([wrapper](auto from, cbor::buffer msg) -> thespian::result {
|
||||
thespian_handle from_handle = reinterpret_cast<thespian_handle>( // NOLINT
|
||||
&from);
|
||||
auto *ret = r(s, from_handle, {msg.data(), msg.size()});
|
||||
auto *ret = wrapper->r(wrapper->s, from_handle, {msg.data(), msg.size()});
|
||||
if (ret) {
|
||||
auto err = cbor::buffer();
|
||||
const uint8_t *data = ret->base;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue