summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2013-09-19 16:42:19 -0700
committerGlenn Kasten <gkasten@google.com>2013-09-19 16:46:04 -0700
commit8d87d7ba113ad90685f1d2669e65251a9b422a5a (patch)
tree1d4d4b08c27cb5ac810e0a5045c0db1f0c8cb3fd
parenta2c6209f6120d300cd28d97ec868b5cabb3ee1a9 (diff)
downloadframeworks_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.cpp23
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
+ }
}