diff --git a/src/android/AudioRecorder_to_android.cpp b/src/android/AudioRecorder_to_android.cpp index ebb95926492d9abbdaca4d643feaa2f755e6b4ab..800a767184d32a5edc21fe0d3e8a7b2bcea03e03 100644 --- a/src/android/AudioRecorder_to_android.cpp +++ b/src/android/AudioRecorder_to_android.cpp @@ -212,6 +212,12 @@ static void audioRecorder_callback(int event, void* user, void *info) { //SL_LOGV("audioRecorder_callback(%d, %p, %p) entering", event, user, info); CAudioRecorder *ar = (CAudioRecorder *)user; + + if (!android::CallbackProtector::enterCbIfOk(ar->mCallbackProtector)) { + // it is not safe to enter the callback (the track is about to go away) + return; + } + void * callbackPContext = NULL; switch(event) { @@ -289,6 +295,8 @@ static void audioRecorder_callback(int event, void* user, void *info) { break; } + + ar->mCallbackProtector->exitCb(); } @@ -312,6 +320,7 @@ SLresult android_audioRecorder_create(CAudioRecorder* ar) { // microphone to simple buffer queue ar->mAndroidObjType = AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE; ar->mAudioRecord.clear(); + ar->mCallbackProtector = new android::CallbackProtector(); ar->mRecordSource = AUDIO_SOURCE_DEFAULT; } else { result = SL_RESULT_CONTENT_UNSUPPORTED; @@ -429,15 +438,30 @@ SLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) { } +//----------------------------------------------------------------------------- +/** + * Called with a lock on AudioRecorder, and blocks until safe to destroy + */ +void android_audioRecorder_preDestroy(CAudioRecorder* ar) { + object_unlock_exclusive(&ar->mObject); + if (ar->mCallbackProtector != 0) { + ar->mCallbackProtector->requestCbExitAndWait(); + } + object_lock_exclusive(&ar->mObject); +} + + //----------------------------------------------------------------------------- void android_audioRecorder_destroy(CAudioRecorder* ar) { SL_LOGV("android_audioRecorder_destroy(%p) entering", ar); if (ar->mAudioRecord != 0) { ar->mAudioRecord->stop(); + ar->mAudioRecord.clear(); } // explicit destructor ar->mAudioRecord.~sp(); + ar->mCallbackProtector.~sp(); #ifdef MONITOR_RECORDING if (NULL != gMonitorFp) { diff --git a/src/android/AudioRecorder_to_android.h b/src/android/AudioRecorder_to_android.h index b8d4dd27cfcf15f17e603f8f8c021c9ed816f91c..d561ca1277cc3da123e6c963e26dadf7de644950 100644 --- a/src/android/AudioRecorder_to_android.h +++ b/src/android/AudioRecorder_to_android.h @@ -45,6 +45,8 @@ extern SLresult android_audioRecorder_getConfig(CAudioRecorder* ar, const SLchar extern SLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async); +extern void android_audioRecorder_preDestroy(CAudioRecorder* ar); + extern void android_audioRecorder_destroy(CAudioRecorder* ar); /************************************************************************************************** diff --git a/src/classes.h b/src/classes.h index 977772dab16f6b5d16e214ec35bad37d6ec03bb2..37508e70b50c7f344bbb71490f536d7ae24a1632 100644 --- a/src/classes.h +++ b/src/classes.h @@ -150,6 +150,7 @@ // FIXME consolidate the next several variables into ARecorder class to avoid placement new enum AndroidObjectType mAndroidObjType; android::sp<android::AudioRecord> mAudioRecord; + android::sp<android::CallbackProtector> mCallbackProtector; audio_source_t mRecordSource; #endif } /*CAudioRecorder*/; diff --git a/src/itf/IEngine.c b/src/itf/IEngine.c index 6950baf601877a53480a1f988df4cfc31839114e..7d3e07a92d5018acf63a1c03b1de3822de4d9b98 100644 --- a/src/itf/IEngine.c +++ b/src/itf/IEngine.c @@ -453,6 +453,8 @@ static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pReco // FIXME unnecessary once those fields are encapsulated in one class, rather // than a structure (void) new (&thiz->mAudioRecord) android::sp<android::AudioRecord>(); + (void) new (&thiz->mCallbackProtector) + android::sp<android::CallbackProtector>(); thiz->mRecordSource = AUDIO_SOURCE_DEFAULT; #endif diff --git a/src/objects/CAudioRecorder.c b/src/objects/CAudioRecorder.c index 956e98727b5640377eada1578f2170229141ab70..6eab0cfce229270ccaf56dedd7e03f1e01d95888 100644 --- a/src/objects/CAudioRecorder.c +++ b/src/objects/CAudioRecorder.c @@ -59,5 +59,9 @@ void CAudioRecorder_Destroy(void *self) predestroy_t CAudioRecorder_PreDestroy(void *self) { + CAudioRecorder *thiz = (CAudioRecorder *) self; +#ifdef ANDROID + android_audioRecorder_preDestroy(thiz); +#endif return predestroy_ok; }