summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/foundation
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-03-05 14:35:41 -0800
committerLajos Molnar <lajos@google.com>2015-03-10 10:36:09 -0700
commit3f27436a9346f043f52265da1e6a74cde2bffd4d (patch)
treea7404d2ba96071bea1f02f93f6782214fc1e4cc1 /media/libstagefright/foundation
parent0655386a0dc15fc31883d2e38917ff0e9db89ae7 (diff)
downloadframeworks_av-3f27436a9346f043f52265da1e6a74cde2bffd4d.zip
frameworks_av-3f27436a9346f043f52265da1e6a74cde2bffd4d.tar.gz
frameworks_av-3f27436a9346f043f52265da1e6a74cde2bffd4d.tar.bz2
stagefright: don't use ALooperRoster mutex for reply handling
Change replyID-s from uint32_t to an object Move reply handling into the loopers (to reuse a common mutex) Bug: 19607784 Change-Id: Iaa035b846c424c5687ed17ce1079b325e86c54be
Diffstat (limited to 'media/libstagefright/foundation')
-rw-r--r--media/libstagefright/foundation/ALooper.cpp28
-rw-r--r--media/libstagefright/foundation/ALooperRoster.cpp36
-rw-r--r--media/libstagefright/foundation/AMessage.cpp53
3 files changed, 74 insertions, 43 deletions
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 617d32b..90b5f68 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -16,6 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "ALooper"
+
+#include <media/stagefright/foundation/ADebug.h>
+
#include <utils/Log.h>
#include <sys/time.h>
@@ -220,4 +223,29 @@ bool ALooper::loop() {
return true;
}
+// to be called by AMessage::postAndAwaitResponse only
+sp<AReplyToken> ALooper::createReplyToken() {
+ return new AReplyToken(this);
+}
+
+// to be called by AMessage::postAndAwaitResponse only
+status_t ALooper::awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response) {
+ // return status in case we want to handle an interrupted wait
+ Mutex::Autolock autoLock(mRepliesLock);
+ CHECK(replyToken != NULL);
+ while (!replyToken->retrieveReply(response)) {
+ mRepliesCondition.wait(mRepliesLock);
+ }
+ return OK;
+}
+
+status_t ALooper::postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &reply) {
+ Mutex::Autolock autoLock(mRepliesLock);
+ status_t err = replyToken->setReply(reply);
+ if (err == OK) {
+ mRepliesCondition.broadcast();
+ }
+ return err;
+}
+
} // namespace android
diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/libstagefright/foundation/ALooperRoster.cpp
index c4e6788..473ce1b 100644
--- a/media/libstagefright/foundation/ALooperRoster.cpp
+++ b/media/libstagefright/foundation/ALooperRoster.cpp
@@ -30,8 +30,7 @@ namespace android {
static bool verboseStats = false;
ALooperRoster::ALooperRoster()
- : mNextHandlerID(1),
- mNextReplyID(1) {
+ : mNextHandlerID(1) {
}
ALooper::handler_id ALooperRoster::registerHandler(
@@ -100,39 +99,6 @@ void ALooperRoster::unregisterStaleHandlers() {
}
}
-status_t ALooperRoster::postAndAwaitResponse(
- const sp<AMessage> &msg, sp<AMessage> *response) {
- Mutex::Autolock autoLock(mLock);
-
- uint32_t replyID = mNextReplyID++;
-
- msg->setInt32("replyID", replyID);
-
- status_t err = msg->post(0 /* delayUs */);
- if (err != OK) {
- response->clear();
- return err;
- }
-
- ssize_t index;
- while ((index = mReplies.indexOfKey(replyID)) < 0) {
- mRepliesCondition.wait(mLock);
- }
-
- *response = mReplies.valueAt(index);
- mReplies.removeItemsAt(index);
-
- return OK;
-}
-
-void ALooperRoster::postReply(uint32_t replyID, const sp<AMessage> &reply) {
- Mutex::Autolock autoLock(mLock);
-
- CHECK(mReplies.indexOfKey(replyID) < 0);
- mReplies.add(replyID, reply);
- mRepliesCondition.broadcast();
-}
-
static void makeFourCC(uint32_t fourcc, char *s) {
s[0] = (fourcc >> 24) & 0xff;
if (s[0]) {
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index d4add15..e549ff6 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -37,6 +37,17 @@ namespace android {
extern ALooperRoster gLooperRoster;
+status_t AReplyToken::setReply(const sp<AMessage> &reply) {
+ if (mReplied) {
+ ALOGE("trying to post a duplicate reply");
+ return -EBUSY;
+ }
+ CHECK(mReply == NULL);
+ mReply = reply;
+ mReplied = true;
+ return OK;
+}
+
AMessage::AMessage(void)
: mWhat(0),
mTarget(0),
@@ -355,24 +366,50 @@ status_t AMessage::post(int64_t delayUs) {
}
status_t AMessage::postAndAwaitResponse(sp<AMessage> *response) {
- return gLooperRoster.postAndAwaitResponse(this, response);
+ sp<ALooper> looper = mLooper.promote();
+ if (looper == NULL) {
+ ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
+ return -ENOENT;
+ }
+
+ sp<AReplyToken> token = looper->createReplyToken();
+ if (token == NULL) {
+ ALOGE("failed to create reply token");
+ return -ENOMEM;
+ }
+ setObject("replyID", token);
+
+ looper->post(this, 0 /* delayUs */);
+ return looper->awaitResponse(token, response);
}
-void AMessage::postReply(uint32_t replyID) {
- gLooperRoster.postReply(replyID, this);
+status_t AMessage::postReply(const sp<AReplyToken> &replyToken) {
+ if (replyToken == NULL) {
+ ALOGW("failed to post reply to a NULL token");
+ return -ENOENT;
+ }
+ sp<ALooper> looper = replyToken->getLooper();
+ if (looper == NULL) {
+ ALOGW("failed to post reply as target looper is gone.");
+ return -ENOENT;
+ }
+ return looper->postReply(replyToken, this);
}
-bool AMessage::senderAwaitsResponse(uint32_t *replyID) const {
- int32_t tmp;
- bool found = findInt32("replyID", &tmp);
+bool AMessage::senderAwaitsResponse(sp<AReplyToken> *replyToken) {
+ sp<RefBase> tmp;
+ bool found = findObject("replyID", &tmp);
if (!found) {
return false;
}
- *replyID = static_cast<uint32_t>(tmp);
+ *replyToken = static_cast<AReplyToken *>(tmp.get());
+ tmp.clear();
+ setObject("replyID", tmp);
+ // TODO: delete Object instead of setting it to NULL
- return true;
+ return *replyToken != NULL;
}
sp<AMessage> AMessage::dup() const {