Author: bdonlan
Date: 2005-05-22 02:07:35 -0400 (Sun, 22 May 2005)
New Revision: 707
Modified:
trunk/clients/Javer2/src/haver/Client.java
trunk/clients/Javer2/src/haver/NonblockingOutputStream.java
Log:
src/haver/NonblockingOutputStream.java, src/haver/Client.java:
* documentation
Modified: trunk/clients/Javer2/src/haver/Client.java
===================================================================
--- trunk/clients/Javer2/src/haver/Client.java 2005-05-22 05:36:50 UTC (rev
706)
+++ trunk/clients/Javer2/src/haver/Client.java 2005-05-22 06:07:35 UTC (rev
707)
@@ -31,6 +31,9 @@
String host;
int port;
+ /**
+ * Mutable boolean flag
+ */
class Flag {
public boolean ok = true;
}
Modified: trunk/clients/Javer2/src/haver/NonblockingOutputStream.java
===================================================================
--- trunk/clients/Javer2/src/haver/NonblockingOutputStream.java 2005-05-22
05:36:50 UTC (rev 706)
+++ trunk/clients/Javer2/src/haver/NonblockingOutputStream.java 2005-05-22
06:07:35 UTC (rev 707)
@@ -9,21 +9,67 @@
import java.util.*;
/**
- *
+ * A wrapper over OutputStream to prevent any methods from blocking, by using a
+ * worker thread to drive the inner stream.
* @author bdonlan
*/
public class NonblockingOutputStream extends java.io.FilterOutputStream
implements Runnable {
-
- protected Vector preflush, pending;
+
+ /**
+ * Pending data for after the flush
+ */
+ protected Vector preflush;
+
+ /**
+ * If a flush is pending, all data included in that flush and not yet
owned by the
+ * worker thread. If no flush is pending, all data.
+ */
+ protected Vector pending;
+ /**
+ * Length of data currently owned by the write thread, in bytes
+ */
protected long active_len;
+ /**
+ * Length of data in the pending vector, in bytes
+ */
protected long pending_len;
+ /**
+ * Length of data in the preflush vector, in bytes
+ */
protected long preflush_len;
- protected boolean flushing, closing, autoflush;
+
+ /**
+ * A manual flush is pending
+ */
+ protected boolean flushing;
+
+ /**
+ * The writer is in the process of closing
+ */
+ protected boolean closing;
+
+ /**
+ * Whether autoflush is enabled.
+ */
+ protected boolean autoflush;
+ /**
+ * The pending write exception, if any
+ */
protected IOException pending_exception = null;
+ /**
+ * The worker thread
+ */
protected Thread th;
+ /**
+ * The wrapped output stream
+ */
protected OutputStream out;
+ /**
+ * Create a new instance of NonblockingOutputStream
+ * @param out OutputStream to wrap
+ */
public NonblockingOutputStream(OutputStream out) {
super(out);
this.out = out;
@@ -35,6 +81,9 @@
th.start();
}
+ /**
+ * Worker thread entry point
+ */
public void run() {
if (Thread.currentThread() != th)
throw new IllegalStateException("run() must be executed from
within " +
@@ -94,7 +143,13 @@
}
}
}
-
+
+ /**
+ * Writes <code>b.length</code> bytes to this output stream.
+ *
+ * @param b the data to be written.
+ * @exception IOException if an I/O error occurs.
+ */
public void write(byte[] b) throws IOException {
if (b.length == 0)
return;
@@ -113,7 +168,20 @@
dump();
}
}
-
+
+ /**
+ * Closes this output stream and releases any system resources
+ * associated with the stream.
+ * <p>
+ * This method returns immediately. After it returns no more methods of
this
+ * instance may be called. Any pending data will be written to the
+ * underlying <code>OutputStream</code> before the worker thread is shut
+ * down.
+ *
+ * @exception IOException if an I/O error occurs.
+ * @see java.io.FilterOutputStream#flush()
+ * @see java.io.FilterOutputStream#out
+ */
public void close() throws IOException {
synchronized(th) {
if (pending_exception != null)
@@ -124,6 +192,15 @@
}
}
+ /**
+ * Flushes this output stream and forces any buffered output bytes
+ * to be written out to the stream.
+ * <p>
+ * This method returns immediately, without waiting for the flush to
+ * complete.
+ *
+ * @exception IOException if an I/O error occurs.
+ */
public void flush() throws IOException {
synchronized(th) {
if (pending_exception != null)
@@ -141,18 +218,22 @@
dump();
}
}
-
+
/**
- * Getter for property autoFlush.
- * @return Value of property autoFlush.
+ * Returns whether the underlying <code>OutputStream</code> will be
flushed when
+ * pending data runs out.
+ * @return Whether the underlying <code>OutputStream</code> will be
flushed when pending
+ * data runs out.
*/
public boolean isAutoFlush() {
return autoflush;
}
/**
- * Setter for property autoFlush.
- * @param autoFlush New value of property autoFlush.
+ * Sets whether the underlying <code>OutputStream</code> should be flushed
+ * whenever pending data runs out.
+ * @param autoFlush Whether the underlying <code>OutputStream</code>
should be flushed when pending
+ * data runs out.
*/
public void setAutoFlush(boolean autoFlush) {
synchronized (th) {
@@ -180,12 +261,29 @@
*/
}
+ /**
+ * Writes the specified <code>byte</code> to this output stream.
+ *
+ * @param b the <code>byte</code>.
+ * @exception IOException if an I/O error occurs.
+ */
+
public void write(int b) throws IOException {
byte[] a = new byte[1];
a[0] = (byte) b;
write(a);
}
-
+
+ /**
+ * Writes <code>len</code> bytes from the specified
+ * <code>byte</code> array starting at offset <code>off</code> to
+ * this output stream.
+ *
+ * @param b the data.
+ * @param off the start offset in the data.
+ * @param len the number of bytes to write.
+ * @exception IOException if an I/O error occurs.
+ */
public void write(byte[] b, int off, int len) throws IOException {
if (len == 0)
return;
@@ -199,4 +297,5 @@
buffer[i] = b[off + i];
write(buffer);
}
+
}