RFC: Too many race conditions.

David Daney ddaney@avtrex.com
Mon May 21 15:01:00 GMT 2007


Andrew Haley wrote:
> Andrew Haley writes:
>  > David Daney writes:
>  > 
>  >  > In the thread using a descriptor, there is a window between when it can 
>  >  > test if the descriptor is closed and using the descriptor.  Part of the 
>  >  > window is in the syscall code in libc and also in the kernel before it 
>  >  > tests for a valid descriptor.
>  >  > 
>  >  > If during this window, a different thread closes the descriptor and then 
>  >  > re-uses it (possibly in two threads), the thread using the descriptor 
>  >  > instead of an error will operate on the wrong descriptor.
>  > 
>  > Ah, I see.  I don't see any way around this problem that doesn't
>  > involve locking the descriptor in some way: there will always be a
>  > window.
>  > 
>  > But is locking really such a huge deal?  Really fixing the bug can be
>  > done with something like this, at least on platforms that support
>  > atomic operations:
>  > 
>  > Index: natFileChannelPosix.cc
>  > ===================================================================
>  > --- natFileChannelPosix.cc	(revision 124185)
>  > +++ natFileChannelPosix.cc	(working copy)
>  > @@ -188,7 +188,11 @@
>  >    int r = 0;
>  >    while (r != 1)
>  >      {
>  > -      r = ::write (fd, &d, 1);
>  > +      {
>  > +	int _fd = __sync_val_compare_and_swap (&fd, fd, -1);
>  > +	r = ::write (_fd, &d, 1);
>  > +	__sync_val_compare_and_swap (&fd, _fd, _fd);
>
> Duh.
>
> 	__sync_val_compare_and_swap (&fd, -1, _fd);
>
> ... but you get the idea ...
>
> Andrew.
>   
The only way to close the race window using user space synchronization 
is to make the close block while you could be calling write().

Consider the case where you are doing a blocking read().  The 
synchronization would cause close() to block until the read() had 
finished.  This is not allowed for nio Channels.  The close has to 
terminate the read operation.

David Daney



More information about the Java mailing list