diff options
author | Glenn Kasten <gkasten@google.com> | 2013-09-19 16:42:19 -0700 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2013-09-19 16:46:04 -0700 |
commit | 8d87d7ba113ad90685f1d2669e65251a9b422a5a (patch) | |
tree | 1d4d4b08c27cb5ac810e0a5045c0db1f0c8cb3fd | |
parent | a2c6209f6120d300cd28d97ec868b5cabb3ee1a9 (diff) | |
download | frameworks_base-8d87d7ba113ad90685f1d2669e65251a9b422a5a.zip frameworks_base-8d87d7ba113ad90685f1d2669e65251a9b422a5a.tar.gz frameworks_base-8d87d7ba113ad90685f1d2669e65251a9b422a5a.tar.bz2 |
Workaround for slow AudioRecord destructor
Bug: 10816117
Change-Id: If59028bc7dc7abb84e1e3642c721c2629653631f
-rw-r--r-- | core/jni/android_media_AudioRecord.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
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> refBase) : mRefBase(refBase) { } +protected: + virtual ~AsyncDestructThread() { } +private: + virtual bool threadLoop() { return false; } + const sp<RefBase> mRefBase; +}; + #define CALLBACK_COND_WAIT_TIMEOUT_MS 1000 static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) { sp<AudioRecord> 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 + } } |