websocketpp icon indicating copy to clipboard operation
websocketpp copied to clipboard

Cannot shutdown cleanly

Open ArosPrince opened this issue 7 years ago • 5 comments

Hello, I know this kind of questions get asked quite often, but I just don't see, what I am doing wrong...

I have the server running in a separate thread so that the run() method does not block the main thread.

I know that if I stop_listening() and close all the opened connections, the run() method should simply exit.

But it doesn't. I can't really tell where it gets stuck because for some reason, I don't see the stack frames for this thread in VS.

So, I create my server simply like this:

m_server.listen(port);
m_server.start_accept();
serverThread = std::thread([this]() {
	m_server.run();
});	

And in the server desctructor I have the following:

std::unique_lock<std::mutex> lock(m);
m_server.stop_perpetual();  // just in case
m_server.stop_listening();
for (auto it : m_connections) {
	m_server.close(it, websocketpp::close::status::going_away, "shutting down...");
}	
serverThread.join(); // it hangs here

Note that it has probably nothing to do with the connections. It happens even if there is no connection ever made during the server lifespan.

ArosPrince avatar Jan 02 '19 11:01 ArosPrince

I have the same problem but with the client class, 1/10 times the remote server closes the connection and I call stop on the client after the connection is closed it still fails to join the thread containing the run method and it's really getting on my nerve

lax1dude avatar Sep 18 '21 23:09 lax1dude

This is my code, currentWebsocketPPThread is a thread spawned from the client's run method

if (currentWebsocketClient && !currentWebsocketClient->stopped()) {
	try {
		if (currentWebsocketClient->get_con_from_hdl(currentWebsocketConnection)->get_state() != websocketpp::session::state::value::closed){
			currentWebsocketClient->get_con_from_hdl(currentWebsocketConnection)->close(websocketpp::close::status::going_away, string("disconnected"));
		}
		while (currentWebsocketClient->get_con_from_hdl(currentWebsocketConnection)->get_state() != websocketpp::session::state::value::closed) {
			this_thread::sleep_for(20ms);
		}
	}catch (exception& ee) {
		// go figure
	}

	if (currentWebsocketPPThread != nullptr) {
		currentWebsocketClient->stop();
		currentWebsocketClient = nullptr;
		if (currentWebsocketPPThread->joinable()) currentWebsocketPPThread->join();
		delete currentWebsocketPPThread;
		currentWebsocketPPThread = nullptr;
	}
}

lax1dude avatar Sep 18 '21 23:09 lax1dude

Is it solved?

guoh27 avatar Jan 20 '22 08:01 guoh27

Sorry, I have no idea. It's been so long. I had even troubles figuring out which project I used it for.

Anyway, I located the project in the end and this is the current destructor I have. It even contains a comment (unlike the version in the OP):

	std::unique_lock<std::mutex> lock(m);
	m_server.stop_perpetual();
	m_server.stop_listening();
	for (auto it : m_connections) {
		m_server.close(it, websocketpp::close::status::going_away, "shutting down...");
	}

	m_server.stop();
	serverThread.join(); //TODO it hangs here if the above line is not called

Apparently I tried to add m_server.stop(); call before calling join().

So maybe it is solved, sorry, I don't have the HW to test it with anymore, but maybe it will help someone.

ArosPrince avatar Jan 20 '22 12:01 ArosPrince