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
|
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE message_lifetime
#include "core-test.hpp"
#include <atomic>
#include <iostream>
#include "caf/all.hpp"
using namespace caf;
fail_on_copy::fail_on_copy(const fail_on_copy&) {
CAF_FAIL("fail_on_copy: copy constructor called");
}
fail_on_copy& fail_on_copy::operator=(const fail_on_copy&) {
CAF_FAIL("fail_on_copy: copy assign operator called");
}
namespace {
class testee : public event_based_actor {
public:
testee(actor_config& cfg) : event_based_actor(cfg) {
// nop
}
~testee() override {
// nop
}
behavior make_behavior() override {
// reflecting a message increases its reference count by one
set_default_handler(reflect_and_quit);
return {[] {
// nop
}};
}
};
class tester : public event_based_actor {
public:
tester(actor_config& cfg, actor aut)
: event_based_actor(cfg),
aut_(std::move(aut)),
msg_(make_message(1, 2, 3)) {
set_down_handler([=](down_msg& dm) {
CHECK_EQ(dm.reason, exit_reason::normal);
CHECK_EQ(dm.source, aut_.address());
quit();
});
}
behavior make_behavior() override {
monitor(aut_);
send(aut_, msg_);
return {[=](int a, int b, int c) {
CHECK_EQ(a, 1);
CHECK_EQ(b, 2);
CHECK_EQ(c, 3);
}};
}
private:
actor aut_;
message msg_;
};
} // namespace
BEGIN_FIXTURE_SCOPE(test_coordinator_fixture<>)
CAF_TEST(nocopy_in_scoped_actor) {
auto msg = make_message(fail_on_copy{1});
self->send(self, msg);
self->receive([&](const fail_on_copy& x) {
CHECK_EQ(x.value, 1);
CHECK_EQ(msg.cdata().get_reference_count(), 2u);
});
CHECK_EQ(msg.cdata().get_reference_count(), 1u);
}
CAF_TEST(message_lifetime_in_scoped_actor) {
auto msg = make_message(1, 2, 3);
self->send(self, msg);
self->receive([&](int a, int b, int c) {
CHECK_EQ(a, 1);
CHECK_EQ(b, 2);
CHECK_EQ(c, 3);
CHECK_EQ(msg.cdata().get_reference_count(), 2u);
});
CHECK_EQ(msg.cdata().get_reference_count(), 1u);
msg = make_message(42);
self->send(self, msg);
CHECK_EQ(msg.cdata().get_reference_count(), 2u);
self->receive([&](int& value) {
auto addr = static_cast<void*>(&value);
CHECK_NE(addr, msg.cdata().at(0));
value = 10;
});
CHECK_EQ(msg.get_as<int>(0), 42);
}
CAF_TEST(message_lifetime_in_spawned_actor) {
for (size_t i = 0; i < 100; ++i)
sys.spawn<tester>(sys.spawn<testee>());
}
END_FIXTURE_SCOPE()
|