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

pgamba
25.20.2008 c51087e0fd110ff0174799aa50e83ec33bf687be
The recent lock introduced recently in order to not access the database while it is truncated is sometimes not released correctly.
The following fix do not change anything in the logic of the replication processing : it just makes more robust the unlocking whatever exception or problem occurs in the processing.

1 files modified
100 ■■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDB.java 100 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDB.java
@@ -253,13 +253,27 @@
    return new ReplServerDBCursor();
  }
  private void closeLockedCursor(Cursor cursor)
    throws DatabaseException
  {
    try
    {
      if (cursor != null)
        cursor.close();
    }
    finally
    {
      dbCloseLock.readLock().unlock();
    }
  }
  /**
   * Read the first Change from the database.
   * @return the first ChangeNumber.
   */
  public ChangeNumber readFirstChange()
  {
    Cursor cursor;
    Cursor cursor = null;
    String str = null;
    try
@@ -274,11 +288,11 @@
    }
    try
    {
      try
      {
      DatabaseEntry key = new DatabaseEntry();
      DatabaseEntry data = new DatabaseEntry();
      OperationStatus status = cursor.getFirst(key, data, LockMode.DEFAULT);
      cursor.close();
      dbCloseLock.readLock().unlock();
      if (status != OperationStatus.SUCCESS)
      {
        /* database is empty */
@@ -292,17 +306,14 @@
        // never happens
      }
      return new ChangeNumber(str);
    } catch (DatabaseException e)
    {
      try
      {
        cursor.close();
        dbCloseLock.readLock().unlock();
      }
      catch (DatabaseException dbe)
      finally
      {
        // The db is dead - let's only log.
        closeLockedCursor(cursor);
      }
    }
    catch (DatabaseException e)
    {
      /* database is faulty */
      MessageBuilder mb = new MessageBuilder();
      mb.append(ERR_CHANGELOG_SHUTDOWN_DATABASE_ERROR.get());
@@ -319,18 +330,18 @@
   */
  public ChangeNumber readLastChange()
  {
    Cursor cursor;
    Cursor cursor = null;
    String str = null;
    try
    {
      dbCloseLock.readLock().lock();
      try
      {
      cursor = db.openCursor(null, null);
      DatabaseEntry key = new DatabaseEntry();
      DatabaseEntry data = new DatabaseEntry();
      OperationStatus status = cursor.getLast(key, data, LockMode.DEFAULT);
      cursor.close();
      dbCloseLock.readLock().unlock();
      if (status != OperationStatus.SUCCESS)
      {
        /* database is empty */
@@ -339,12 +350,19 @@
      try
      {
       str = new String(key.getData(), "UTF-8");
      } catch (UnsupportedEncodingException e)
        }
        catch (UnsupportedEncodingException e)
      {
        // never happens
      }
      return new ChangeNumber(str);
    } catch (DatabaseException e)
      }
      finally
      {
        closeLockedCursor(cursor);
      }
    }
    catch (DatabaseException e)
    {
      MessageBuilder mb = new MessageBuilder();
      mb.append(ERR_CHANGELOG_SHUTDOWN_DATABASE_ERROR.get());
@@ -371,6 +389,10 @@
  public class ReplServerDBCursor
  {
    private Cursor cursor = null;
    // The transaction that will protect the actions done with the cursor
    // Will be let null for a read cursor
    // Will be set non null for a write cursor
    private Transaction txn = null;
    DatabaseEntry key = new DatabaseEntry();
    DatabaseEntry data = new DatabaseEntry();
@@ -407,8 +429,6 @@
              OperationStatus.SUCCESS)
            {
              // We could not even move the cursor closed to it => failure
              // Unlocking is required before throwing any exception
              dbCloseLock.readLock().unlock();
              throw new Exception("ChangeNumber not available");
            }
            else
@@ -420,18 +440,10 @@
              if (cursor.getPrev(key, data, LockMode.DEFAULT) !=
                OperationStatus.SUCCESS)
              {
                try
                {
                  cursor.close();
                closeLockedCursor(cursor);
                dbCloseLock.readLock().lock();
                  cursor = db.openCursor(txn, null);
                }
                catch(Exception e)
                {
                  // Unlocking is required before throwing any exception
                  dbCloseLock.readLock().unlock();
                  throw(e);
                }
              }
            }
          }
        }
@@ -439,8 +451,7 @@
      catch (Exception e)
      {
        // Unlocking is required before throwing any exception
        dbCloseLock.readLock().unlock();
        cursor.close();
        closeLockedCursor(cursor);
        throw (e);
      }
    }
@@ -451,12 +462,25 @@
      {
        // We'll go on only if no close or no clear is running
        dbCloseLock.readLock().lock();
        // Create the transaction that will protect whatever done with this
        // write cursor.
        txn = dbenv.beginTransaction();
        cursor = db.openCursor(txn, null);
      }
      catch(DatabaseException e)
      {
        dbCloseLock.readLock().unlock();
        if (txn != null)
        {
          try
          {
            txn.abort();
          }
          catch (DatabaseException dbe)
          {}
        }
        closeLockedCursor(cursor);
        throw (e);
      }
    }
@@ -468,23 +492,17 @@
    {
      try
      {
        if (cursor != null)
        {
          cursor.close();
        closeLockedCursor(cursor);
          cursor = null;
        }
      }
      catch (DatabaseException e)
      {
        dbCloseLock.readLock().unlock();
        MessageBuilder mb = new MessageBuilder();
        mb.append(ERR_CHANGELOG_SHUTDOWN_DATABASE_ERROR.get());
        mb.append(stackTraceToSingleLineString(e));
        logError(mb.toMessage());
        replicationServer.shutdown();
      }
      if (txn != null)
      {
        try
@@ -499,7 +517,6 @@
          replicationServer.shutdown();
        }
      }
      dbCloseLock.readLock().unlock();
    }
    /**
@@ -515,7 +532,7 @@
        return;
      try
      {
        cursor.close();
        closeLockedCursor(cursor);
        cursor = null;
      }
      catch (DeadlockException e1)
@@ -526,8 +543,6 @@
      }
      catch (DatabaseException e)
      {
        dbCloseLock.readLock().unlock();
        MessageBuilder mb = new MessageBuilder();
        mb.append(ERR_CHANGELOG_SHUTDOWN_DATABASE_ERROR.get());
        mb.append(stackTraceToSingleLineString(e));
@@ -548,7 +563,6 @@
          replicationServer.shutdown();
        }
      }
      dbCloseLock.readLock().unlock();
    }
    /**