This is the most simplistic version I can make to recreate this problem. It is a wxwidgets (wxdialog/wxsmith) application but I can run it from the command line so it starts the gui and gives me cout in the console.
This code is a wxDialog and creates a 2nd thread "std::thread m_threadWebListener" but when you go to close the form it will not close.
Code: Select all
class http_connection : public std::enable_shared_from_this<http_connection>
{
public:
http_connection(tcp::socket socket)
: socket_(std::move(socket))
{
}
// Initiate the asynchronous operations associated with the connection.
void start(bool bExitListener)
{
if (bExitListener)
{
cout << "shutting down 1" << endl;
boost::beast::error_code ec;
socket_.shutdown(tcp::socket::shutdown_send, ec);
}
}
private:
// The socket for the currently connected client.
tcp::socket socket_;
// The buffer for performing reads.
boost::beast::flat_buffer buffer_{8192};
// The request message.
http::request<http::dynamic_body> request_;
// The response message.
http::response<http::dynamic_body> response_;
// The timer for putting a deadline on connection processing.
boost::asio::basic_waitable_timer<std::chrono::steady_clock> deadline_{
socket_.get_executor().context(), std::chrono::seconds(60)};
};
// "Loop" forever accepting new connections.
void http_server(tcp::acceptor& acceptor, tcp::socket& socket, Beast_1_69Dialog &self)
{
cout << "http_server - " << self.m_bExitWebServer << endl;
if (self.m_bExitWebServer)
{
boost::beast::error_code ec2;
socket.shutdown(tcp::socket::shutdown_send, ec2);
return;
}
else
{
acceptor.async_accept(socket,
[&](boost::beast::error_code ec)
{
if(!ec)
{
std::make_shared<http_connection>(std::move(socket))->start(self.m_bExitWebServer);
http_server(acceptor, socket, self);
}
});
}
}
void CreateWebListener(Beast_1_69Dialog *self)
{
string sIpAddress = IP_ADDRESS;
int iPort = PORT_NUMBER;
try
{
auto const address = boost::asio::ip::make_address(sIpAddress);
unsigned short port = static_cast<unsigned short>(iPort);
boost::asio::io_context ioc{1};
tcp::acceptor acceptor{ioc, {address, port}};
tcp::socket socket{ioc};
http_server(acceptor, socket, *self);
ioc.run();
}
catch(std::exception const& e)
{
std::cerr << "Error: " << e.what() << std::endl;
}
}
void Beast_1_69Dialog::OnInit(wxInitDialogEvent& event)
{
m_threadWebListener = std::thread(CreateWebListener, this);
}
void Beast_1_69Dialog::OnClose(wxCloseEvent& event)
{
m_bExitWebServer = true;
if (m_threadWebListener.joinable())
{
CNetworkGet oGet;
oGet.SetParams(IP_ADDRESS, PORT_NUMBER, "/time");
oGet.Execute();
cout << "joinable" << endl;
m_threadWebListener.join();
}
else
{
cout << "not joinable" << endl;
}
// wxWindow::Close(); // doesnt work
//wxTheApp->ExitMainLoop(); // doesnt work
this->Destroy(); // works but causes core dump "double free or corruption (out)" "Aborted (core dumped)"
}
Code: Select all
http_server - 0
( CLICKED CLOSE FORM )
shutting down 1
http_server - 1
joinable
( CLICKED CLOSE FORM AGAIN) // form didnt close
not joinable
// form still didnt close
Calling this->Destroy(); works but causes core dump
"double free or corruption (out)"
"Aborted (core dumped)"
What is keepping this form from closing?