| 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 |