Merge "Define PluginCommandModule for plugins"
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
index 81b4f14..68436ca 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
@@ -437,16 +437,10 @@
         public void onClick(final ClickEvent event) {
           b.setEnabled(false);
           Util.MANAGE_SVC.submit(patchSet.getId(),
-              new GerritCallback<ChangeDetail>() {
+              new ChangeDetailCache.GerritWidgetCallback(b) {
                 public void onSuccess(ChangeDetail result) {
                   onSubmitResult(result);
                 }
-
-                @Override
-                public void onFailure(Throwable caught) {
-                  b.setEnabled(true);
-                  super.onFailure(caught);
-                }
               });
         }
       });
@@ -611,17 +605,7 @@
       public void onClick(final ClickEvent event) {
         b.setEnabled(false);
         Util.MANAGE_SVC.publish(patchSet.getId(),
-            new GerritCallback<ChangeDetail>() {
-              public void onSuccess(ChangeDetail result) {
-                detailCache.set(result);
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                b.setEnabled(true);
-                super.onFailure(caught);
-              }
-            });
+            new ChangeDetailCache.GerritWidgetCallback(b));
       }
     });
     actionsPanel.add(b);
@@ -634,7 +618,7 @@
       public void onClick(final ClickEvent event) {
         b.setEnabled(false);
         PatchUtil.DETAIL_SVC.deleteDraftPatchSet(patchSet.getId(),
-            new GerritCallback<ChangeDetail>() {
+            new ChangeDetailCache.GerritWidgetCallback(b) {
               public void onSuccess(final ChangeDetail result) {
                 if (result != null) {
                   detailCache.set(result);
@@ -642,12 +626,6 @@
                   Gerrit.display(PageLinks.MINE);
                 }
               }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                b.setEnabled(true);
-                super.onFailure(caught);
-              }
             });
       }
     });
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SuExec.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SuExec.java
index 492966e..b4c59a8 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SuExec.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SuExec.java
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.sshd;
 
+import com.google.common.util.concurrent.Atomics;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.AccessPath;
 import com.google.gerrit.server.CurrentUser;
@@ -32,6 +33,7 @@
 import java.net.SocketAddress;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Executes any other command as a different user identity.
@@ -57,7 +59,7 @@
   @Argument(index = 0, multiValued = true, metaVar = "COMMAND")
   private List<String> args = new ArrayList<String>();
 
-  private Command cmd;
+  private final AtomicReference<Command> atomicCmd;
 
   @Inject
   SuExec(@CommandName(Commands.ROOT) final DispatchCommandProvider dispatcher,
@@ -69,6 +71,7 @@
     this.session = session;
     this.userFactory = userFactory;
     this.callingContext = callingContext;
+    atomicCmd = Atomics.newReference();
   }
 
   @Override
@@ -83,10 +86,7 @@
           final BaseCommand cmd = dispatcher.get();
           cmd.setArguments(args.toArray(new String[args.size()]));
           provideStateTo(cmd);
-
-          synchronized (this) {
-            this.cmd = cmd;
-          }
+          atomicCmd.set(cmd);
           cmd.start(env);
         } finally {
           SshScope.set(old);
@@ -136,11 +136,9 @@
 
   @Override
   public void destroy() {
-    synchronized (this) {
-      if (cmd != null) {
+    Command cmd = atomicCmd.getAndSet(null);
+    if (cmd != null) {
         cmd.destroy();
-        cmd = null;
-      }
     }
   }
 }