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
Can't get richer than this
Can't get richer than this
Posts: 702
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