[9] RFR 8166253: (ch) FileLock object can get GC'd and result in unexpected release of file lock

Hamlin Li huaming.li at oracle.com
Wed Jan 31 05:32:56 UTC 2018



On 31/01/2018 11:04 AM, Brian Burkhalter wrote:
>
> On Jan 30, 2018, at 12:58 AM, Alan Bateman <Alan.Bateman at oracle.com 
> <mailto:Alan.Bateman at oracle.com>> wrote:
>
>>> The proposed fix is:
>>>
>>> http://cr.openjdk.java.net/~bpb/8166253/webrev.03/ 
>>> <http://cr.openjdk.java.net/%7Ebpb/8166253/webrev.03/><http://cr.openjdk.java.net/%7Ebpb/8166253/webrev.03/>
>>>
>> I think it would be simpler if FileChannel maintained a set of the 
>> valid locks obtained via the channel, the the unlock can remove the 
>> lock from the set.
>
> I don’t see how to do this. The FileLock already holds a reference to 
> the Channel and if the converse were to obtain there would be circular 
> references and things blocked from being collected. 
Hi Brian,

I don't have expertise in this area, but I'd like to share my points.

First, I think JVM GC can deal with circular references, so it's not an 
issue.

Then Let me try to explain what Alan means:
As you have pointed out the content in FileLock spec:
"A file-lock object is initially valid. It remains valid until the lock 
is released by invoking the release method, by closing the channel that 
was used to acquire it, or by the termination of the Java virtual 
machine, whichever comes first."
 From the spec, we can conclude that a java file-lock object should have 
the same lifetime as its channel except it's release or closed 
explicitly. So it's reasonable for the channel object to just have 
strong references to the file-lock objects, and delete references if 
file-lock objects are released or the channel is closed. I think in this 
way no new interface like FileLockListener needs to be added, and no 
modification is needed in FileLockImpl and FileLockTable, just needs to 
add/remove file-lock objects in FileChannelImpl and 
AsynchronousFileChannelImpl accordingly. And by this way, file-lock 
objects referred / weak-referred in FileChannelImpl.SimpleFileLockTable 
/ FileLockTable.SharedFileLockTable have the same lifetime, so 
FileChannelImpl.SimpleFileLockTable can be simply removed.

> I did however come up with a simpler change which passes the new test:
>
> http://cr.openjdk.java.net/~bpb/8166253/webrev.04/ 
> <http://cr.openjdk.java.net/%7Ebpb/8166253/webrev.04/>
Second, although it will solve JDK-8166253, it will introduce a new 
issue by line 290("if (!ref.isValid()) {") in FileLockTable.java. I 
think all the refs in queue will satisfy the condition "ref.isValid()", 
so there will be no ref be removed by removeStaleEntries, it will 
increase queue infinitely, finally could get out of memory if long 
enough. And seems there is workaround for this new issue, because line 
290 is the key point to fix the JDK-8166253.

So I prefer Alan's suggestion, it's more clear and straight.

Thank you
-Hamlin
>
> More comprehensive testing would need to be done if this looks better.
>
> On Jan 30, 2018, at 2:16 AM, Daniel Fuchs <daniel.fuchs at oracle.com 
> <mailto:daniel.fuchs at oracle.com>> wrote:
>
>> Should fileKey be made final (AFAICS the field
>> is never mutated) and should isLockReleased
>> be volatile (appears that it could be mutated/read
>> from different threads)?
>
> Fixed in the above webrev.
>
> Thanks,
>
> Brian

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/nio-dev/attachments/20180131/b58564d0/attachment.html>


More information about the nio-dev mailing list