changeset 2305:77a59d9a4ce5

Eliminate spurious exception throwing in PulseAudio provider. 2010-07-12 Jon VanAlten <jon.vanalten@redhat.com> * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java: Eliminate spurious exception throwing from open, close, read, write, drain, and flush calls on closed lines. Use isOpen() API call instead of instance variable where appropriate.
author Jon VanAlten <jon.vanalten@redhat.com>
date Mon, 12 Jul 2010 11:13:35 -0400
parents 2d3c4a7208ec
children b7ee63785b8d
files ChangeLog pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java
diffstat 5 files changed, 77 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jul 08 15:54:35 2010 -0400
+++ b/ChangeLog	Mon Jul 12 11:13:35 2010 -0400
@@ -1,3 +1,12 @@
+2010-07-12 Jon VanAlten <jon.vanalten@redhat.com>
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java:
+	Eliminate spurious exception throwing from open, close, read, write,
+	drain, and flush calls on closed lines.
+	Use isOpen() API call instead of instance variable where appropriate.
+
 2010-07-08  Man Lung Wong  <mwong@redhat.com>
 
     * netx/net/sourceforge/jnlp/Parser.java:
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Thu Jul 08 15:54:35 2010 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Mon Jul 12 11:13:35 2010 -0400
@@ -86,7 +86,7 @@
 	protected void open(AudioFormat format, int bufferSize)
 			throws LineUnavailableException {
 
-		if (isOpen) {
+		if (isOpen()) {
 			throw new IllegalStateException("Line is already open");
 		}
 
@@ -139,7 +139,7 @@
 			}
 		}
 
-		if (!isOpen) {
+		if (!isOpen()) {
 			throw new IllegalArgumentException("Invalid format");
 		}
 
@@ -299,9 +299,10 @@
 	@Override
 	public void close() {
 
-		if (!isOpen) {
-			throw new IllegalStateException(
-					"Line must be open for close() to work");
+		if (!isOpen()) {
+			// For whatever reason, we are being asked to close
+			// a line that is not even open.
+			return;
 		}
 
 		synchronized (eventLoop.threadLock) {
@@ -346,7 +347,7 @@
 
 	@Override
 	public void start() {
-		if (!isOpen) {
+		if (!isOpen()) {
 			throw new IllegalStateException(
 					"Line must be open()ed before it can be start()ed");
 		}
@@ -376,10 +377,10 @@
 
 	@Override
 	public synchronized void stop() {
-		if (!isOpen) {
-			throw new IllegalStateException(
-					"Line must be open()ed before it can be start()ed");
-
+		if (!isOpen()) {
+			// For some reason, we are being asked to stop a line
+			// that isn't even open.
+			return;
 		}
 		writeInterrupted = true;
 		if (!isStarted) {
@@ -433,7 +434,7 @@
 			throws LineUnavailableException;
 
 	public Stream getStream() {
-		if (!isOpen) {
+		if (!isOpen()) {
 			throw new IllegalStateException("Line must be open");
 		}
 
@@ -442,7 +443,7 @@
 
 	@Override
 	public int getBufferSize() {
-		if (!isOpen) {
+		if (!isOpen()) {
 			return DEFAULT_BUFFER_SIZE;
 		}
 		return bufferSize;
@@ -450,7 +451,7 @@
 
 	@Override
 	public AudioFormat getFormat() {
-		if (!isOpen) {
+		if (!isOpen()) {
 			return defaultFormat;
 		}
 		return currentFormat;
@@ -467,7 +468,7 @@
 	 *            the name of this audio stream
 	 */
 	public void setName(String streamName) {
-		if (isOpen) {
+		if (isOpen()) {
 
 			Operation o;
 			synchronized (eventLoop.threadLock) {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java	Thu Jul 08 15:54:35 2010 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java	Mon Jul 12 11:13:35 2010 -0400
@@ -62,7 +62,7 @@
 
 	@Override
 	public void close() {
-		if (!isOpen) {
+		if (!isOpen()) {
 			throw new IllegalStateException("Line is not open");
 		}
 
@@ -79,7 +79,7 @@
 
 	@Override
 	public Control getControl(Type control) {
-		if (isOpen) {
+		if (isOpen()) {
 			for (Control aControl : controls) {
 				if (aControl.getType() == control) {
 					return aControl;
@@ -92,7 +92,7 @@
 
 	@Override
 	public Control[] getControls() {
-		if (!isOpen) {
+		if (!isOpen()) {
 			return new Control[] {};
 		}
 
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Thu Jul 08 15:54:35 2010 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Mon Jul 12 11:13:35 2010 -0400
@@ -142,8 +142,9 @@
 			writeInterrupted = false;
 		}
 
-		if (!isOpen) {
-			throw new IllegalStateException("must call open() before write()");
+		if (!isOpen()) {
+			// A closed line can write exactly 0 bytes.
+			return 0;
 		}
 
 		int frameSize = currentFormat.getFrameSize();
@@ -259,11 +260,6 @@
 
 	@Override
 	public void drain() {
-		if (!isOpen) {
-			throw new IllegalStateException(
-					"Line must be open before it can be drain()ed");
-
-		}
 
 		synchronized (this) {
 			writeInterrupted = true;
@@ -271,13 +267,13 @@
 
 		do {
 			synchronized (this) {
-				if (!isOpen) {
+				if (!isOpen()) {
 					return;
 				}
 				if (getBytesInBuffer() == 0) {
 					return;
 				}
-				if (isStarted || !isOpen) {
+				if (isStarted) {
 					break;
 				}
 				try {
@@ -301,29 +297,27 @@
 
 	@Override
 	public void flush() {
-		if (!isOpen) {
-			throw new IllegalStateException(
-					"Line must be open before it can be flush()ed");
-		}
 		synchronized (this) {
 			writeInterrupted = true;
 		}
 
-		Operation operation;
-		synchronized (eventLoop.threadLock) {
-			operation = stream.flush();
+		if (isOpen()) {
+			Operation operation;
+			synchronized (eventLoop.threadLock) {
+				operation = stream.flush();
+			}
+
+			operation.waitForCompletion();
+			operation.releaseReference();
 		}
 
-		operation.waitForCompletion();
-		operation.releaseReference();
-
 	}
 
 	@Override
 	synchronized public void close() {
 
-		if (!isOpen) {
-			throw new IllegalStateException("not open so cant close");
+		if (!isOpen()) {
+			return;
 		}
 
 		writeInterrupted = true;
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java	Thu Jul 08 15:54:35 2010 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java	Mon Jul 12 11:13:35 2010 -0400
@@ -76,15 +76,19 @@
 
 	@Override
 	synchronized public void close() {
+		if (!isOpen()) {
+			// Probably due to some programmer error, we are being
+			// asked to close an already closed line.  Oh well.
+			Debug.println(DebugLevel.Verbose,
+					"PulseAudioTargetDataLine.close(): "
+					+ "Line closed that wasn't open.");
+			return;
+		}
+
 		/* check for permission to record audio */
 		AudioPermission perm = new AudioPermission("record", null);
 		perm.checkGuard(null);
 
-		if (!isOpen) {
-			throw new IllegalStateException(
-					"Line cant be closed if it isnt open");
-		}
-
 		PulseAudioMixer parentMixer = PulseAudioMixer.getInstance();
 		parentMixer.removeTargetLine(this);
 
@@ -101,7 +105,7 @@
 		AudioPermission perm = new AudioPermission("record", null);
 		perm.checkGuard(null);
 
-		if (isOpen) {
+		if (isOpen()) {
 			throw new IllegalStateException("already open");
 		}
 		super.open(format, bufferSize);
@@ -142,8 +146,9 @@
 
 		/* check state and inputs */
 
-		if (!isOpen) {
-			throw new IllegalStateException("must call open() before read()");
+		if (!isOpen()) {
+			// A closed line can produce zero bytes of data.
+			return 0;
 		}
 
 		int frameSize = currentFormat.getFrameSize();
@@ -220,7 +225,7 @@
 		while (remainingLength != 0) {
 			synchronized (this) {
 
-				if (!isOpen || !isStarted) {
+				if (!isOpen() || !isStarted) {
 					return sizeRead;
 				}
 
@@ -287,57 +292,57 @@
 	@Override
 	public void drain() {
 
-		if (!isOpen) {
-			throw new IllegalStateException("must call open() before drain()");
-		}
-
-		synchronized (this) {
-			drained = true;
-		}
-
 		// blocks when there is data on the line
 		// http://www.jsresources.org/faq_audio.html#stop_drain_tdl
 		while (true) {
 			synchronized (this) {
-				if (!isStarted || !isOpen) {
+				if (!isStarted || !isOpen()) {
 					break;
 				}
 			}
 			try {
+				//TODO: Is this the best length of sleep?
+				//Maybe in case this loop runs for a long time
+				//it would be good to switch to a longer
+				//sleep.  Like bump it up each iteration after
+				//the Nth iteration, up to a MAXSLEEP length.
 				Thread.sleep(100);
 			} catch (InterruptedException e) {
 				// do nothing
 			}
 		}
 
+		synchronized (this) {
+			drained = true;
+		}
+
 	}
 
 	@Override
 	public void flush() {
-		if (!isOpen) {
-			throw new IllegalStateException("Line must be open");
-		}
+		if (isOpen()) {
 
-		/* flush the buffer on pulseaudio's side */
-		Operation operation;
-		synchronized (eventLoop.threadLock) {
-			operation = stream.flush();
+			/* flush the buffer on pulseaudio's side */
+			Operation operation;
+			synchronized (eventLoop.threadLock) {
+				operation = stream.flush();
+			}
+			operation.waitForCompletion();
+			operation.releaseReference();
 		}
-		operation.waitForCompletion();
-		operation.releaseReference();
 
 		synchronized (this) {
 			flushed = true;
 			/* flush the partial fragment we stored */
 			fragmentBuffer = null;
 		}
-
 	}
 
 	@Override
 	public int available() {
-		if (!isOpen) {
-			throw new IllegalStateException("Line must be open");
+		if (!isOpen()) {
+			// a closed line has 0 bytes available.
+			return 0;
 		}
 
 		synchronized (eventLoop.threadLock) {