MOHAMED
MOHAMED

Reputation: 43558

what's the risk of closing socket which is used in another thread by accept?

I have a server application.

The server is accpting the connection from clients in a thread with:

 while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
     .....
 }

I have another thread which executed in the exit of my application. in this thread I close the socket socket_desc:

close(socket_desc);

what is the risk of closing a socket in a thread and there is another thread wich make accept on the same socket?

Upvotes: 0

Views: 1085

Answers (3)

kiranpradeep
kiranpradeep

Reputation: 11221

I could be wrong. But, it might be for a scenario like this:- Consider 3 threads - A, B, C.

  1. Thread A waits on socket and goes to sleep
  2. Thread B closes the socket
  3. Thread C creates a new socket and which happens to get the same file descriptor number as the recently closed socket ( Socket is also a file )
  4. Thread A wakes up ( with error code on accept ) and then call close thinking unexpected error => This affects a completely different valid socket created in C !!

Upvotes: 2

harper
harper

Reputation: 13690

You can close the socket to abort the accept function. But you must change the code, and check the return value of API functions carefully. Your attempt while the while loop will not work, since it doesn't check for SOCK_ERROR (-1).

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 181159

To the best of my knowledge, the semantics of the combination of actions you describe are not defined, and that should be enough of a concern to find an alternative. I speculate that behaviors reasonably likely to be observed include

  • the close() returning quickly, and
    • the accept() call failing quickly, perhaps indicating an EBADF, EINVAL, or ENOTSOCK error, or
    • the accept() call continuing to block until a connection request arrives, or
    • the accept() call blocking indefinitely; or
  • the close() blocking until accept() returns, if it ever does; or
  • close() and accept() deadlocking.

If indeed the semantics are not defined, however, then pretty much anything could happen.

If a different thread must close the socket than the one accept()ing connections on it, then you would be wise to set some sort of flag to indicate that the program is exiting, then signal() the accept()ing thread to break it out of accept(). The thread(s) receiving such a signal would know from the program-exiting flag to stop instead of trying to accept() again.

If your threads are cancelable, then the global flag could take the form of a thread-cancellation message. The accept() function is a cancellation point, so your threads will receive the cancellation message no later than the next time they call accept().

Upvotes: 1

Related Questions