This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: RFC: Too many race conditions.
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);
+ }
if (r == -1)
{
if (::java::lang::Thread::interrupted())
@@ -242,8 +246,7 @@
void
FileChannelImpl::implCloseChannel (void)
{
- jint save = fd;
- fd = -1;
+ jint save = __sync_val_compare_and_swap (&fd, fd, -1);
if (::close (save))
throw new IOException (JvNewStringLatin1 (strerror (errno)));
}
That's an overhead, but not a large one in comparison with the system
call.
Andrew.