Browse Source

Merge "Fix hanging fetch via SSH"

tags/v4.2.0.201601211800-r
Shawn Pearce 8 years ago
parent
commit
80edcac06f

+ 17
- 5
org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java View File

import java.io.InputStream; import java.io.InputStream;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicInteger;


/** Thread to copy from an input stream to an output stream. */ /** Thread to copy from an input stream to an output stream. */
public class StreamCopyThread extends Thread { public class StreamCopyThread extends Thread {


private volatile boolean done; private volatile boolean done;


private final AtomicInteger flushCount = new AtomicInteger(0);

/** /**
* Create a thread to copy data from an input stream to an output stream. * Create a thread to copy data from an input stream to an output stream.
* *
* the request. * the request.
*/ */
public void flush() { public void flush() {
flushCount.incrementAndGet();
interrupt(); interrupt();
} }


public void run() { public void run() {
try { try {
final byte[] buf = new byte[BUFFER_SIZE]; final byte[] buf = new byte[BUFFER_SIZE];
int interruptCounter = 0;
int flushCountBeforeRead = 0;
boolean readInterrupted = false;
for (;;) { for (;;) {
try { try {
if (interruptCounter > 0) {
if (readInterrupted) {
dst.flush(); dst.flush();
interruptCounter--;
readInterrupted = false;
if (!flushCount.compareAndSet(flushCountBeforeRead, 0)) {
// There was a flush() call since last blocked read.
// Set interrupt status, so next blocked read will throw
// an InterruptedIOException and we will flush again.
interrupt();
}
} }


if (done) if (done)
break; break;


flushCountBeforeRead = flushCount.get();
final int n; final int n;
try { try {
n = src.read(buf); n = src.read(buf);
} catch (InterruptedIOException wakey) { } catch (InterruptedIOException wakey) {
interruptCounter++;
readInterrupted = true;
continue; continue;
} }
if (n < 0) if (n < 0)


// set interrupt status, which will be checked // set interrupt status, which will be checked
// when we block in src.read // when we block in src.read
if (writeInterrupted)
if (writeInterrupted || flushCount.get() > 0)
interrupt(); interrupt();
break; break;
} }

Loading…
Cancel
Save