Emil
Emil

Reputation: 381

Unblocking accept()

I have a blocking call to accept(). From another thread I close the socket, hoping that it'll unblock the accept() call, which it does but I have a case when it doesn't: e.g. thread A enters accept(), thread B closes the socket, thread A doesn't return from accept().

Question: what could cause closing a socket to not unblock an accept()?

Upvotes: 1

Views: 2156

Answers (3)

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84169

One hacky trick to unblock accept(2) is to actually connect(2) to the listening end from your other thread. Flip some flag indicating it's time to stop the loop, connect(2), close(2) the connecting socket. That way the accept(2)-ing thread would know to close the socket and shut itself down.

Upvotes: 2

David Schwartz
David Schwartz

Reputation: 182769

You must not ever free a resource in one thread while another thread is or might be using it. You will never get this to work reliably. For one thing, you can never be 100% sure the thread is actually blocked in accept, as opposed to about to block in it. So there will always be race conditions.

And, of course, shutdown won't work because the socket is not connected.

There are a couple of ways to handle this problem. For example, you can set a flag that the thread checks when it returns from accept and then make a connection yourself. That will cause the thread to return from accept and then it will see the flag and terminate.

You can also switch to non-blocking sockets. Have the thread call select or poll with a timeout and check if the thread should terminate when it returns from select or poll. You can also select or poll on both the socket and a pipe. Then just send a byte on the pipe to unblock the thread. pthread_kill is another possibility, as is pthread_cancel.

Not knowing the details of your problem, my guess would be the best solution is to rearchitect so you don't have a thread whose sole job is to wait forever in accept. That way, you won't even have a thread you need to kill. If you don't want to keep accepting connections, just rig things so that your threads stop doing that, but let the threads keep going doing other things. (The number of running threads you have should be dependent on the number of things you can usefully do at once, not the total number of things you have to do.)

Upvotes: 1

Arnold Spence
Arnold Spence

Reputation: 22272

Try calling shutdown() followed by close() from thread B. You should be checking the return codes on these calls too as they may help you figure out what is going wrong when thread A fails to become unblocked.

Upvotes: 0

Related Questions