summaryrefslogtreecommitdiffstats
path: root/src/android/CallbackProtector.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2011-09-12 10:23:54 -0700
committerGlenn Kasten <gkasten@google.com>2011-09-21 07:31:06 -0700
commitf4b45a37248899ae2d27bb172f8387fbf1edff8e (patch)
tree9935045c7f259e2be956f53b91595079212bedd2 /src/android/CallbackProtector.cpp
parent22de06ce0df9144d47069c235e60c9d2b08c0fff (diff)
downloadandroid_frameworks_wilhelm-f4b45a37248899ae2d27bb172f8387fbf1edff8e.tar.gz
android_frameworks_wilhelm-f4b45a37248899ae2d27bb172f8387fbf1edff8e.tar.bz2
android_frameworks_wilhelm-f4b45a37248899ae2d27bb172f8387fbf1edff8e.zip
Bug 5090073 Callback protectors
Add callback protector for decode to PCM usage cases. Move callback protection up earlier for URI decode use case only. Other: Remove redundant mCallbackProtector field. Optimization: on exit from callback protector, only broadcast if !mSafeToEnterCb, that is if destroy has requested callback protectors to finish up. More callback protector logging. Add callback protector requestCbExit() [no wait], not yet used. Unrelated: 3rd parameter of adecoder_writeToBufferQueue is always CAudioPlayer * instead of void *. Change-Id: I57a46acf0e5ecb213540b13ca08098177ad7ad6e
Diffstat (limited to 'src/android/CallbackProtector.cpp')
-rw-r--r--src/android/CallbackProtector.cpp79
1 files changed, 77 insertions, 2 deletions
diff --git a/src/android/CallbackProtector.cpp b/src/android/CallbackProtector.cpp
index 9732265..e1221ee 100644
--- a/src/android/CallbackProtector.cpp
+++ b/src/android/CallbackProtector.cpp
@@ -15,6 +15,7 @@
*/
#include "CallbackProtector.h"
+#include "sllog.h"
#include <media/stagefright/foundation/ADebug.h>
@@ -24,11 +25,22 @@ namespace android {
CallbackProtector::CallbackProtector() : RefBase(),
mSafeToEnterCb(true),
- mCbCount(0) {
+ mCbCount(0)
+#ifdef USE_DEBUG
+ , mCallbackThread(NULL),
+ mCallbackTid(0),
+ mRequesterThread(NULL),
+ mRequesterTid(0)
+#endif
+{
}
CallbackProtector::~CallbackProtector() {
+ Mutex::Autolock _l(mLock);
+ if (mCbCount) {
+ SL_LOGE("Callback protector detected an active callback after destroy");
+ }
}
@@ -38,6 +50,7 @@ bool CallbackProtector::enterCbIfOk(const sp<CallbackProtector> &protector) {
if (protector != 0) {
return protector->enterCb();
} else {
+ SL_LOGE("Callback protector is missing");
return false;
}
}
@@ -47,6 +60,23 @@ bool CallbackProtector::enterCb() {
Mutex::Autolock _l(mLock);
if (mSafeToEnterCb) {
mCbCount++;
+#ifdef USE_DEBUG
+ if (mCbCount > 1) {
+ SL_LOGW("Callback protector allowed multiple or nested callback entry");
+ } else {
+ mCallbackThread = pthread_self();
+ mCallbackTid = gettid();
+ }
+#endif
+ } else {
+#ifdef USE_DEBUG
+ SL_LOGI("Callback protector denied callback entry by thread %p tid %d during destroy"
+ " requested by thread %p tid %d",
+ (void *) pthread_self(), gettid(),
+ (void *) mRequesterThread, mRequesterTid);
+#else
+ SL_LOGI("Callback protector denied callback entry during destroy");
+#endif
}
return mSafeToEnterCb;
}
@@ -59,7 +89,21 @@ void CallbackProtector::exitCb() {
mCbCount--;
if (mCbCount == 0) {
- mCbExitedCondition.broadcast();
+ if (!mSafeToEnterCb) {
+#ifdef USE_DEBUG
+ SL_LOGI("Callback protector detected return from callback by thread %p tid %d during"
+ " destroy requested by thread %p tid %d",
+ (void *) mCallbackThread, mCallbackTid,
+ (void *) mRequesterThread, mRequesterTid);
+#else
+ SL_LOGI("Callback protector detected return from callback during destroy");
+#endif
+ mCbExitedCondition.broadcast();
+ }
+#ifdef USE_DEBUG
+ mCallbackThread = NULL;
+ mCallbackTid = 0;
+#endif
}
}
@@ -67,10 +111,41 @@ void CallbackProtector::exitCb() {
void CallbackProtector::requestCbExitAndWait() {
Mutex::Autolock _l(mLock);
mSafeToEnterCb = false;
+#ifdef USE_DEBUG
+ mRequesterThread = pthread_self();
+ mRequesterTid = gettid();
+#endif
while (mCbCount) {
+#ifdef USE_DEBUG
+ SL_LOGI("Callback protector detected in-progress callback by thread %p tid %d during"
+ " blocking destroy requested by thread %p tid %d",
+ (void *) mCallbackThread, mCallbackTid,
+ (void *) pthread_self(), gettid());
+#else
+ SL_LOGI("Callback protector detected in-progress callback during blocking destroy");
+#endif
mCbExitedCondition.wait(mLock);
}
}
+void CallbackProtector::requestCbExit() {
+ Mutex::Autolock _l(mLock);
+ mSafeToEnterCb = false;
+#ifdef USE_DEBUG
+ mRequesterThread = pthread_self();
+ mRequesterTid = gettid();
+#endif
+ if (mCbCount) {
+#ifdef USE_DEBUG
+ SL_LOGI("Callback protector detected in-progress callback by thread %p tid %d during"
+ " non-blocking destroy requested by thread %p tid %d",
+ (void *) mCallbackThread, mCallbackTid,
+ (void *) pthread_self(), gettid());
+#else
+ SL_LOGI("Callback protector detected in-progress callback during non-blocking destroy");
+#endif
+ }
+}
+
} // namespace android