Using boost :: asio I use async_accept to receive connections. This works well, but there is one problem, and I need to suggest how to deal with it. Using regular async_accept:
Listener::Listener(int port) : acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), port)) , socket(io) { start_accept(); } void Listener::start_accept() { Request *r = new Request(io); acceptor.async_accept(r->socket(), boost::bind(&Listener::handle_accept, this, r, placeholders::error)); }
It works fine, but there is a problem: the Request object is created using the usual new one , so that it can "leak" memory. Not quite a leak, it only occurs when the program stops, but I want to make valgrind happy.
Of course, there is an option: I can replace it with shared_ptr and pass it to each event handler. This will work until the program stops, when asio io_service stops, all objects will be destroyed, and the request will be free. But in this way, I should always have an active asio event for Request , otherwise it will be destroyed! I think its a direct path to failure, so I also don't like this option.
UPD Third option: Listener contains a shared_ptr list for active connections. It looks great, and I prefer to use it unless a better way is found. The disadvantage is this: since this scheme allows you to do garbage collection on connection downtimes, it is unsafe: deleting a pointer to a connection with Listener will immediately destroy it, which can lead to segfault when any of the connection handlers is active in another thread. Using mutex can not fix this cus in this case we should block almost everything.
Is there a way to make the acceptor work with connection management in a beautiful and safe way? I will be glad to hear any suggestions.