/** @param workTokDir Token directory (common for multiple nodes). */
    private void cleanupResources(File workTokDir) {
      RandomAccessFile lockFile = null;

      FileLock lock = null;

      try {
        lockFile = new RandomAccessFile(new File(workTokDir, LOCK_FILE_NAME), "rw");

        lock = lockFile.getChannel().lock();

        if (lock != null) processTokenDirectory(workTokDir);
        else if (log.isDebugEnabled())
          log.debug(
              "Token directory is being processed concurrently: " + workTokDir.getAbsolutePath());
      } catch (OverlappingFileLockException ignored) {
        if (log.isDebugEnabled())
          log.debug(
              "Token directory is being processed concurrently: " + workTokDir.getAbsolutePath());
      } catch (FileLockInterruptionException ignored) {
        Thread.currentThread().interrupt();
      } catch (IOException e) {
        U.error(log, "Failed to process directory: " + workTokDir.getAbsolutePath(), e);
      } finally {
        U.releaseQuiet(lock);
        U.closeQuiet(lockFile);
      }
    }
  /** {@inheritDoc} */
  @Override
  public void start() throws IgniteCheckedException {
    IpcSharedMemoryNativeLoader.load(log);

    pid = IpcSharedMemoryUtils.pid();

    if (pid == -1) throw new IpcEndpointBindException("Failed to get PID of the current process.");

    if (size <= 0) throw new IpcEndpointBindException("Space size should be positive: " + size);

    String tokDirPath = this.tokDirPath;

    if (F.isEmpty(tokDirPath)) throw new IpcEndpointBindException("Token directory path is empty.");

    tokDirPath = tokDirPath + '/' + locNodeId.toString() + '-' + IpcSharedMemoryUtils.pid();

    tokDir = U.resolveWorkDirectory(tokDirPath, false);

    if (port <= 0 || port >= 0xffff)
      throw new IpcEndpointBindException("Port value is illegal: " + port);

    try {
      srvSock = new ServerSocket();

      // Always bind to loopback.
      srvSock.bind(new InetSocketAddress("127.0.0.1", port));
    } catch (IOException e) {
      // Although empty socket constructor never throws exception, close it just in case.
      U.closeQuiet(srvSock);

      throw new IpcEndpointBindException(
          "Failed to bind shared memory IPC endpoint (is port already " + "in use?): " + port, e);
    }

    gcWorker = new GcWorker(gridName, "ipc-shmem-gc", log);

    new IgniteThread(gcWorker).start();

    if (log.isInfoEnabled())
      log.info(
          "IPC shared memory server endpoint started [port="
              + port
              + ", tokDir="
              + tokDir.getAbsolutePath()
              + ']');
  }
  /** @throws Exception if error occur. */
  @SuppressWarnings("unchecked")
  private void checkGar() throws Exception {
    initGar = true;

    String garDir = "modules/extdata/p2p/deploy";
    String garFileName = "p2p.gar";

    File origGarPath = U.resolveIgnitePath(garDir + '/' + garFileName);

    File tmpPath = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());

    if (!tmpPath.mkdir()) throw new IOException("Can not create temp directory");

    try {
      File newGarFile = new File(tmpPath, garFileName);

      U.copy(origGarPath, newGarFile, false);

      assert newGarFile.exists();

      try {
        garFile = "file:///" + tmpPath.getAbsolutePath();

        try {
          Ignite ignite1 = startGrid(1);
          Ignite ignite2 = startGrid(2);

          Integer res =
              ignite1
                  .compute()
                  .<UUID, Integer>execute(TASK_NAME, ignite2.cluster().localNode().id());

          assert res != null;
        } finally {
          stopGrid(1);
          stopGrid(2);
        }
      } finally {
        if (newGarFile != null && !newGarFile.delete()) error("Can not delete temp gar file");
      }
    } finally {
      if (!tmpPath.delete()) error("Can not delete temp directory");
    }
  }
    /** @param workTokDir Token directory (common for multiple nodes). */
    private void processTokenDirectory(File workTokDir) {
      for (File f : workTokDir.listFiles()) {
        if (!f.isDirectory()) {
          if (!f.getName().equals(LOCK_FILE_NAME)) {
            if (log.isDebugEnabled()) log.debug("Unexpected file: " + f.getName());
          }

          continue;
        }

        if (f.equals(tokDir)) {
          if (log.isDebugEnabled()) log.debug("Skipping own token directory: " + tokDir.getName());

          continue;
        }

        String name = f.getName();

        int pid;

        try {
          pid = Integer.parseInt(name.substring(name.lastIndexOf('-') + 1));
        } catch (NumberFormatException ignored) {
          if (log.isDebugEnabled()) log.debug("Failed to parse file name: " + name);

          continue;
        }

        // Is process alive?
        if (IpcSharedMemoryUtils.alive(pid)) {
          if (log.isDebugEnabled()) log.debug("Skipping alive node: " + pid);

          continue;
        }

        if (log.isDebugEnabled()) log.debug("Possibly stale token folder: " + f);

        // Process each token under stale token folder.
        File[] shmemToks = f.listFiles();

        if (shmemToks == null)
          // Although this is strange, but is reproducible sometimes on linux.
          return;

        int rmvCnt = 0;

        try {
          for (File f0 : shmemToks) {
            if (log.isDebugEnabled()) log.debug("Processing token file: " + f0.getName());

            if (f0.isDirectory()) {
              if (log.isDebugEnabled()) log.debug("Unexpected directory: " + f0.getName());
            }

            // Token file format: gg-shmem-space-[auto_idx]-[other_party_pid]-[size]
            String[] toks = f0.getName().split("-");

            if (toks.length != 6) {
              if (log.isDebugEnabled()) log.debug("Unrecognized token file: " + f0.getName());

              continue;
            }

            int pid0;
            int size;

            try {
              pid0 = Integer.parseInt(toks[4]);
              size = Integer.parseInt(toks[5]);
            } catch (NumberFormatException ignored) {
              if (log.isDebugEnabled()) log.debug("Failed to parse file name: " + name);

              continue;
            }

            if (IpcSharedMemoryUtils.alive(pid0)) {
              if (log.isDebugEnabled()) log.debug("Skipping alive process: " + pid0);

              continue;
            }

            if (log.isDebugEnabled()) log.debug("Possibly stale token file: " + f0);

            IpcSharedMemoryUtils.freeSystemResources(f0.getAbsolutePath(), size);

            if (f0.delete()) {
              if (log.isDebugEnabled()) log.debug("Deleted file: " + f0.getName());

              rmvCnt++;
            } else if (!f0.exists()) {
              if (log.isDebugEnabled())
                log.debug("File has been concurrently deleted: " + f0.getName());

              rmvCnt++;
            } else if (log.isDebugEnabled()) log.debug("Failed to delete file: " + f0.getName());
          }
        } finally {
          // Assuming that no new files can appear, since
          if (rmvCnt == shmemToks.length) {
            U.delete(f);

            if (log.isDebugEnabled()) log.debug("Deleted empty token directory: " + f.getName());
          }
        }
      }
    }