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

Reply via email to