As part of my work on issue 40290 I have find out
that there is a subtle problem present in the
system that can cause nearly anything to get
broken "once upon a time". The problem is that
when one part of the system is writing to output
stream of a file object, other part can read the
(not yet finished) content. This is sometimes
causing DataObjects to not be propertly
recognized, mime type being wrongly guessed, etc,
I'd like to propose simple solution: Mutual
exclusion of getInputStream() and
getOutputStream(). That way if there is an open
output stream for a file object, nobody else could
get an inputstream, the call would block (for
certain timeout, that is my suggestion).
The implementation shall be pretty straightforward
as there already is StreamPool that registers all
open streams and can be used to implement the
I believe that by fixing this issue a lot of
phantom errors occuring from time to time would
this should be handled w/ extreme care. Yarda's suggested solution
introduces a hidden lock
Created attachment 16187 [details]
Test that demonstrates the problem
I believe that the current behaviour is buggy and as we have now test
I am turning this issue from enh to defect. I am not sure about the
priority, but as this can be responsible for any random problem, I am
setting this to p2.
Created attachment 16188 [details]
Simplest fix that detects and reports the problem instead of silently pretending that everything is all right
This seems like P3 unless there is a known significant problem arising
Anyway, the patch looks fine; I can't think of any situation where it
would be unwanted.
Jarda, okay. Let integrate the patch first thing after you'll be back
at work. *After* because in case of trouble you'd be available to
Created attachment 16205 [details]
More abitious fix
I am suspecting various problems with settings files (as issue 40290)
to be caused by this problem - e.g. somebody starts to read the
content of setting file until it is fully created and possibly messes
up the public id, etc.
For that the early detection fix (that throws exception) is enough. If
such situation occurs, we will know about it and yes, I cannot think
of a situation when it would go wrong. Just instead of reading
unfinished content (means wrong content) it throws exception, I
believe that is better.
If we really get such exception and we will be searching for a
solution I offer the more ambitious fix, that contains a recovery
mechanism for cases when the read/write collision occurs.
For reference: the last-attached patch is a kind of spin lock with
timeout. Crude but probably safer than the read-write lock which was
also proposed, at least in the absence of a clear global locking
strategy for Filesystems.
Your patch ensures that you can't get input stream until related
output stream is closed. But what about if you get first input stream
and then output stream (there may occure various race conditions).
There exist FileLock (could be embryo of global locking strategy) in
filesystems. There could be possible to get exclusive and non
exclusive locks. FileLocks could also call nio.FileLocks to use native
locking. There could be provided support for mutual IS & OS exclusion
and something like described in #40739. But it deserves API changes,
agreement and reviews. So, I think that RFE would be more suitable here.
If there are real known problems caused by current behaviour then
FileLocks can be already used for mutual IS & OS exclusion (get
FileLock also for reading from input stream and somehow handle
I modified attached patch. Please see new patch and review.
Created attachment 16453 [details]
Stream + tests
Definitively improves current situation. I was not able to find out a
test for mutual exclusion of write when an input stream is open, which
seems to be also addressed by the changes in code, however.
new revision: 1.97; previous revision: 1.96
/cvs/openide/src/org/openide/filesystems/StreamPool.java,v <-- new
revision: 1.6; previous revision: 1.5
new revision: 1.38; previous revision: 1.37
Closed, too old