I am trying to understand different scenarios of cyclic references while using ioContext and shared_ptr and i stumbled into this.
In the code below class Test has a member variable shared_ptr<io_context>. When i make a the lambda inside of function ioContext post inside of async_wait i pass shared_from_this() {which is Test} in it. Imagine now ioContext is running in a different thread so the lambda gets added to internal ioContext queue. According to my understanding the lambda goes inside of ioContext internal queue and now there is a cyclic reference Test –> ioContext –> lambda –> Test.
Is my understanding correct here ? Is there any way to avoid this ?
https://coliru.stacked-crooked.com/a/586afa794d15ef8f
#include <boost/asio.hpp>
#include <boost/date_time.hpp>
#include <iostream>
std::string getTime()
{
return std::string("[").append(to_iso_extended_string(boost::posix_time::microsec_clock::universal_time())).append("] ");
}
class Test : public std::enable_shared_from_this<Test> {
public:
Test(const std::shared_ptr<boost::asio::io_context>& ioContext)
: ioContext_(ioContext), timer_(*ioContext) {}
void start() {
std::cout << getTime() << "at startn";
timer_.expires_after(std::chrono::seconds(3));
timer_.async_wait([this, self=shared_from_this()](const boost::system::error_code& ec)
{
std::cout << getTime() << "Inside wait!n";
if (!ec)
{
ioContext_->post([this, self=shared_from_this()]()
{
printInPost();
});
}
});
}
void printInPost() {
std::cout << getTime() << "I get printed!n";
}
private:
std::shared_ptr<boost::asio::io_context> ioContext_;
boost::asio::steady_timer timer_;
};
int main() {
std::shared_ptr<boost::asio::io_context> ioContext = std::make_shared<boost::asio::io_context>();
std::shared_ptr<Test> myTest = std::make_shared<Test>(ioContext);
myTest->start();
ioContext->run();
}