diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java index d73e2055a..8df3ea5b2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java @@ -232,7 +232,7 @@ public void close() throws IOException { class SshFetchConnection extends BasePackFetchConnection { private ChannelExec channel; - private Thread errorThread; + private StreamCopyThread errorThread; private int exitStatus; @@ -275,7 +275,7 @@ public void close() { if (errorThread != null) { try { - errorThread.join(); + errorThread.halt(); } catch (InterruptedException e) { // Stop waiting and return anyway. } finally { @@ -300,7 +300,7 @@ public void close() { class SshPushConnection extends BasePackPushConnection { private ChannelExec channel; - private Thread errorThread; + private StreamCopyThread errorThread; private int exitStatus; @@ -343,7 +343,7 @@ public void close() { if (errorThread != null) { try { - errorThread.join(); + errorThread.halt(); } catch (InterruptedException e) { // Stop waiting and return anyway. } finally { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java index c36835692..f2715aca2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java @@ -59,6 +59,8 @@ public class StreamCopyThread extends Thread { private final AtomicInteger flushCounter = new AtomicInteger(0); + private volatile boolean done; + /** * Create a thread to copy data from an input stream to an output stream. * @@ -87,6 +89,26 @@ public void flush() { interrupt(); } + /** + * Request that the thread terminate, and wait for it. + *

+ * This method signals to the copy thread that it should stop as soon as + * there is no more IO occurring. + * + * @throws InterruptedException + * the calling thread was interrupted. + */ + public void halt() throws InterruptedException { + for (;;) { + join(250 /* milliseconds */); + if (isAlive()) { + done = true; + interrupt(); + } else + break; + } + } + @Override public void run() { try { @@ -96,6 +118,9 @@ public void run() { if (needFlush()) dst.flush(); + if (done) + break; + final int n; try { n = src.read(buf);