Multi Threaded Application Wont Exit Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 111
Joined: Wed Oct 28, 2015 9:48 pm

Multi Threaded Application Wont Exit

Post by Everydaydiesel » Mon Feb 11, 2019 3:55 pm

I have spent way too much time on this so I am reaching out for help to guys that are much smarter.

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?

Manolo
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 698
Joined: Mon Apr 30, 2012 11:07 pm

Re: Multi Threaded Application Wont Exit

Post by Manolo » Mon Feb 11, 2019 4:47 pm

I don't see you call event.Skip() at Beast_1_69Dialog::OnClose(...), supposed Beast_1_69Dialog derives from wxDialog.

Let wx does its job instead of closing/destroying the window on your own.

Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 111
Joined: Wed Oct 28, 2015 9:48 pm

Re: Multi Threaded Application Wont Exit

Post by Everydaydiesel » Mon Feb 11, 2019 5:50 pm

thank you soooo much
closing the socket, joining the thread and calling event.skip() works!

thanks again

Post Reply