EDIT: I never figured this out - I refactored the code to be pretty much identical to a Boost sample, and still had the problem. If anyone else has this problem, yours may be the more common shared_from_this() being called when no shared_ptr exists (or in the constructor). Otherwise, I recommend just rebuilding from the boost asio samples.
I'm trying to do something that I think is pretty common, but I am having some issues.
I'm using boost asio, and trying to create a TCP server. I accept connections with async_accept, and I create shared pointers. I have a long lived object (like a connection manager), that inserts the shared_ptr into a set. Here is a snippet:
std::shared_ptr<WebsocketClient> ptr = std::make_shared<WebsocketClient>(std::move(s));
directory.addPending(ptr);
ptr->onConnect(std::bind(&Directory::addClient, &directory, std::placeholders::_1));
ptr->onDisconnect(std::bind(&Directory::removeClient, &directory, std::placeholders::_1));
ptr->onMessage(std::bind(&Directory::onMessage, &directory, std::placeholders::_1, std::placeholders::_2));
ptr->start();
The Directory has std::set<std::shared_ptr<WebsocketClient>> pendingClients;
The function for adding a client is:
void Directory::addPending(std::shared_ptr<WebsocketClient> ptr){
std::cout << "Added pending client: " << ptr->getName() << std::endl;
pendingClients.insert(ptr);
}
Now, when the WebsocketClient starts, it tries to create a shared_ptr using shared_from_this() and then initiates an async_read_until ("\r\n\r\n"), and passes that shared_ptr to the lambda to keep ownership. It crashes before actually invoking the asio function, on shared_from_this().
Call stack looks like this:
server.exe!WebsocketClient::start()
server.exe!Server::acceptConnection::__l2::<lambda>(boost::system::error_code ec)
server.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder1<void <lambda>(boost::system::error_code),boost::system::error_code> >(boost::asio::detail::binder1<void <lambda>(boost::system::error_code),boost::system::error_code> & function, ...)
server.exe!boost::asio::detail::win_iocp_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ip::tcp,void <lambda>(boost::system::error_code) ::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, const boost::system::error_code & result_ec, unsigned __int64 __formal) Line 142 C++
server.exe!boost::asio::detail::win_iocp_io_service::do_one(bool ec, boost::system::error_code &)
server.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec)
server.exe!Server::run()
server.exe!main(int argc, char * * argv)
However, I get a bad_weak_ptr when I call shared_from_this. I thought that was thrown when no shared_ptr owned this object, but when I call the addPending, I insert "ptr" into a set, so there should still be a reference to it.
Any ideas? If you need more details please ask, and I'll provide them. This is my first post on StackOverflow, so let me know what I can improve.