WatchService - Exposing more of the Inotify Event Model
Rémi Forax
forax at univ-mlv.fr
Thu Sep 23 11:12:13 PDT 2010
Le 23/09/2010 19:15, Benedict Elliott Smith a écrit :
> On 23 September 2010 18:11, Rémi Forax <forax at univ-mlv.fr
> <mailto:forax at univ-mlv.fr>> wrote:
>
> Le 23/09/2010 17:45, Benedict Elliott Smith a écrit :
>> It /is/ fairly easy to store the Watchable as a field in the
>> WatchKey, except that the WatchKey is created by the
>> WatchService, over which the user typically has no control - and
>> the default implementations return a WatchKey that cannot tell
>> you what it is watching (despite obviously having to know this).
>
> Ok.
> As I said, I think a more general attached Object is a better
> solution in my opinion.
>
> If you would rather provide the ability to annotate the information
> WatchKey with arbitrary information this would be a perfectly
> acceptable solution IMHO.
>
>>
>> As such, currently (and in the example usages) the user has to
>> insert the WatchKey that is returned by the WatchService into a
>> map which stores the Watchable. The problem is that if a
>> different thread registers the Watchable to the one consuming
>> events from the WatchService, it is possible for a WatchKey to be
>> returned to the consumer before the map contains it, and hence
>> the consumer does not know what Watchable it is for.
>
> If you store/retreive the path in a synchronized block or use a
> ConcurrentHashMap
> and call put() before registering, I don't see why there is a
> problem ?
>
> Using a ConcurrentHashMap only enforces a happens-before relation, it
> does not address race conditions. Consider the following pseudo-code:
>
> Thread1 {
> watchkey = watchservice.register(mypath)
> sharedmap.put(watchkey, mypath)
> }
>
> Thread2 {
> watchkey = watchservice.poll()
> path = sharedmap.get(watchkey)
> }
>
> While making sharedmap either synchronized or a ConcurrentHashMap does
> guarantee that the map is consistent and that the mapping eventually
> shows up for Thread2, it does nothing to address the fact that Thread1
> may be swapped out after executing the first instruction, and not
> execute its second instruction until after Thread2 reads from the map,
> getting no result.
>
> You could synchronize around both steps, but this is really not a very
> elegant solution. Also, it is a pitfall many people will not even
> notice, and hence not code to avoid. It seems best to address it with
> an obvious and simply solution that is built into the standard
> examples of usage. i.e. that the path is obtainable from the WatchKey.
> It seems likely that this information will required more often than
> not, surely?
There is another possible implementation, using a blocking queue and
interrupt:
Thread {
queue.put(mypath);
watchserviceThread.interrupt();
}
WatchserviceThread {
for(;;) {
try {
watchkey = watchservice.take()
} catch(InterruptedException e) {
while ((path = queue.poll()) != null) {
path.register(watchservice);
sharedmap.put(watchey, path);
}
continue;
}
path = sharedmap.get(watchkey);
...
}
}
In that case, the registration and the watchkey retreival are
confined in one thread.
>
>>
>> This seems bad to me.
>>
>> Even if this weren't the case though, it seems a bit unnecessary
>> to expect the user to store the Watchable themselves - as you
>> say, it should be easy to store it in the WatchKey, so I'm not
>> sure why it isn't exposed to the user? Or am I missing something
>> obvious?
>
> It's not exposed because the current implementation doesn't store
> it :)
> On Linux the file descriptor is stored not the corresponding Path.
>
>
> Fair enough, I can see why you would have chosen to avoid putting it
> in (since Path is not a particularly lightweight object) - but it
> seems like it might be a necessary evil to help prevent this problem
> biting users randomly without their knowing why or what to do about it.
>
>
> Rémi
>
Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/nio-dev/attachments/20100923/cab3cc90/attachment-0001.html
More information about the nio-dev
mailing list