Hello,

One more detail: if in the unsetLockIfUnused() method in the DBLocking class, I put the locks.remove(object) call in a synchronized(locks){} block, the problem does not appear any more, but as I don't understand exactly what the problem is, I am not sure if it really solves it or if it just change the timing a little bit making the problem less likely to happen.

Regards

Simon




Hello Christian,

After some testing on my side, I didn't see the ConcurrentModificationException any more.
That's the good news.

However, when running a slightly modified version of the small test case you wrote from my sample application, I faced another problem.
The test can run for a few seconds to almost an hour but eventually, the following exception is thrown.


java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryRelease(ReentrantReadWriteLock.java:374)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1260)
    at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.unlock(ReentrantReadWriteLock.java:1131)
    at org.basex.core.locks.DBLocking.release(DBLocking.java:215)
    at org.basex.core.Context.unregister(Context.java:287)
    at org.basex.core.Command.execute(Command.java:105)
    at org.basex.api.client.LocalSession.execute(LocalSession.java:132)
    at org.basex.api.client.Session.execute(Session.java:36)
    at basextest.BaseXTestDBLocking$1.run(BaseXTestDBLocking.java:43)

I attach my new test case (BaseXTestAdd.java), but the main modification is that in each created thread I also add documents to the collections instead of only opening it.


I was also able to see that in the call to getOrCreateLock() in DBLocking#release(final Proc pr) (line 212) the lock is created while it should already be in the locks Map, but I really cannot understand how this is possible. It would mean that the lock was removed by another thread but for that the usage value must be wrong in the lockUsage map, and I cannot find any sequence of operation that could lead to such a situation.

Trying to pin-point more precisely the problem, I wrote another test (BaseXTestDBLocking.java) that calls directly the acquire and release methods of the DBLocking class. The problem seems to happen more quickly with this test.


Any thoughts ?

Regards

Simon