1 thread is making an accept call in for(;;;) loop .On a certain condition closeSocket is called and it closes the same socket on which accept call is being made . The accept call gives error . I get EBDAF error on Solaris and EINVAL error on Linux . How should i overcome this problem . Can I check the socketnum state before making an accept call . How should I approach this problem .
-
In principle yes, but you should show some code in your question. BTW, what is giving the error code, the `close` or the `accept` ? – Basile Starynkevitch Jun 18 '15 at 16:53
-
1possible duplicate of [Is accept() thread-safe?](http://stackoverflow.com/questions/5124320/is-accept-thread-safe) – Klaus Jun 18 '15 at 16:56
-
What problem? One thread is bocked, waiting for clients to connect when you rip out the socket from underneath it. Of course it will error/except - what you see is expected behaviour. – Martin James Jun 18 '15 at 16:59
-
I need an understanding how can I overcome it to improve the performance of my process as system calls are costly – Vivek Jun 18 '15 at 17:11
-
1How to overcome this? Don't close the socket. – Andrew Henle Jun 18 '15 at 17:20
-
1You observed some behaviour, claimed it was problematic, and then said something about performance. I have _no_ idea why you think the behaviour is a problem for you, or what performance implications it could possibly have. Please clarify. – Useless Jun 18 '15 at 17:27
-
1No you can't check the socket return state *before* you make the `accept()` call. What you've observed is the correct and predicted behaviour. There is nothing here to solve and there is certainly jnothing that has any impact on performance. Your question doesn't make sense. – user207421 Jun 18 '15 at 18:22
2 Answers
You cannot close a socket in one thread while another thread is using it. The basic problem is that there is simply no way to know whether the other thread is using the socket or about to use the socket. And if it's about to use the socket, there are unavoidable race conditions. This mistake has caused real world problems, including one with serious security implications.
Instead, just don't close the socket. Signal the thread that might be using the socket any other way, and then have that thread close the socket.

- 179,497
- 17
- 214
- 278
accept will return with error because the socket (file descriptor) was closed. You can consider this error in your code.
An alternative technique for not getting error that is common in many applications (Thrift uses it): from a second thread you connect to this socket and send a special message, for example, just "1". When the server receives this message it finishes the loop and closes the socket.
Of course there is a risk of DoS attack if another machine begins to send "1" to your server. Then you need to check the message comes from the same machine and from a port used by your process. Or better, do what Martin James says below.

- 5,606
- 3
- 28
- 34
-
Use a 'stop' boolean that you check after every accept() return. Set the stop, do a connect on the local stack, job done. No DoS possibility by the route you suggest - the stop will not be set. – Martin James Jun 18 '15 at 19:10
-
-
@MartinJames You can't do that because you're not guaranteed to get an error. The call may succeed and do the wrong thing. There is simply no way to make this safe and a lot of paisn (and serious security flaws) have been suffered because people attempted this. – David Schwartz Jun 19 '15 at 03:40
-
@DavidShwartz, I think the best and most secure way way is the one I indicated with the modification as per MartinJames' first note. I'm used to do it in this way and I saw Thrift, as an example of a known library, does the same. – rodolk Jun 19 '15 at 10:29