changeset 2619:7f9a42012be7

PR1050: Stream objects not garbage collected 2012-06-28 Omair Majid <omajid@redhat.com> * NEWS: Update with fix. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java: Add new member variable contextPointer. * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1new): Save j_context as contextPointer. (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1unref): Delete the global ref and dellocate the java context. (cork_callback): Don't check userdata. It is NULL. (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1cork): Dont allocate and pass a java_context to pa_stream_cork. It is not needed. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java (testOpenCloseLotsOfTimes): New method.
author Omair Majid <omajid@redhat.com>
date Thu, 28 Jun 2012 13:27:42 -0400
parents fa76bb3356e5
children 1364a03b0f2b
files ChangeLog pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java
diffstat 4 files changed, 44 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jun 10 17:42:18 2011 -0400
+++ b/ChangeLog	Thu Jun 28 13:27:42 2012 -0400
@@ -1,3 +1,19 @@
+2012-06-28  Omair Majid  <omajid@redhat.com>
+
+	PR1050: Stream objects not garbage collected
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java:
+	Add new member variable contextPointer.
+	* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1new):
+	Save j_context as contextPointer.
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1unref):
+	Delete the global ref and dellocate the java context.
+	(cork_callback): Don't check userdata. It is NULL.
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1cork):
+	Dont allocate and pass a java_context to pa_stream_cork. It is not needed.
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java
+	(testOpenCloseLotsOfTimes): New method.
+
 2011-06-10  Denis Lila  <dlila@redhat.com>
 
 	* pulseaudio/*: Fix whitespace.
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Fri Jun 10 17:42:18 2011 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Thu Jun 28 13:27:42 2012 -0400
@@ -108,7 +108,10 @@
 
     public static final String DEFAULT_DEVICE = null;
 
+    // stores a pointer to pa_stream
     private byte[] streamPointer;
+    // stores a pointer to the java_context/this object for callbacks
+    private byte[] contextPointer;
 
     static {
         SecurityWrapper.loadNativeLibrary();
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Fri Jun 10 17:42:18 2011 -0400
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Thu Jun 28 13:27:42 2012 -0400
@@ -256,6 +256,8 @@
     j_context->env = env;
     j_context->obj = (*env)->NewGlobalRef(env, obj);
 
+    setJavaPointer(env, obj, CONTEXT_POINTER, j_context);
+
     pa_context* context = convertJavaPointerToNative(env, contextPointer);
     assert(context);
 
@@ -295,7 +297,7 @@
         (*env)->ReleaseStringUTFChars(env, nameString,name);
     }
 
-    setJavaPointer(env, obj, "streamPointer", stream);
+    setJavaPointer(env, obj, STREAM_POINTER, stream);
 
     /*
      *
@@ -323,10 +325,17 @@
  */
 JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1unref
 (JNIEnv* env, jobject obj) {
+
+    java_context* j_context = getJavaPointer(env, obj, CONTEXT_POINTER);
+    assert(j_context);
+    (*env)->DeleteGlobalRef(env, j_context->obj);
+    free(j_context);
+    setJavaPointer(env, obj, CONTEXT_POINTER, NULL);
+
     pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER);
     assert(stream);
     pa_stream_unref(stream);
-    setJavaPointer(env, obj, "streamPointer", NULL);
+    setJavaPointer(env, obj, STREAM_POINTER, NULL);
 }
 
 /*
@@ -656,9 +665,7 @@
 
 static void cork_callback(pa_stream* stream, int success, void* userdata) {
 
-    java_context* context = userdata;
     assert(stream);
-    assert(context);
     JNIEnv* env = pulse_thread_env;
     assert(env);
     notifyWaitingOperations(env);
@@ -678,11 +685,7 @@
 (JNIEnv* env, jobject obj, jint yes) {
     pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
     assert(stream);
-    java_context* j_context = malloc(sizeof(java_context));
-    assert(j_context);
-    j_context->env = env;
-    j_context->obj = (*env)->NewGlobalRef(env, obj);
-    pa_operation* operation = pa_stream_cork(stream, yes, cork_callback, j_context);
+    pa_operation* operation = pa_stream_cork(stream, yes, cork_callback, NULL);
     assert(operation);
     return convertNativePointerToJava(env, operation);
 }
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java	Fri Jun 10 17:42:18 2011 -0400
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java	Thu Jun 28 13:27:42 2012 -0400
@@ -115,6 +115,19 @@
 		clip.close();
 	}
 
+    @Test
+    public void testOpenCloseLotsOfTimes() throws LineUnavailableException,
+            UnsupportedAudioFileException, IOException {
+        File soundFile = new File("testsounds/startup.wav");
+        AudioInputStream audioInputStream = AudioSystem
+                .getAudioInputStream(soundFile);
+        for (int i = 0; i < 1000; i++) {
+            Clip clip = (Clip) mixer.getLine(new Line.Info(Clip.class));
+            clip.open(audioInputStream);
+            clip.close();
+        }
+    }
+
 	@Test
 	public void testLoop4Times() throws LineUnavailableException, IOException,
 			UnsupportedAudioFileException {