mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
17.02.2013 e51bf9ccc4c08a9f93f4e0295bd334bbd3b747ca
OPENDJ-1116 Introduce abstraction for the changelog DB

Investigating ExternalChangeLogTest.ECLReplicationServerFullTest(), I found a bug introduced by r9538.
In DraftCNDBCursor(long) ctor, when returning null, the code did not release the readLock anymore. Previously, it threw an exception that was caught, then released the readLock and rethrown.
Problem is there was an underlying bug in the previous code too: when the DB was already closed, the readLock would not be released at all.

Now by introducing the cursorHeld local variable, the readLock is appropriately released in the finally clause when no cursor is held at all.
Also fixed the code in DraftCNDBCursor().
1 files modified
32 ■■■■■ changed files
opends/src/server/org/opends/server/replication/server/changelog/je/DraftCNDB.java 32 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/server/changelog/je/DraftCNDB.java
@@ -377,6 +377,7 @@
      // unlock it when throwing an exception.
      dbCloseLock.readLock().lock();
      boolean cursorHeld = false;
      Cursor localCursor = null;
      try
      {
@@ -423,18 +424,21 @@
        this.txn = null;
        this.cursor = localCursor;
        cursorHeld = true;
      }
      catch (DatabaseException e)
      {
        // Unlocking is required before throwing any exception
        closeLockedCursor(localCursor);
        throw new ChangelogException(e);
      }
      catch (ChangelogException e)
      finally
      {
        // Unlocking is required before throwing any exception
        closeLockedCursor(localCursor);
        throw e;
        if (!cursorHeld)
        {
          // Do not keep a readLock on the DB when this class does not hold a DB
          // cursor. Either an exception was thrown or no cursor could be opened
          // for some reason.
          closeLockedCursor(localCursor);
        }
      }
    }
@@ -446,6 +450,7 @@
      this.key = new ReplicationDraftCNKey();
      // We'll go on only if no close or no clear is running
      boolean cursorHeld = false;
      dbCloseLock.readLock().lock();
      try
      {
@@ -465,23 +470,30 @@
        this.txn = localTxn;
        this.cursor = localCursor;
        cursorHeld = true;
      }
      catch (DatabaseException e)
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
        closeLockedCursor(localCursor);
        DraftCNDB.abort(localTxn);
        throw new ChangelogException(e);
      }
      catch (ChangelogException e)
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
        closeLockedCursor(localCursor);
        DraftCNDB.abort(localTxn);
        throw e;
      }
      finally
      {
        if (!cursorHeld)
        {
          // Do not keep a readLock on the DB when this class does not hold a DB
          // cursor. Either an exception was thrown or no cursor could be opened
          // for some reason.
          closeLockedCursor(localCursor);
        }
      }
    }
    /**