rewrite SF's message loop on top of Looper
Change-Id: Ib56139f87a5c0b124e34da5c8151207219b2577b
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index aebe1b8..1846ccb 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -29,169 +29,81 @@
// ---------------------------------------------------------------------------
-void MessageList::insert(const sp<MessageBase>& node)
-{
- LIST::iterator cur(mList.begin());
- LIST::iterator end(mList.end());
- while (cur != end) {
- if (*node < **cur) {
- mList.insert(cur, node);
- return;
- }
- ++cur;
- }
- mList.insert(++end, node);
+MessageBase::MessageBase()
+ : MessageHandler() {
}
-void MessageList::remove(MessageList::LIST::iterator pos)
-{
- mList.erase(pos);
+MessageBase::~MessageBase() {
}
+void MessageBase::handleMessage(const Message&) {
+ this->handler();
+ barrier.open();
+};
+
// ---------------------------------------------------------------------------
MessageQueue::MessageQueue()
- : mInvalidate(false)
-{
- mInvalidateMessage = new MessageBase(INVALIDATE);
-}
-
-MessageQueue::~MessageQueue()
+ : mLooper(new Looper(true)),
+ mInvalidatePending(0)
{
}
-sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout)
-{
- sp<MessageBase> result;
+MessageQueue::~MessageQueue() {
+}
- bool again;
+void MessageQueue::waitMessage() {
do {
- const nsecs_t timeoutTime = systemTime() + timeout;
- while (true) {
- Mutex::Autolock _l(mLock);
- nsecs_t now = systemTime();
- nsecs_t nextEventTime = -1;
-
- LIST::iterator cur(mMessages.begin());
- if (cur != mMessages.end()) {
- result = *cur;
- }
-
- if (result != 0) {
- if (result->when <= now) {
- // there is a message to deliver
- mMessages.remove(cur);
- break;
- }
- nextEventTime = result->when;
- result = 0;
- }
-
- // see if we have an invalidate message
- if (mInvalidate) {
- mInvalidate = false;
- mInvalidateMessage->when = now;
- result = mInvalidateMessage;
- break;
- }
-
- if (timeout >= 0) {
- if (timeoutTime < now) {
- // we timed-out, return a NULL message
- result = 0;
- break;
- }
- if (nextEventTime > 0) {
- if (nextEventTime > timeoutTime) {
- nextEventTime = timeoutTime;
- }
- } else {
- nextEventTime = timeoutTime;
- }
- }
-
- if (nextEventTime >= 0) {
- //LOGD("nextEventTime = %lld ms", nextEventTime);
- if (nextEventTime > 0) {
- // we're about to wait, flush the binder command buffer
- IPCThreadState::self()->flushCommands();
- const nsecs_t reltime = nextEventTime - systemTime();
- if (reltime > 0) {
- mCondition.waitRelative(mLock, reltime);
- }
- }
- } else {
- //LOGD("going to wait");
- // we're about to wait, flush the binder command buffer
- IPCThreadState::self()->flushCommands();
- mCondition.wait(mLock);
- }
- }
- // here we're not holding the lock anymore
-
- if (result == 0)
+ // handle invalidate events first
+ if (android_atomic_and(0, &mInvalidatePending) != 0)
break;
- again = result->handler();
- if (again) {
- // the message has been processed. release our reference to it
- // without holding the lock.
- result->notify();
- result = 0;
- }
-
- } while (again);
+ IPCThreadState::self()->flushCommands();
- return result;
+ int32_t ret = mLooper->pollOnce(-1);
+ switch (ret) {
+ case ALOOPER_POLL_WAKE:
+ // we got woken-up there is work to do in the main loop
+ continue;
+
+ case ALOOPER_POLL_CALLBACK:
+ // callback was handled, loop again
+ continue;
+
+ case ALOOPER_POLL_TIMEOUT:
+ // timeout (should not happen)
+ continue;
+
+ case ALOOPER_POLL_ERROR:
+ LOGE("ALOOPER_POLL_ERROR");
+ continue;
+
+ default:
+ // should not happen
+ LOGE("Looper::pollOnce() returned unknown status %d", ret);
+ continue;
+ }
+ } while (true);
}
status_t MessageQueue::postMessage(
- const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
+ const sp<MessageBase>& messageHandler, nsecs_t relTime)
{
- return queueMessage(message, relTime, flags);
+ const Message dummyMessage;
+ if (relTime > 0) {
+ mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
+ } else {
+ mLooper->sendMessage(messageHandler, dummyMessage);
+ }
+ return NO_ERROR;
}
status_t MessageQueue::invalidate() {
- Mutex::Autolock _l(mLock);
- mInvalidate = true;
- mCondition.signal();
+ android_atomic_or(1, &mInvalidatePending);
+ mLooper->wake();
return NO_ERROR;
}
-status_t MessageQueue::queueMessage(
- const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
-{
- Mutex::Autolock _l(mLock);
- message->when = systemTime() + relTime;
- mMessages.insert(message);
-
- //LOGD("MessageQueue::queueMessage time = %lld ms", message->when);
- //dumpLocked(message);
-
- mCondition.signal();
- return NO_ERROR;
-}
-
-void MessageQueue::dump(const sp<MessageBase>& message)
-{
- Mutex::Autolock _l(mLock);
- dumpLocked(message);
-}
-
-void MessageQueue::dumpLocked(const sp<MessageBase>& message)
-{
- LIST::const_iterator cur(mMessages.begin());
- LIST::const_iterator end(mMessages.end());
- int c = 0;
- while (cur != end) {
- const char tick = (*cur == message) ? '>' : ' ';
- LOGD("%c %d: msg{.what=%08x, when=%lld}",
- tick, c, (*cur)->what, (*cur)->when);
- ++cur;
- c++;
- }
-}
-
// ---------------------------------------------------------------------------
}; // namespace android