Loading services/surfaceflinger/MessageQueue.cpp +49 −137 Original line number Diff line number Diff line Loading @@ -29,169 +29,81 @@ namespace android { // --------------------------------------------------------------------------- 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) : mLooper(new Looper(true)), mInvalidatePending(0) { mInvalidateMessage = new MessageBase(INVALIDATE); } MessageQueue::~MessageQueue() { MessageQueue::~MessageQueue() { } sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout) { sp<MessageBase> result; 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); // handle invalidate events first if (android_atomic_and(0, &mInvalidatePending) != 0) 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) break; 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; again = result->handler(); if (again) { // the message has been processed. release our reference to it // without holding the lock. result->notify(); result = 0; } case ALOOPER_POLL_CALLBACK: // callback was handled, loop again continue; case ALOOPER_POLL_TIMEOUT: // timeout (should not happen) continue; } while (again); case ALOOPER_POLL_ERROR: LOGE("ALOOPER_POLL_ERROR"); continue; return result; 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); } status_t MessageQueue::invalidate() { Mutex::Autolock _l(mLock); mInvalidate = true; mCondition.signal(); 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(); status_t MessageQueue::invalidate() { android_atomic_or(1, &mInvalidatePending); mLooper->wake(); 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 services/surfaceflinger/MessageQueue.h +13 −66 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ #include <utils/threads.h> #include <utils/Timers.h> #include <utils/List.h> #include <utils/Looper.h> #include "Barrier.h" Loading @@ -31,92 +31,39 @@ namespace android { // --------------------------------------------------------------------------- class MessageBase; class MessageList { List< sp<MessageBase> > mList; typedef List< sp<MessageBase> > LIST; public: inline LIST::iterator begin() { return mList.begin(); } inline LIST::const_iterator begin() const { return mList.begin(); } inline LIST::iterator end() { return mList.end(); } inline LIST::const_iterator end() const { return mList.end(); } inline bool isEmpty() const { return mList.empty(); } void insert(const sp<MessageBase>& node); void remove(LIST::iterator pos); }; // ============================================================================ class MessageBase : public LightRefBase<MessageBase> class MessageBase : public MessageHandler { public: nsecs_t when; uint32_t what; int32_t arg0; MessageBase() : when(0), what(0), arg0(0) { } MessageBase(uint32_t what, int32_t arg0=0) : when(0), what(what), arg0(arg0) { } MessageBase(); // return true if message has a handler virtual bool handler() { return false; } virtual bool handler() = 0; // waits for the handler to be processed void wait() const { barrier.wait(); } // releases all waiters. this is done automatically if // handler returns true void notify() const { barrier.open(); } protected: virtual ~MessageBase() { } virtual ~MessageBase(); private: virtual void handleMessage(const Message& message); mutable Barrier barrier; friend class LightRefBase<MessageBase>; }; inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { return lhs.when < rhs.when; } // --------------------------------------------------------------------------- class MessageQueue { typedef List< sp<MessageBase> > LIST; public: class MessageQueue { sp<Looper> mLooper; volatile int32_t mInvalidatePending; public: MessageQueue(); ~MessageQueue(); // pre-defined messages enum { INVALIDATE = '_upd' }; sp<MessageBase> waitMessage(nsecs_t timeout = -1); status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0, uint32_t flags = 0); void waitMessage(); status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0); status_t invalidate(); void dump(const sp<MessageBase>& message); private: status_t queueMessage(const sp<MessageBase>& message, nsecs_t reltime, uint32_t flags); void dumpLocked(const sp<MessageBase>& message); Mutex mLock; Condition mCondition; MessageList mMessages; bool mInvalidate; sp<MessageBase> mInvalidateMessage; }; // --------------------------------------------------------------------------- Loading services/surfaceflinger/SurfaceFlinger.cpp +2 −13 Original line number Diff line number Diff line Loading @@ -311,19 +311,8 @@ status_t SurfaceFlinger::readyToRun() #pragma mark Events Handler #endif void SurfaceFlinger::waitForEvent() { while (true) { nsecs_t timeout = -1; sp<MessageBase> msg = mEventQueue.waitMessage(timeout); if (msg != 0) { switch (msg->what) { case MessageQueue::INVALIDATE: // invalidate message, just return to the main loop return; } } } void SurfaceFlinger::waitForEvent() { mEventQueue.waitMessage(); } void SurfaceFlinger::signalEvent() { Loading Loading
services/surfaceflinger/MessageQueue.cpp +49 −137 Original line number Diff line number Diff line Loading @@ -29,169 +29,81 @@ namespace android { // --------------------------------------------------------------------------- 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) : mLooper(new Looper(true)), mInvalidatePending(0) { mInvalidateMessage = new MessageBase(INVALIDATE); } MessageQueue::~MessageQueue() { MessageQueue::~MessageQueue() { } sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout) { sp<MessageBase> result; 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); // handle invalidate events first if (android_atomic_and(0, &mInvalidatePending) != 0) 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) break; 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; again = result->handler(); if (again) { // the message has been processed. release our reference to it // without holding the lock. result->notify(); result = 0; } case ALOOPER_POLL_CALLBACK: // callback was handled, loop again continue; case ALOOPER_POLL_TIMEOUT: // timeout (should not happen) continue; } while (again); case ALOOPER_POLL_ERROR: LOGE("ALOOPER_POLL_ERROR"); continue; return result; 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); } status_t MessageQueue::invalidate() { Mutex::Autolock _l(mLock); mInvalidate = true; mCondition.signal(); 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(); status_t MessageQueue::invalidate() { android_atomic_or(1, &mInvalidatePending); mLooper->wake(); 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
services/surfaceflinger/MessageQueue.h +13 −66 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ #include <utils/threads.h> #include <utils/Timers.h> #include <utils/List.h> #include <utils/Looper.h> #include "Barrier.h" Loading @@ -31,92 +31,39 @@ namespace android { // --------------------------------------------------------------------------- class MessageBase; class MessageList { List< sp<MessageBase> > mList; typedef List< sp<MessageBase> > LIST; public: inline LIST::iterator begin() { return mList.begin(); } inline LIST::const_iterator begin() const { return mList.begin(); } inline LIST::iterator end() { return mList.end(); } inline LIST::const_iterator end() const { return mList.end(); } inline bool isEmpty() const { return mList.empty(); } void insert(const sp<MessageBase>& node); void remove(LIST::iterator pos); }; // ============================================================================ class MessageBase : public LightRefBase<MessageBase> class MessageBase : public MessageHandler { public: nsecs_t when; uint32_t what; int32_t arg0; MessageBase() : when(0), what(0), arg0(0) { } MessageBase(uint32_t what, int32_t arg0=0) : when(0), what(what), arg0(arg0) { } MessageBase(); // return true if message has a handler virtual bool handler() { return false; } virtual bool handler() = 0; // waits for the handler to be processed void wait() const { barrier.wait(); } // releases all waiters. this is done automatically if // handler returns true void notify() const { barrier.open(); } protected: virtual ~MessageBase() { } virtual ~MessageBase(); private: virtual void handleMessage(const Message& message); mutable Barrier barrier; friend class LightRefBase<MessageBase>; }; inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { return lhs.when < rhs.when; } // --------------------------------------------------------------------------- class MessageQueue { typedef List< sp<MessageBase> > LIST; public: class MessageQueue { sp<Looper> mLooper; volatile int32_t mInvalidatePending; public: MessageQueue(); ~MessageQueue(); // pre-defined messages enum { INVALIDATE = '_upd' }; sp<MessageBase> waitMessage(nsecs_t timeout = -1); status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0, uint32_t flags = 0); void waitMessage(); status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0); status_t invalidate(); void dump(const sp<MessageBase>& message); private: status_t queueMessage(const sp<MessageBase>& message, nsecs_t reltime, uint32_t flags); void dumpLocked(const sp<MessageBase>& message); Mutex mLock; Condition mCondition; MessageList mMessages; bool mInvalidate; sp<MessageBase> mInvalidateMessage; }; // --------------------------------------------------------------------------- Loading
services/surfaceflinger/SurfaceFlinger.cpp +2 −13 Original line number Diff line number Diff line Loading @@ -311,19 +311,8 @@ status_t SurfaceFlinger::readyToRun() #pragma mark Events Handler #endif void SurfaceFlinger::waitForEvent() { while (true) { nsecs_t timeout = -1; sp<MessageBase> msg = mEventQueue.waitMessage(timeout); if (msg != 0) { switch (msg->what) { case MessageQueue::INVALIDATE: // invalidate message, just return to the main loop return; } } } void SurfaceFlinger::waitForEvent() { mEventQueue.waitMessage(); } void SurfaceFlinger::signalEvent() { Loading