From 8d87d7ba113ad90685f1d2669e65251a9b422a5a Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 19 Sep 2013 16:42:19 -0700 Subject: Workaround for slow AudioRecord destructor Bug: 10816117 Change-Id: If59028bc7dc7abb84e1e3642c721c2629653631f --- core/jni/android_media_AudioRecord.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 1c43cc5..3994047 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -310,6 +310,18 @@ android_media_AudioRecord_stop(JNIEnv *env, jobject thiz) // ---------------------------------------------------------------------------- +// This class is used to destroy a RefBase asynchronously +class AsyncDestructThread : public Thread +{ +public: + AsyncDestructThread(sp refBase) : mRefBase(refBase) { } +protected: + virtual ~AsyncDestructThread() { } +private: + virtual bool threadLoop() { return false; } + const sp mRefBase; +}; + #define CALLBACK_COND_WAIT_TIMEOUT_MS 1000 static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) { sp lpRecorder = setAudioRecord(env, thiz, 0); @@ -342,6 +354,17 @@ static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) { env->DeleteGlobalRef(lpCookie->audioRecord_ref); delete lpCookie; } + // FIXME AudioRecord destruction should not be slow + if (lpRecorder != 0) { + // must be a raw reference to avoid a race after run() + AsyncDestructThread *adt = new AsyncDestructThread(lpRecorder); + // guaranteed to not run destructor + lpRecorder.clear(); + // after the run(), adt thread will hold a strong reference to lpRecorder, + // and the only strong reference to itself + adt->run("AsyncDestruct"); + // do not delete adt here: adt thread destroys itself, and lpRecorder if needed + } } -- cgit v1.1