/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_MESSAGE_QUEUE_H #define ANDROID_MESSAGE_QUEUE_H #include <stdint.h> #include <errno.h> #include <sys/types.h> #include <utils/threads.h> #include <utils/Timers.h> #include <utils/List.h> #include "Barrier.h" 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> { 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) { } // return true if message has a handler virtual bool handler() { return false; } // 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() { } private: 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: 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); 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; }; // --------------------------------------------------------------------------- }; // namespace android #endif /* ANDROID_MESSAGE_QUEUE_H */