MCPcopy Create free account
hub / github.com/COVESA/vsomeip / ExampleOwner

Class ExampleOwner

test/unit_tests/endpoint_tests/test_timer.cpp:33–72  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

31
32TEST_F(test_example_use_case, a_const_shared_ptr_of_timer_is_thread_safe) {
33 class ExampleOwner : public std::enable_shared_from_this<ExampleOwner> {
34 struct hidden { }; // private struct ensures that ::create is used for a proper setup
35 public:
36 static std::shared_ptr<ExampleOwner> create(boost::asio::io_context& _io) {
37 auto p = std::make_shared<ExampleOwner>(hidden{}, _io);
38 // 1. ensures that task is properly set before any actual usage of the timer.
39 // 2. capture this by weak_ref to avoid the need of manual destruction of the timer.
40 // Note: This step can not be done in the c'tor as the weak_from_this/shared_from_this call would return a nullptr at this
41 // point.
42 // Note: This two step setup is inevitable as the task of the timer and the owner of the timer form an ownership cycle (although
43 // only temporary due to the usage of weak_from_this).
44
45 // the return can be ignored in this very instance, because the timer had no chance to have been
46 // started before. The return is given, to highlight that adjusting the timers task at a later
47 // stage is a dangerous operation and has a chance to fail (because the timer class itself will
48 // protect against the change of the task while the timer is running).
49 [[maybe_unused]] bool set_was_success = p->timer_->set_task([weak_ref = p->weak_from_this()] {
50 if (auto self = weak_ref.lock(); self) {
51 self->counter_ += 1;
52 }
53 return true;
54 });
55 return p;
56 }
57
58 ExampleOwner([[maybe_unused]] hidden _, boost::asio::io_context& _io) :
59 // create a timer with a dummy task to ensure the shared_ptr is receiving its memory in the ctor and can therefore be
60 // used from any thread without further inspection
61 timer_(timer::create(_io, 12ms, [] { return false; })) { }
62
63 // Because the timer has a thread-safe interface, the shared_ptr to the timer is const, and the task is setup is ensured
64 // in a dedicated create function there is no need for synchronization primitives when using the timer itself.
65 void start() { timer_->start(); }
66 void stop() { timer_->stop(); }
67
68 std::atomic<uint32_t> counter_{0};
69
70 private:
71 std::shared_ptr<timer> const timer_;
72 };
73
74 auto owner = ExampleOwner::create(dummy_context_);
75 // start the timer

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected