Reputation: 1791
The thing is, I have detached threads created on my server which works in a thread-per-client way, so the function which accepts a client, creates another listener function (as a thread, and detaches it) waiting for another client to join.
Like the following in pseudo code:
Listen to client...
Accept Client Connection...
If client connection is Valid then
Create and detach a thread of the exact same function.
Else
Keep on listening...
I detach the threads only because afterwards, the thread who created a certain thread is handling a client, if that client leaves all clients that logged in after that client would be forced to log out (because there's a chain of threads):
//-> means creating a thread
Listening thread... Handling Client 1 -> Listening... Handling 2 -> Listening... Handling 3
and so on. So when client 1's thread will terminate, all of the others would do so.
That is why I cannot give up on detach (unless I'd create the threads in the main()
, obviously, but that's not the architecture of the program).
Now, the problem occurs when someone exits without informing a thing, so the thread won't peacefully end. The only time I notice the fact that a client is not online is when recv()
or send()
are returning a negative value. When I notice that, I have to terminate the thread.
I tried doing so by using std::terminate()
but I get an error window saying r6010 - abort() has been called.
How do I terminate that thread without all of the server crashing?
Would I be forced to change the architecture ?
Upvotes: 2
Views: 2464
Reputation: 283793
The way to end a thread is to return from its thread procedure.
If you want the ending decision to be made from deep inside processing code, then throw an exception that is caught by the thread procedure. This has several huge benefits over pthread_exit
:
Stack unwinding occurs, so dynamic allocations used by your processing code won't be leaked (if properly held in smart pointers), as well as any other cleanup performed in destructors (flushing file buffers, etc).
In the future if you want to add retry logic or anything like that, you can catch the exception. Conversely a call to pthread_exit
is like a call to std::terminate
or std::exit
-- the current context ends unconditionally (although a handler can be installed via set_terminate
, that handler cannot cancel the exit). Reusable code should never force an application-level exit.
Upvotes: 1
Reputation: 48635
I think you need to put test a variable in your client comms loop that signals a thread when to return:
class ClientComms
{
// set to true when you want the thread to stop
std::atomic_bool done;
public:
ClientComms(): done(false) {}
void operator()()
{
while(!done)
{
// communicate with client
}
}
};
Upvotes: 0