You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jena.apache.org by Andy Seaborne <an...@apache.org> on 2012/12/02 20:58:05 UTC

Concurrency test failure (reasoners)

In the jena-core-simplified branch, I am getting a test failure for

com.hp.hpl.jena.reasoner.rulesys.test.ConcuerrencyTest.testWithOWLMemMicroRuleInfModel

The deadlock does not seem to be from the changes as this looks like an 
embrace situation:

A/ In LPTopGoalIterator moveForward is synchronized and then grabs a 
lock on an LPBRuleEngine.

So the locking is:
LPTopGoalIterator -> LPBRuleEngine

B/ LPBRuleEngine.checkSafeToUpdate has "Should be called from within a 
synchronized block." in the javadoc and it calls 
LPTopGoalIterator.close, a synchronized method.

The outer synchronized is LPBRuleEngine.deleteAllRules

so the lock order is

LPBRuleEngine -> LPTopGoalIterator


Oops.

Is the sequence below safe?  Move the synchronized in to cover only the 
close and get of the engine.

LPTopGoalIterator --

  private /*synchronized*/ void moveForward() {
         LPBRuleEngine lpEngine ;
         synchronized(this)
         {
             checkClosed();
             lpEngine = interpreter.getEngine();
         }
         synchronized (lpEngine) {
             // Check again, is lpEngine valid?
             checkClosed();

	Andy


--------------------------
Debug from ConcurrencyTest:
The commented out Java6 has been put in.

*** Deadlocked threads
Thread "pool-1-thread-20" id=28 BLOCKED
Lock name: com.hp.hpl.jena.reasoner.rulesys.impl.LPBRuleEngine@7a4632db 
owned by "pool-1-thread-1" id=9

Stack trace:
    com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward 
(LPTopGoalIterator.java:89)
    com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext 
(LPTopGoalIterator.java:200)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
    com.hp.hpl.jena.util.iterator.UniqueExtendedIterator.hasNext 
(UniqueExtendedIterator.java:77)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
    com.hp.hpl.jena.util.iterator.FilterIterator.hasNext 
(FilterIterator.java:55)
    com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext 
(Map1Iterator.java:49)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
 
com.hp.hpl.jena.reasoner.rulesys.test.ConcurrencyTest$1QueryExecutingRunnable.run 
(ConcurrencyTest.java:129)
    java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:471)
    java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:334)
    java.util.concurrent.FutureTask.run (FutureTask.java:166)
    java.util.concurrent.ThreadPoolExecutor.runWorker 
(ThreadPoolExecutor.java:1110)
    java.util.concurrent.ThreadPoolExecutor$Worker.run 
(ThreadPoolExecutor.java:603)
    java.lang.Thread.run (Thread.java:722)

Thread "pool-1-thread-1" id=9 BLOCKED
Lock name: 
com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator@46c2ea31 owned 
by "pool-1-thread-5" id=13

Stack trace:
    com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.close 
(LPTopGoalIterator.java:173)
 
com.hp.hpl.jena.reasoner.rulesys.impl.LPBRuleEngine.checkSafeToUpdate 
(LPBRuleEngine.java:235)
    com.hp.hpl.jena.reasoner.rulesys.impl.LPBRuleEngine.deleteAllRules 
(LPBRuleEngine.java:158)
    com.hp.hpl.jena.reasoner.rulesys.FBRuleInfGraph.prepare 
(FBRuleInfGraph.java:463)
    com.hp.hpl.jena.reasoner.rulesys.FBRuleInfGraph.findWithContinuation 
(FBRuleInfGraph.java:576)
    com.hp.hpl.jena.reasoner.rulesys.FBRuleInfGraph.graphBaseFind 
(FBRuleInfGraph.java:608)
    com.hp.hpl.jena.reasoner.BaseInfGraph.graphBaseFind 
(BaseInfGraph.java:375)
    com.hp.hpl.jena.graph.impl.GraphBase.find (GraphBase.java:264)
    com.hp.hpl.jena.graph.GraphUtil.findAll (GraphUtil.java:128)
    com.hp.hpl.jena.rdf.model.impl.ModelCom.listStatements 
(ModelCom.java:1014)
 
com.hp.hpl.jena.reasoner.rulesys.test.ConcurrencyTest$1QueryExecutingRunnable.run 
(ConcurrencyTest.java:123)
    java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:471)
    java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:334)
    java.util.concurrent.FutureTask.run (FutureTask.java:166)
    java.util.concurrent.ThreadPoolExecutor.runWorker 
(ThreadPoolExecutor.java:1110)
    java.util.concurrent.ThreadPoolExecutor$Worker.run 
(ThreadPoolExecutor.java:603)
    java.lang.Thread.run (Thread.java:722)

Thread "pool-1-thread-5" id=13 BLOCKED
Lock name: com.hp.hpl.jena.reasoner.rulesys.impl.LPBRuleEngine@7a4632db 
owned by "pool-1-thread-1" id=9

Stack trace:
    com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.moveForward 
(LPTopGoalIterator.java:89)
    com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator.hasNext 
(LPTopGoalIterator.java:200)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
    com.hp.hpl.jena.util.iterator.UniqueExtendedIterator.hasNext 
(UniqueExtendedIterator.java:77)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
    com.hp.hpl.jena.util.iterator.FilterIterator.hasNext 
(FilterIterator.java:55)
    com.hp.hpl.jena.util.iterator.Map1Iterator.hasNext 
(Map1Iterator.java:49)
    com.hp.hpl.jena.util.iterator.WrappedIterator.hasNext 
(WrappedIterator.java:76)
 
com.hp.hpl.jena.reasoner.rulesys.test.ConcurrencyTest$1QueryExecutingRunnable.run 
(ConcurrencyTest.java:129)
    java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:471)
    java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:334)
    java.util.concurrent.FutureTask.run (FutureTask.java:166)
    java.util.concurrent.ThreadPoolExecutor.runWorker 
(ThreadPoolExecutor.java:1110)
    java.util.concurrent.ThreadPoolExecutor$Worker.run 
(ThreadPoolExecutor.java:603)
    java.lang.Thread.run (Thread.java:722)


Re: Concurrency test failure (reasoners)

Posted by Andy Seaborne <an...@apache.org>.
And another one ... this time involving LPTopGoalIterator.close

I have (in the "simplified branch") remove all method locking in 
LPTopGoalIterator and made sure all locks on LPTopGoalIterator are done 
either with no nested lock or inside a local synchronized on the 
LPBRuleEngine instance.

Many test cycles run, inside Eclispe and in Maven (which show different 
behaviours) ... so far, no deadlocks.

	Andy

On 02/12/12 21:00, Andy Seaborne wrote:
> On 02/12/12 19:58, Andy Seaborne wrote:
>> In the jena-core-simplified branch, I am getting a test failure for
>>
>> com.hp.hpl.jena.reasoner.rulesys.test.ConcuerrencyTest.testWithOWLMemMicroRuleInfModel
>>
>>
>>
>> The deadlock does not seem to be from the changes as this looks like an
>> embrace situation:
>>
>> A/ In LPTopGoalIterator moveForward is synchronized and then grabs a
>> lock on an LPBRuleEngine.
>>
>> So the locking is:
>> LPTopGoalIterator -> LPBRuleEngine
>>
>> B/ LPBRuleEngine.checkSafeToUpdate has "Should be called from within a
>> synchronized block." in the javadoc and it calls
>> LPTopGoalIterator.close, a synchronized method.
>>
>> The outer synchronized is LPBRuleEngine.deleteAllRules
>>
>> so the lock order is
>>
>> LPBRuleEngine -> LPTopGoalIterator
>>
>>
>> Oops.
>>
>> Is the sequence below safe?  Move the synchronized in to cover only the
>> close and get of the engine.
>>
>> LPTopGoalIterator --
>>
>>   private /*synchronized*/ void moveForward() {
>>          LPBRuleEngine lpEngine ;
>>          synchronized(this)
>>          {
>>              checkClosed();
>>              lpEngine = interpreter.getEngine();
>>          }
>>          synchronized (lpEngine) {
>>              // Check again, is lpEngine valid?
>>              checkClosed();
>>
>>      Andy
>
>
> That didn't work - I'm seeing other concurrency failures now.
>
> To duplicate the lock ordering in LPBRuleEngine.checkSafeToUpdate I have
> put in (jena-core-simplied branch):
>
> private void moveForward() {
>      LPBRuleEngine lpEngine ;
>      synchronized(this)
>      {
>          checkClosed();
>          lpEngine = interpreter.getEngine();
>      }
>      synchronized (lpEngine) {
>      // Elsewhere code takes an LPBRuleEngine then an LPTopGoalIterator
>      // Ensure we do that lock order here as well as just synchronized
>      // on the method reverses the locks takne, leading to deadlock.
>          synchronized(this)
>          {
>              checkClosed();
>           ....
>
> which, so far, has been passing.
>
>      Andy


Re: Concurrency test failure (reasoners)

Posted by Andy Seaborne <an...@apache.org>.
On 02/12/12 19:58, Andy Seaborne wrote:
> In the jena-core-simplified branch, I am getting a test failure for
>
> com.hp.hpl.jena.reasoner.rulesys.test.ConcuerrencyTest.testWithOWLMemMicroRuleInfModel
>
>
> The deadlock does not seem to be from the changes as this looks like an
> embrace situation:
>
> A/ In LPTopGoalIterator moveForward is synchronized and then grabs a
> lock on an LPBRuleEngine.
>
> So the locking is:
> LPTopGoalIterator -> LPBRuleEngine
>
> B/ LPBRuleEngine.checkSafeToUpdate has "Should be called from within a
> synchronized block." in the javadoc and it calls
> LPTopGoalIterator.close, a synchronized method.
>
> The outer synchronized is LPBRuleEngine.deleteAllRules
>
> so the lock order is
>
> LPBRuleEngine -> LPTopGoalIterator
>
>
> Oops.
>
> Is the sequence below safe?  Move the synchronized in to cover only the
> close and get of the engine.
>
> LPTopGoalIterator --
>
>   private /*synchronized*/ void moveForward() {
>          LPBRuleEngine lpEngine ;
>          synchronized(this)
>          {
>              checkClosed();
>              lpEngine = interpreter.getEngine();
>          }
>          synchronized (lpEngine) {
>              // Check again, is lpEngine valid?
>              checkClosed();
>
>      Andy


That didn't work - I'm seeing other concurrency failures now.

To duplicate the lock ordering in LPBRuleEngine.checkSafeToUpdate I have 
put in (jena-core-simplied branch):

private void moveForward() {
     LPBRuleEngine lpEngine ;
     synchronized(this)
     {
         checkClosed();
         lpEngine = interpreter.getEngine();
     }
     synchronized (lpEngine) {
     // Elsewhere code takes an LPBRuleEngine then an LPTopGoalIterator
     // Ensure we do that lock order here as well as just synchronized
     // on the method reverses the locks takne, leading to deadlock.
         synchronized(this)
         {
             checkClosed();
          ....

which, so far, has been passing.

	Andy