/**
   * Shutdown the file loader and release all resources
   *
   * @param immediate boolean
   */
  public void shutdownLoader(boolean immediate) {

    // Shutdown the background load/save thread pool

    if (m_backgroundLoader != null) m_backgroundLoader.shutdownThreads();
  }
  /**
   * Request file data to be loaded/saved
   *
   * @param req FileRequest
   */
  public void queueFileRequest(FileRequest req) {

    // Pass the request to the background load/save thread pool

    m_backgroundLoader.queueFileRequest(req);
  }
  /**
   * Start the file loader
   *
   * @param ctx DeviceContext
   */
  public void startLoader(DeviceContext ctx) {

    // Get the file state cache from the context

    m_stateCache = getContext().getStateCache();

    // Add the file loader as a file state listener so that we can cleanup temporary data files

    m_stateCache.addStateListener(this);

    // Get the database interface

    DBQueueInterface dbQueue = null;

    if (getContext().getDBInterface() instanceof DBQueueInterface)
      dbQueue = (DBQueueInterface) getContext().getDBInterface();
    else throw new RuntimeException("Database interface does not implement queue interface");

    // Perform a queue cleanup before starting the thread pool. This will check the temporary cache
    // area and delete
    // files that are not part of a queued save/transaction save request.

    FileRequestQueue recoveredQueue = null;

    try {

      // Cleanup the temporary cache area and queue

      recoveredQueue =
          dbQueue.performQueueCleanup(m_tempDir, TempDirPrefix, TempFilePrefix, JarFilePrefix);

      // DEBUG

      if (recoveredQueue != null && Debug.EnableInfo && hasDebug())
        Debug.println(
            "[DBLoader] Cleanup recovered "
                + recoveredQueue.numberOfRequests()
                + " pending save files");
    } catch (DBException ex) {

      // DEBUG

      if (Debug.EnableError && hasDebug()) Debug.println(ex);
    }

    // Check if there are any file save requests pending in the queue database

    FileRequestQueue saveQueue = new FileRequestQueue();

    try {
      dbQueue.loadFileRequests(1, FileRequest.SAVE, saveQueue, 1);
    } catch (DBException ex) {
    }

    // Create the background load/save thread pool

    m_backgroundLoader = new BackgroundLoadSave("DBLdr", dbQueue, m_stateCache, this);

    m_backgroundLoader.setReadWorkers(m_readWorkers);
    m_backgroundLoader.setWriteWorkers(m_writeWorkers);

    m_backgroundLoader.setDebug(m_threadDebug);

    // Start the file loader threads, start the request loading if there are pending file save
    // requests

    m_backgroundLoader.startThreads(saveQueue.numberOfRequests());

    // Queue the recovered file save requests

    if (recoveredQueue != null) {

      // Queue the file save requests

      while (recoveredQueue.numberOfRequests() > 0)
        queueFileRequest(recoveredQueue.removeRequestNoWait());
    }
  }