Eugene
Eugene

Reputation: 143

C++ asio provide async execution of thread

I got a simple server app. When new client connecting, it handles request from client and send data back to it. My problem is to provide a async execution of handle thread. Now, when began a handle thread it stops acceptor loop and wait for return of corresponding function. The question is how to organize the continuation of acceptor loop (to be able to simultaneously handle other connection) after starting a handle thread?

Server.h:

class Server
{
private:
    //Storage
    boost::asio::io_service service;
    boost::asio::ip::tcp::acceptor* acceptor; 
    boost::mutex mtx;

    //Methods
    void acceptorLoop();
    void HandleRequest(boost::asio::ip::tcp::socket* clientSock);

public:
    Server();
};

Server.cpp

void Server::acceptorLoop()
{
    std::cout << "Waiting for clients..." << std::endl;

    while (TRUE)
    {
        boost::asio::ip::tcp::socket clientSock (service);
        acceptor->accept(clientSock); //new socket accepted
        std::cout << "New client joined! ";
        boost::thread request_thread (&Server::HandleRequest, this, &clientSock); //create a thread
        request_thread.join(); //here I start thread, but I want to continue acceptor loop and not wait until function return.
    }
}

void Server::HandleRequest(boost::asio::ip::tcp::socket* clientSock)
{
    if (clientSock->available())
    {
        //Works with socket
    }
}

Server::Server()
{
    acceptor = new boost::asio::ip::tcp::acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8001));
    acceptorLoop(); //loop started
}

Upvotes: 1

Views: 577

Answers (2)

Evgeniy
Evgeniy

Reputation: 2511

You have two main problems here:

  1. Thread joining - you are waiting for thread finish before accept new connection
  2. Using pointer to a socket created on a stack

I recommend you this changes:

    boost::asio::ip::tcp::socket clientSock (service);
    acceptor->accept(clientSock); //new socket accepted
    std::cout << "New client joined! ";
    std::thread{std::bind(&Server::HandleRequest, this, std::placeholders::_1), std::move(clientSock)}.detach();

And HandleRequest will change to this:

void Server::HandleRequest(boost::asio::ip::tcp::socket&& clientSock)
{
    if (clientSock.available())
    {
        //Works with socket
    }
}

You can also store thread somewhere and join it later instead of detaching.

Upvotes: 1

yeoman
yeoman

Reputation: 1681

So why do you call join? Join is about waiting for a thread to finish, and you say you don't want to wait for the thread, so, well... just don't call join?

Upvotes: 1

Related Questions