diff options
author | Glenn Kasten <gkasten@google.com> | 2013-09-20 00:08:58 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-09-20 00:08:58 +0000 |
commit | 9d53e30e5eaf53cb0bd57319e02025ba7182bba3 (patch) | |
tree | c4f10d13b698a6eaaca65b561347645a04e153eb /core/jni | |
parent | a17309fd9ed705bb3a9d7adbf3b30eb71952dabc (diff) | |
parent | 8d87d7ba113ad90685f1d2669e65251a9b422a5a (diff) | |
download | frameworks_base-9d53e30e5eaf53cb0bd57319e02025ba7182bba3.zip frameworks_base-9d53e30e5eaf53cb0bd57319e02025ba7182bba3.tar.gz frameworks_base-9d53e30e5eaf53cb0bd57319e02025ba7182bba3.tar.bz2 |
Merge "Workaround for slow AudioRecord destructor" into klp-dev
Diffstat (limited to 'core/jni')
-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 + } } |