Remove unused field

Use atomics to manage closed state and IOExceptions
This commit is contained in:
zab2
2013-07-05 19:48:31 +00:00
parent 7f8efca0ba
commit bec62c1be7

View File

@@ -3,6 +3,8 @@ package net.i2p.client.streaming;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import net.i2p.I2PAppContext;
import net.i2p.data.ByteArray;
@@ -24,13 +26,12 @@ class MessageOutputStream extends OutputStream {
private int _valid;
private final Object _dataLock;
private final DataReceiver _dataReceiver;
private IOException _streamError;
private volatile boolean _closed;
private final AtomicReference<IOException>_streamError = new AtomicReference<IOException>(null);
private final AtomicBoolean _closed = new AtomicBoolean(false);
private long _written;
private int _writeTimeout;
private ByteCache _dataCache;
private final Flusher _flusher;
private long _lastFlushed;
private volatile long _lastBuffered;
/** if we enqueue data but don't flush it in this period, flush it passively */
private final int _passiveFlushDelay;
@@ -98,7 +99,7 @@ class MessageOutputStream extends OutputStream {
@Override
public void write(byte b[], int off, int len) throws IOException {
if (_closed) throw new IOException("Already closed");
if (_closed.get()) throw new IOException("Already closed");
if (_log.shouldLog(Log.DEBUG))
_log.debug("write(b[], " + off + ", " + len + ") ");
int cur = off;
@@ -106,7 +107,7 @@ class MessageOutputStream extends OutputStream {
long begin = _context.clock().now();
while (remaining > 0) {
WriteStatus ws = null;
if (_closed) throw new IOException("closed underneath us");
if (_closed.get()) throw new IOException("closed underneath us");
// we do any waiting outside the synchronized() block because we
// want to allow other threads to flushAvailable() whenever they want.
// this is the only method that *adds* to the _buf, and all
@@ -139,7 +140,6 @@ class MessageOutputStream extends OutputStream {
_written += _valid;
_valid = 0;
throwAnyError();
_lastFlushed = _context.clock().now();
locked_updateBufferSize();
}
@@ -239,7 +239,7 @@ class MessageOutputStream extends OutputStream {
_enqueued = true;
}
public void timeReached() {
if (_closed)
if (_closed.get())
return;
_enqueued = false;
long timeLeft = (_lastBuffered + _passiveFlushDelay - _context.clock().now());
@@ -265,7 +265,6 @@ class MessageOutputStream extends OutputStream {
ws = _dataReceiver.writeData(_buf, 0, _valid);
_written += _valid;
_valid = 0;
_lastFlushed = _context.clock().now();
locked_updateBufferSize();
_dataLock.notifyAll();
sent = true;
@@ -330,7 +329,6 @@ class MessageOutputStream extends OutputStream {
_written += _valid;
_valid = 0;
locked_updateBufferSize();
_lastFlushed = _context.clock().now();
_dataLock.notifyAll();
}
}
@@ -345,7 +343,7 @@ class MessageOutputStream extends OutputStream {
// Wait a loooooong time, until we have the ACK
if (_log.shouldLog(Log.DEBUG))
_log.debug("before waiting " + _writeTimeout + "ms for completion of " + ws);
if (_closed &&
if (_closed.get() &&
( (_writeTimeout > Connection.DISCONNECT_TIMEOUT) ||
(_writeTimeout <= 0) ) )
ws.waitForCompletion(Connection.DISCONNECT_TIMEOUT);
@@ -372,12 +370,12 @@ class MessageOutputStream extends OutputStream {
*/
@Override
public void close() throws IOException {
if (_closed) {
if (!_closed.compareAndSet(false,true)) {
synchronized (_dataLock) { _dataLock.notifyAll(); }
LogUtil.logCloseLoop(_log, "MOS");
return;
}
// setting _closed before flush() will force flush() to send a CLOSE packet
_closed = true;
_flusher.cancel();
// In 0.8.1 we rewrote flush() to only wait for accept into the window,
@@ -411,10 +409,12 @@ class MessageOutputStream extends OutputStream {
* Only for use inside package
*/
public void closeInternal() {
_closed = true;
if (!_closed.compareAndSet(false,true)) {
LogUtil.logCloseLoop(_log, "close internal");
return;
}
_flusher.cancel();
if (_streamError == null)
_streamError = new IOException("Closed internally");
_streamError.compareAndSet(null,new IOException("Closed internally"));
clearData(true);
}
@@ -435,7 +435,6 @@ class MessageOutputStream extends OutputStream {
_buf = null;
_valid = 0;
}
_lastFlushed = _context.clock().now();
_dataLock.notifyAll();
}
if (ba != null) {
@@ -443,12 +442,11 @@ class MessageOutputStream extends OutputStream {
}
}
public boolean getClosed() { return _closed; }
public boolean getClosed() { return _closed.get(); }
private void throwAnyError() throws IOException {
IOException ioe = _streamError;
IOException ioe = _streamError.getAndSet(null);
if (ioe != null) {
_streamError = null;
// constructor with cause not until Java 6
IOException ioe2 = new IOException("Output stream error");
ioe2.initCause(ioe);
@@ -457,8 +455,7 @@ class MessageOutputStream extends OutputStream {
}
void streamErrorOccurred(IOException ioe) {
if (_streamError == null)
_streamError = ioe;
_streamError.compareAndSet(null,ioe);
clearData(false);
}
@@ -484,7 +481,6 @@ class MessageOutputStream extends OutputStream {
_valid = 0;
locked_updateBufferSize();
_dataLock.notifyAll();
_lastFlushed = _context.clock().now();
}
long afterBuild = System.currentTimeMillis();
if ( (afterBuild - before > 1000) && (_log.shouldLog(Log.DEBUG)) )
@@ -504,7 +500,10 @@ class MessageOutputStream extends OutputStream {
}
void destroy() {
_closed = true;
if (!_closed.compareAndSet(false,true)) {
LogUtil.logCloseLoop(_log, "destroy()");
return;
}
_flusher.cancel();
synchronized (_dataLock) {
_dataLock.notifyAll();