Fix missing flush in StreamCopyThread
It is possible to miss flush() invocation in StreamCopyThread. In this case some data will not be sent to remote host and we will wait forever (or until timeout) in src.read(). Use a counter to keep track of the flush requests. Change-Id: Ia818be9b109a1674d9e2a9c78e125ab248cfb75b Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
a54e0bae68
commit
3f143b8d6b
|
@ -47,6 +47,7 @@
|
||||||
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 {
|
||||||
|
@ -56,7 +57,7 @@ public class StreamCopyThread extends Thread {
|
||||||
|
|
||||||
private final OutputStream dst;
|
private final OutputStream dst;
|
||||||
|
|
||||||
private volatile boolean doFlush;
|
private final AtomicInteger flushCounter = 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.
|
||||||
|
@ -82,10 +83,8 @@ public StreamCopyThread(final InputStream i, final OutputStream o) {
|
||||||
* the request.
|
* the request.
|
||||||
*/
|
*/
|
||||||
public void flush() {
|
public void flush() {
|
||||||
if (!doFlush) {
|
flushCounter.incrementAndGet();
|
||||||
doFlush = true;
|
interrupt();
|
||||||
interrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,10 +93,8 @@ public void run() {
|
||||||
final byte[] buf = new byte[BUFFER_SIZE];
|
final byte[] buf = new byte[BUFFER_SIZE];
|
||||||
for (;;) {
|
for (;;) {
|
||||||
try {
|
try {
|
||||||
if (doFlush) {
|
if (needFlush())
|
||||||
doFlush = false;
|
|
||||||
dst.flush();
|
dst.flush();
|
||||||
}
|
|
||||||
|
|
||||||
final int n;
|
final int n;
|
||||||
try {
|
try {
|
||||||
|
@ -125,4 +122,13 @@ public void run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean needFlush() {
|
||||||
|
int i = flushCounter.get();
|
||||||
|
if (i > 0) {
|
||||||
|
flushCounter.decrementAndGet();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue