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

Valery Kharseko
yesterday 1af0a1247d3e2d503a53723dd1d844c90c43ccc6
opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/JEStorage.java
@@ -791,37 +791,50 @@
      trees.clear();
    }
    if (env != null)
    try
    {
      DirectoryServer.deregisterMonitorProvider(monitor);
      monitor = null;
      try
      if (env != null)
      {
        // Not yet registered when a failed open got no further than the environment itself.
        if (monitor != null)
        {
          DirectoryServer.deregisterMonitorProvider(monitor);
          monitor = null;
        }
        env.close();
        env = null;
      }
      catch (DatabaseException e)
      {
        throw new IllegalStateException(e);
      }
    }
    if (memQuota != null)
    catch (DatabaseException e)
    {
      if (config.getDBCacheSize() > 0)
      {
        memQuota.releaseMemory(config.getDBCacheSize());
      }
      else
      {
        memQuota.releaseMemory(memQuota.memPercentToBytes(config.getDBCachePercent()));
      }
      throw new IllegalStateException(e);
    }
    config.removeJEChangeListener(this);
    envConfig = null;
    if (diskMonitor != null)
    finally
    {
      diskMonitor.deregisterMonitoredDirectory(getDirectory(), this);
      // Given back after the environment, and whether or not its close threw: reporting the
      // memory free before the environment has actually freed it would let a racing enable of
      // another backend be admitted while this one's cache is still resident.
      if (memQuota != null)
      {
        if (config.getDBCacheSize() > 0)
        {
          memQuota.releaseMemory(config.getDBCacheSize());
        }
        else
        {
          memQuota.releaseMemory(memQuota.memPercentToBytes(config.getDBCachePercent()));
        }
        // Released once: what an open takes, the next open takes again, and a close which follows
        // a close - BackendImpl.importLDIF closes the storage of its root container however the
        // import ended, on top of the close the import itself made - releases nothing more.
        memQuota = null;
      }
      config.removeJEChangeListener(this);
      envConfig = null;
      if (diskMonitor != null)
      {
        diskMonitor.deregisterMonitoredDirectory(getDirectory(), this);
      }
    }
  }
@@ -836,8 +849,53 @@
      // Do not open files on disk
      return;
    }
    rejectIfOpen();
    buildConfiguration(accessMode, false);
    open0();
    openOrGiveBack();
  }
  /**
   * Refuses to open an environment which is open, before anything is taken for the attempt: the
   * refusal guards against a programming error, and what this storage holds is left as it is.
   */
  private void rejectIfOpen()
  {
    if (env != null)
    {
      throw new IllegalStateException(
          "Database is already open, either the backend is enabled or an import is currently running.");
    }
  }
  /**
   * Opens the environment, or gives back what the attempt took before it failed. Nothing else will:
   * a root container does not close a storage whose {@code open()} threw, and a backend whose open
   * failed is thrown away with the storage still registered as a listener of its configuration and
   * the cache size it reserved still drawn from the memory quota - once per attempt to enable it.
   */
  private void openOrGiveBack() throws ConfigException
  {
    boolean opened = false;
    try
    {
      open0();
      opened = true;
    }
    finally
    {
      if (!opened)
      {
        try
        {
          close();
        }
        catch (RuntimeException e)
        {
          // The failure being given up after is the one worth reporting, and this must not replace it.
          logger.traceException(e);
        }
      }
    }
  }
  private boolean isBackendIncomplete(AccessMode accessMode)
@@ -863,11 +921,6 @@
    setupStorageFiles(backendDirectory, config.getDBDirectoryPermissions(), config.dn());
    try
    {
      if (env != null)
      {
        throw new IllegalStateException(
            "Database is already open, either the backend is enabled or an import is currently running.");
      }
      env = new Environment(backendDirectory, envConfig);
      monitor = new JEMonitor(config.getBackendId() + " JE Database", env);
      DirectoryServer.registerMonitorProvider(monitor);
@@ -899,8 +952,9 @@
  @Override
  public Importer startImport() throws ConfigException, StorageRuntimeException
  {
    rejectIfOpen();
    buildConfiguration(AccessMode.READ_WRITE, true);
    open0();
    openOrGiveBack();
    return new ImporterImpl();
  }