# HG changeset patch # User Omair Majid # Date 1340904462 14400 # Node ID 7f9a42012be765a859957190b5449f1afdf21488 # Parent fa76bb3356e5079c12c86bfd5a1904a0863acafe PR1050: Stream objects not garbage collected 2012-06-28 Omair Majid * 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. diff -r fa76bb3356e5 -r 7f9a42012be7 ChangeLog --- 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 + + 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 * pulseaudio/*: Fix whitespace. diff -r fa76bb3356e5 -r 7f9a42012be7 pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java --- 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(); diff -r fa76bb3356e5 -r 7f9a42012be7 pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c --- 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); } diff -r fa76bb3356e5 -r 7f9a42012be7 pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java --- 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 {