Closed GoogleCodeExporter closed 9 years ago
Original comment by sergey.s...@gmail.com
on 12 Mar 2012 at 3:22
Hi,
thanks for reporting. I would ask you few questions:
1. Are you using only one thread or concurrent access from many threads? Do all
entries in your stacktrace describe different states of the same one thread or
do all those entries describe different threads? I suppose you are using only
one thread and stacktrace describe different states of this one thread, am I
right?
2. Could you describe something about exception which is thrown from
AbstractInterruptibleChannel? Why lock isn't valid after that?
3. Could you suggest something about what can be released invalid lock?
JDK reference states:
"void java.nio.channels.FileLock.release() throws IOException
Releases this lock.
If this lock object is valid then invoking this method releases the lock and
renders the object invalid. If this lock object is invalid then invoking this
method has no effect."
So, if lock was become invalid after some exception in NIO SPI level then it
can't be released, or there is some way to unlock it?
Thanks!
Original comment by sergey.s...@gmail.com
on 12 Mar 2012 at 5:04
In any case, what you find is a very serious and interesting. We only need to
understand exactly what is happening and how is it possible to solve such
situations. Thank you very much for your help.
Original comment by sergey.s...@gmail.com
on 12 Mar 2012 at 5:22
Hi,
> 1. Are you using only one thread or concurrent access from many threads?
The stacktraces come from a single thread, i suspended all other threads (in
debugger) in our application before it called any code from SQLJet. So yes, all
the stacktraces come from the single thread
> 2. an exception ClosedByInterruptException is then thrown. I guess it's an ex
similar to InterruptedException.
> Why lock isn't valid after that?
I have no idea, i didn't investigate.
> 3. Could you suggest something about what can be released invalid lock?
I am sorry, i am not familiar too much with java.nio API. I'll take a look
tomorrow at work and try to understand why the lock gets invalid.
Original comment by ondra.vr...@gmail.com
on 12 Mar 2012 at 6:45
Hi, i would like to correct my partially wrong assumptions. To 3)
> However when the thread accessing the db gets interrupted while in
java.nio.channels.spi.AbstractInterruptibleChannel.blockedOn(AbstractInterruptib
leChannel.java:191), only one of the two locks are unlocked and released.
In the meaning of java.nio locking (java.nio.channels.FileLock), all
locks are correctly released and the db file is unlocked.
> The second one persists (stored in
org.tmatesoft.sqljet.core.internal.fs.SqlJetFileLockManager.locks) as
shared/invalid and the database cannot be locked for write any more until you
shut the application down.
Although invalid (and released) the lock is still kept by SqlJetFileLockManager
and never gets deleted from its static field SqlJetFileLockManager.locks. And
*this is the problem*. Because there is still this (shared though invalid) lock
(SqlJetFileLock) in SqlJetFileLockManager it prevents SQLJet from acquiring an
exclusive lock on the db file when needed sometimes later in another thread:
java.lang.Thread.State: RUNNABLE
at org.tmatesoft.sqljet.core.internal.fs.SqlJetFileLockManager.createLock(SqlJetFileLockManager.java:70)
- locked <0x00000000d1f4c990> (a java.util.concurrent.ConcurrentHashMap)
at org.tmatesoft.sqljet.core.internal.fs.SqlJetFileLockManager.tryLock(SqlJetFileLockManager.java:87)
at org.tmatesoft.sqljet.core.internal.fs.SqlJetFile.lock(SqlJetFile.java:542)
- locked <0x00000000d1fcb470> (a java.util.HashMap)
- locked <0x00000000f43f0c60> (a org.tmatesoft.sqljet.core.internal.fs.SqlJetFile)
at org.tmatesoft.sqljet.core.internal.pager.SqlJetPager.waitOnLock(SqlJetPager.java:2522)
Because removal of the instance of SqlJetFileLock from the
SqlJetFileLockManager is handled only in SqlJetFileLock.release() and this
method is never called, because the java.nio.FileLock is invalid:
> if (l.isValid())
> l.release();
taken from the unlock() method of SqlJetFile, SqlJetFileLockManager will never
release the pending invalid lock
I hope it makes sense now. Sorry i was not 100% clear before.
Original comment by ondra.vr...@gmail.com
on 13 Mar 2012 at 9:11
this small patch seems to resolve all my problems. However it is heavily
dependent on the knowledge that all FileLock(s) handled in SqlJetFile are
actually SqlJetFileLock(s). From the javadoc FileLock.release may throw an
exception, the patch is not safe enough if for some reason an instance of
java.nio.channels.FileLock instead of SqlJetFileLock would appear in
SqlJetFile. But maybe it would be enough to just wrap the calls in try-catch
blocks?
Original comment by ondra.vr...@gmail.com
on 13 Mar 2012 at 9:28
Attachments:
Thanks! I'll review your patch and I'm sure you have found and fixed very
subtle flaw in SqlJet code. Thanks you a lot.
Soon there will be updated build with your patch included and it would be
better if you will test it with your test cases.
Original comment by sergey.s...@gmail.com
on 13 Mar 2012 at 1:05
Thanks for the patch. New SVNKit build with the patch included is available
here:
http://teamcity.tmatesoft.com/viewLog.html?buildId=1924&tab=artifacts&buildTypeI
d=bt43
Original comment by kit...@gmail.com
on 13 Mar 2012 at 5:38
thanks, i tried the snapshot. Now i can perform any modification commands with
SVNKit even after a previous command is canceled.
Original comment by ondra.vr...@gmail.com
on 14 Mar 2012 at 9:48
Original comment by sergey.s...@gmail.com
on 30 Oct 2012 at 9:45
Original issue reported on code.google.com by
ondra.vr...@gmail.com
on 12 Mar 2012 at 1:22Attachments: