Paul Martin
2016-04-27 c2188a840bc4153ae92112b04b2e06a90d3944aa
src/main/java/com/gitblit/transport/ssh/commands/SshCommandFactory.java
@@ -1,4 +1,5 @@
/*
 * Copyright (C) 2009 The Android Open Source Project
 * Copyright 2014 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,6 +21,8 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -34,33 +37,40 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.Keys;
import com.gitblit.manager.IGitblit;
import com.gitblit.transport.ssh.SshDaemonClient;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.WorkQueue;
import com.google.common.util.concurrent.Atomics;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
 *
 * @author Eric Myhre
 *
 */
public class SshCommandFactory implements CommandFactory {
   private static final Logger logger = LoggerFactory.getLogger(SshCommandFactory.class);
   private final WorkQueue workQueue;
   private final IGitblit gitblit;
   private final ScheduledExecutorService startExecutor;
   private final ExecutorService destroyExecutor;
   public SshCommandFactory(IGitblit gitblit, IdGenerator idGenerator) {
   public SshCommandFactory(IGitblit gitblit, WorkQueue workQueue) {
      this.gitblit = gitblit;
      this.workQueue = workQueue;
      int threads = 2;// cfg.getInt("sshd","commandStartThreads", 2);
      WorkQueue workQueue = new WorkQueue(idGenerator);
      int threads = gitblit.getSettings().getInteger(Keys.git.sshCommandStartThreads, 2);
      startExecutor = workQueue.createQueue(threads, "SshCommandStart");
      destroyExecutor = Executors.newSingleThreadExecutor(
            new ThreadFactoryBuilder()
               .setNameFormat("SshCommandDestroy-%s")
               .setDaemon(true)
               .build());
   }
   public void stop() {
      destroyExecutor.shutdownNow();
   }
   public RootDispatcher createRootDispatcher(SshDaemonClient client, String commandLine) {
      return new RootDispatcher(gitblit, client, commandLine);
      return new RootDispatcher(gitblit, client, commandLine, workQueue);
   }
   @Override
@@ -166,27 +176,23 @@
      }
      private int translateExit(final int rc) {
         return rc;
         //
         // switch (rc) {
         // case BaseCommand.STATUS_NOT_ADMIN:
         // return 1;
         //
         // case BaseCommand.STATUS_CANCEL:
         // return 15 /* SIGKILL */;
         //
         // case BaseCommand.STATUS_NOT_FOUND:
         // return 127 /* POSIX not found */;
         //
         // default:
         // return rc;
         // }
         switch (rc) {
         case BaseCommand.STATUS_NOT_ADMIN:
            return 1;
         case BaseCommand.STATUS_CANCEL:
            return 15 /* SIGKILL */;
         case BaseCommand.STATUS_NOT_FOUND:
            return 127 /* POSIX not found */;
         default:
            return rc;
         }
      }
      private void log(final int rc) {
         if (logged.compareAndSet(false, true)) {
            // log.onExecute(cmd, rc);
            logger.info("onExecute: {} exits with: {}", cmd.getClass().getSimpleName(), rc);
         }
      }
@@ -196,27 +202,22 @@
         Future<?> future = task.getAndSet(null);
         if (future != null) {
            future.cancel(true);
            // destroyExecutor.execute(new Runnable() {
            // @Override
            // public void run() {
            // onDestroy();
            // }
            // });
            destroyExecutor.execute(new Runnable() {
               @Override
               public void run() {
                  onDestroy();
               }
            });
         }
      }
      @SuppressWarnings("unused")
      private void onDestroy() {
         synchronized (this) {
            if (cmd != null) {
               // final Context old = sshScope.set(ctx);
               try {
                  cmd.destroy();
                  // log(BaseCommand.STATUS_CANCEL);
               } finally {
                  // ctx = null;
                  cmd = null;
                  // sshScope.set(old);
               }
            }
         }