Merge "Support for posting messages and synchronously waiting for a response."
This commit is contained in:
committed by
Android (Google) Code Review
commit
539340fe2c
@@ -31,9 +31,14 @@ struct ALooperRoster {
|
|||||||
|
|
||||||
void unregisterHandler(ALooper::handler_id handlerID);
|
void unregisterHandler(ALooper::handler_id handlerID);
|
||||||
|
|
||||||
void postMessage(const sp<AMessage> &msg, int64_t delayUs = 0);
|
status_t postMessage(const sp<AMessage> &msg, int64_t delayUs = 0);
|
||||||
void deliverMessage(const sp<AMessage> &msg);
|
void deliverMessage(const sp<AMessage> &msg);
|
||||||
|
|
||||||
|
status_t postAndAwaitResponse(
|
||||||
|
const sp<AMessage> &msg, sp<AMessage> *response);
|
||||||
|
|
||||||
|
void postReply(uint32_t replyID, const sp<AMessage> &reply);
|
||||||
|
|
||||||
sp<ALooper> findLooper(ALooper::handler_id handlerID);
|
sp<ALooper> findLooper(ALooper::handler_id handlerID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -45,6 +50,12 @@ private:
|
|||||||
Mutex mLock;
|
Mutex mLock;
|
||||||
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
|
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
|
||||||
ALooper::handler_id mNextHandlerID;
|
ALooper::handler_id mNextHandlerID;
|
||||||
|
uint32_t mNextReplyID;
|
||||||
|
Condition mRepliesCondition;
|
||||||
|
|
||||||
|
KeyedVector<uint32_t, sp<AMessage> > mReplies;
|
||||||
|
|
||||||
|
status_t postMessage_l(const sp<AMessage> &msg, int64_t delayUs);
|
||||||
|
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
|
DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -72,6 +72,17 @@ struct AMessage : public RefBase {
|
|||||||
|
|
||||||
void post(int64_t delayUs = 0);
|
void post(int64_t delayUs = 0);
|
||||||
|
|
||||||
|
// Posts the message to its target and waits for a response (or error)
|
||||||
|
// before returning.
|
||||||
|
status_t postAndAwaitResponse(sp<AMessage> *response);
|
||||||
|
|
||||||
|
// If this returns true, the sender of this message is synchronously
|
||||||
|
// awaiting a response, the "replyID" can be used to send the response
|
||||||
|
// via "postReply" below.
|
||||||
|
bool senderAwaitsResponse(uint32_t *replyID) const;
|
||||||
|
|
||||||
|
void postReply(uint32_t replyID);
|
||||||
|
|
||||||
// Performs a deep-copy of "this", contained messages are in turn "dup'ed".
|
// Performs a deep-copy of "this", contained messages are in turn "dup'ed".
|
||||||
// Warning: RefBase items, i.e. "objects" are _not_ copied but only have
|
// Warning: RefBase items, i.e. "objects" are _not_ copied but only have
|
||||||
// their refcount incremented.
|
// their refcount incremented.
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
ALooperRoster::ALooperRoster()
|
ALooperRoster::ALooperRoster()
|
||||||
: mNextHandlerID(1) {
|
: mNextHandlerID(1),
|
||||||
|
mNextReplyID(1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ALooper::handler_id ALooperRoster::registerHandler(
|
ALooper::handler_id ALooperRoster::registerHandler(
|
||||||
@@ -70,15 +71,19 @@ void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
|
|||||||
mHandlers.removeItemsAt(index);
|
mHandlers.removeItemsAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALooperRoster::postMessage(
|
status_t ALooperRoster::postMessage(
|
||||||
const sp<AMessage> &msg, int64_t delayUs) {
|
const sp<AMessage> &msg, int64_t delayUs) {
|
||||||
Mutex::Autolock autoLock(mLock);
|
Mutex::Autolock autoLock(mLock);
|
||||||
|
return postMessage_l(msg, delayUs);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t ALooperRoster::postMessage_l(
|
||||||
|
const sp<AMessage> &msg, int64_t delayUs) {
|
||||||
ssize_t index = mHandlers.indexOfKey(msg->target());
|
ssize_t index = mHandlers.indexOfKey(msg->target());
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
LOGW("failed to post message. Target handler not registered.");
|
LOGW("failed to post message. Target handler not registered.");
|
||||||
return;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HandlerInfo &info = mHandlers.valueAt(index);
|
const HandlerInfo &info = mHandlers.valueAt(index);
|
||||||
@@ -91,10 +96,12 @@ void ALooperRoster::postMessage(
|
|||||||
msg->target());
|
msg->target());
|
||||||
|
|
||||||
mHandlers.removeItemsAt(index);
|
mHandlers.removeItemsAt(index);
|
||||||
return;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
looper->post(msg, delayUs);
|
looper->post(msg, delayUs);
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
|
void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
|
||||||
@@ -145,4 +152,38 @@ sp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) {
|
|||||||
return looper;
|
return looper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = postMessage_l(msg, 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();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
extern ALooperRoster gLooperRoster;
|
||||||
|
|
||||||
AMessage::AMessage(uint32_t what, ALooper::handler_id target)
|
AMessage::AMessage(uint32_t what, ALooper::handler_id target)
|
||||||
: mWhat(what),
|
: mWhat(what),
|
||||||
mTarget(target),
|
mTarget(target),
|
||||||
@@ -227,11 +229,30 @@ bool AMessage::findRect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AMessage::post(int64_t delayUs) {
|
void AMessage::post(int64_t delayUs) {
|
||||||
extern ALooperRoster gLooperRoster;
|
|
||||||
|
|
||||||
gLooperRoster.postMessage(this, delayUs);
|
gLooperRoster.postMessage(this, delayUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t AMessage::postAndAwaitResponse(sp<AMessage> *response) {
|
||||||
|
return gLooperRoster.postAndAwaitResponse(this, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMessage::postReply(uint32_t replyID) {
|
||||||
|
gLooperRoster.postReply(replyID, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMessage::senderAwaitsResponse(uint32_t *replyID) const {
|
||||||
|
int32_t tmp;
|
||||||
|
bool found = findInt32("replyID", &tmp);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*replyID = static_cast<uint32_t>(tmp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
sp<AMessage> AMessage::dup() const {
|
sp<AMessage> AMessage::dup() const {
|
||||||
sp<AMessage> msg = new AMessage(mWhat, mTarget);
|
sp<AMessage> msg = new AMessage(mWhat, mTarget);
|
||||||
msg->mNumItems = mNumItems;
|
msg->mNumItems = mNumItems;
|
||||||
|
|||||||
Reference in New Issue
Block a user