Re: Design Questions on Termination



On Dec 28, 9:45 am, Scott Gifford <sgiff...@xxxxxxxxxxxxxxxx> wrote:

Here's a possible solution for sockets. Instead of calling close() on
the file descriptor, Tm calls shutdown(). That leaves the file
descriptor around so the same fd number won't be assigned to a
different connection, but it will be in a state where select() will
find it readable, read will return 0, and write will fail. The child
should notice one of those conditions, and can then exit its select
loop and close the socket safely.

That's a common pattern and it definitely works, but I don't think it
will solve the race condition. If you call 'shutdown' without
synchronizing with the other thread, what happens in the following
case:

1) You are about to call 'shutdown', you have made that decision.

2) The thread returns from 'select' because the connection you were
going to shutdown just happened to close normally from the other side.

3) That thread goes through its set and finds the connection shut down
normally.

4) It calls 'close'.

5) Something happens that results in a new connection being made or
accepted, it gets the same file descriptor as the thread closed in
step 4.

6) We go back to the 'shutdown' thread, and it shuts down the new
connection made in step 5.

Oops.

So you have to synchronize with the thread that can call 'close' to
call 'shutdown' anyway. So how much does 'shutdown' help you? It will
get you out of 'select', but how do you know when it is safe to call
it?

DS
.