changeset 92:f4ead96961a9

2008-08-20 Omair Majid <omajid@redhat.com> * src/java/org/classpath/icedtea/pulseaudio/Operation.java (finalize): New function. (releaseReference): Set operationPointer to null. (waitForCompletion): Replaced stub with actual implementation. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioStreamVolumeControl.java (setStreamVolume): Replaced polling loop with call to waitForCompletion. (native_getOperationState): Removed obsolete function. * src/native/org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl.c (set_sink_input_volume_callback): New function. (Java_org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl_native_1setValue): Commented out debug info. Added a callback for pa_context_set_sink_input_volume. (Java_org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl_native_1getOperationState): Removed obsolete function. * unittests/org/classpath/icedtea/pulseaudio/PulseSouceDataLineTest.java (testVolumeChanging): Removed unused varaible mute.
author Omair Majid <omajid@redhat.com>
date Wed, 20 Aug 2008 11:05:00 -0400
parents 675a5044aecb
children c9268e180613
files src/java/org/classpath/icedtea/pulseaudio/Operation.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioStreamVolumeControl.java src/native/org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl.c unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java
diffstat 4 files changed, 73 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/Operation.java	Tue Aug 19 17:29:25 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/Operation.java	Wed Aug 20 11:05:00 2008 -0400
@@ -81,6 +81,13 @@
 		this.eventLoop = EventLoop.getEventLoop();
 	}
 
+	@Override
+	protected void finalize() throws Throwable {
+		// might catch operations which havent been released
+		assert (operationPointer == 0);
+		super.finalize();
+	}
+
 	public void addReference() {
 		assert (operationPointer != 0);
 		synchronized (eventLoop.threadLock) {
@@ -93,6 +100,7 @@
 		synchronized (eventLoop.threadLock) {
 			native_unref();
 		}
+		operationPointer = 0;
 	}
 
 	public boolean isNull() {
@@ -121,11 +129,21 @@
 
 	}
 
-	public void waitForCompletion() throws InterruptedException {
+	public void waitForCompletion() {
+		assert (operationPointer != 0);
+		State operationState = getState();
+		assert (operationState != State.Done);
+
+		do {
+			synchronized (eventLoop.threadLock) {
 
-		synchronized (eventLoop.threadLock) {
-			eventLoop.threadLock.wait();
-		}
+				try {
+					eventLoop.threadLock.wait();
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+		} while (getState() != State.Done);
 
 	}
 }
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioStreamVolumeControl.java	Tue Aug 19 17:29:25 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioStreamVolumeControl.java	Wed Aug 20 11:05:00 2008 -0400
@@ -47,17 +47,16 @@
 	}
 
 	protected synchronized void setStreamVolume(float newValue) {
-		int operationPointer;
-		int operationState;
+		Operation op;
 		synchronized (eventLoop.threadLock) {
-			operationPointer = native_setValue(newValue);
-			operationState = native_getOperationState(operationPointer);
+			op = new Operation(native_setValue(newValue));
 		}
-		while (operationState != 1) {
-			synchronized (eventLoop.threadLock) {
-				operationState = native_getOperationState(operationPointer);
-			}
-		}
+
+		op.waitForCompletion();
+
+		assert (op.getState() == Operation.State.Done);
+
+		op.releaseReference();
 
 	}
 
@@ -65,7 +64,5 @@
 		return line.getVolume();
 	}
 
-	private native int native_getOperationState(int operationState);
-
 	public native int native_setValue(float newValue);
 }
--- a/src/native/org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl.c	Tue Aug 19 17:29:25 2008 -0400
+++ b/src/native/org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl.c	Wed Aug 20 11:05:00 2008 -0400
@@ -41,20 +41,56 @@
 #include "jni-common.h"
 #include "org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl.h"
 
+extern JNIEnv* pulse_thread_env;
 
+static void set_sink_input_volume_callback(pa_context* context, int success,
+		void* userdata) {
 
+	JNIEnv* env = pulse_thread_env;
+
+	const char* eventLoopClassName =
+			"Lorg/classpath/icedtea/pulseaudio/EventLoop;";
+	jclass eventLoopClass = (*env)->FindClass(env, eventLoopClassName);
+	assert(eventLoopClass);
+
+	const char* getEventLoopIDSignature =
+			"()Lorg/classpath/icedtea/pulseaudio/EventLoop;";
+	jmethodID getEventLoopID = (*env)->GetStaticMethodID(env, eventLoopClass, "getEventLoop",
+			getEventLoopIDSignature);
+	assert(getEventLoopID);
+
+	jobject eventLoop = (*env)->CallStaticObjectMethod(env, eventLoopClass, getEventLoopID);
+	assert(eventLoop);
 
-JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl_native_1setValue(JNIEnv *env, jobject obj, jfloat new_volume) {
-	printf("IN NATIVE SET VOLUME\n");
+	jfieldID lockID = (*env)->GetFieldID(env, eventLoopClass, "threadLock",
+			"Ljava/lang/Object;");
+	assert(lockID);
+
+	jobject lockObject = (*env)->GetObjectField(env, eventLoop, lockID);
+	assert(lockObject);
+
+	(*env)->MonitorEnter(env, lockObject);
+
+	jclass objectClass = (*env)->FindClass(env,"Ljava/lang/Object;");
+	assert(objectClass);
+	jmethodID notifyAllID = (*env)->GetMethodID(env, objectClass, "notifyAll", "()V");
+	assert(notifyAllID);
+
+	(*env)->CallObjectMethod(env, lockObject, notifyAllID);
+
+	(*env)->MonitorExit(env, lockObject);
+
+}
+
+JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl_native_1setValue
+(JNIEnv *env, jobject obj, jfloat new_volume) {
+	//	printf("IN NATIVE SET VOLUME\n");
 	pa_stream *stream = getJavaPointer(env, obj, "streamPointer");
-	printf("STREAM POINTER %d", (int) stream);
+	//	printf("STREAM POINTER %d", (int) stream);
 	pa_context *context = pa_stream_get_context(stream);
 	int stream_id = pa_stream_get_index(stream);
 	int channels = pa_stream_get_sample_spec(stream)->channels;
 	pa_cvolume cv;
-	return  (jint) pa_context_set_sink_input_volume(context, stream_id, pa_cvolume_set(&cv, channels, new_volume), NULL, NULL);
+	return (jint) pa_context_set_sink_input_volume(context, stream_id, pa_cvolume_set(&cv, channels, new_volume), set_sink_input_volume_callback, NULL);
 }
 
-JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioStreamVolumeControl_native_1getOperationState(JNIEnv *env, jobject obj, jint operation) {
-	return pa_operation_get_state((pa_operation *) operation);
-}
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java	Tue Aug 19 17:29:25 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseSourceDataLineTest.java	Wed Aug 20 11:05:00 2008 -0400
@@ -244,8 +244,6 @@
 		line.start();
 		PulseAudioStreamVolumeControl volume = (PulseAudioStreamVolumeControl) line
 				.getControl(FloatControl.Type.VOLUME);
-		PulseAudioStreamMuteControl mute = (PulseAudioStreamMuteControl) line
-				.getControl(BooleanControl.Type.MUTE);
 
 		volume.setValue(PulseAudioStreamVolumeControl.MIN_VOLUME);