I am making a HTTP server and I want to pass a socket client class to thread to handle the request. The problem is that the destructor gets called right after starting the thread so the socket gets closed. The simplified version of code looks like this.
while (true) {
TcpSocket client = m_socket.accept();
std::thread clientThread([this, &client] { this->handleClient(client); });
clientThread.detach();
}
I tried making a function that accepts a connection and passes it to a thread with a given function but I can't get it to work. I am using a tuple here because you can't pass a parameter pack to lambda in c++17.
template<typename Function, typename ...Args>
std::thread TcpListener::acceptAndPassToThread(Function&& function, Args&&... args)
{
int socketDescriptor = accept(m_socketDescriptor, nullptr, nullptr);
std::tuple arguments = std::make_tuple(std::forward<Args>(args)...);
std::thread clientThread([socketDescriptor, function, arguments] {
TcpSocket client = TcpSocket(socketDescriptor);
auto callArguments = std::tuple_cat(std::make_tuple(client), arguments);
std::apply(function, callArguments);
});
return clientThread;
}
I could do something like this but I would prefer not to use socket descriptors outside the class.
while (true)
{
int clientDescriptor = m_socket.acceptDescriptor();
std::thread clientThread([this, clientDescriptor] {
TcpSocket client = TcpSocket::fromDescriptor(clientDescriptor);
this->handleClient(client);
});
clientThread.detach();
}
Also what would be the proper way to call the TcpListener::acceptAndPassToThread function with a class member function.