summaryrefslogtreecommitdiffstats
path: root/include/utils/Looper.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/utils/Looper.h')
-rw-r--r--include/utils/Looper.h377
1 files changed, 0 insertions, 377 deletions
diff --git a/include/utils/Looper.h b/include/utils/Looper.h
deleted file mode 100644
index 3c2905d..0000000
--- a/include/utils/Looper.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2010 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 UTILS_LOOPER_H
-#define UTILS_LOOPER_H
-
-#include <utils/threads.h>
-#include <utils/RefBase.h>
-#include <utils/KeyedVector.h>
-#include <utils/Timers.h>
-
-#include <android/looper.h>
-
-// When defined, uses epoll_wait() for polling, otherwise uses poll().
-#define LOOPER_USES_EPOLL
-
-// When defined, logs performance statistics for tuning and debugging purposes.
-//#define LOOPER_STATISTICS
-
-#ifdef LOOPER_USES_EPOLL
-#include <sys/epoll.h>
-#else
-#include <sys/poll.h>
-#endif
-
-/*
- * Declare a concrete type for the NDK's looper forward declaration.
- */
-struct ALooper {
-};
-
-namespace android {
-
-/**
- * A message that can be posted to a Looper.
- */
-struct Message {
- Message() : what(0) { }
- Message(int what) : what(what) { }
-
- /* The message type. (interpretation is left up to the handler) */
- int what;
-};
-
-
-/**
- * Interface for a Looper message handler.
- *
- * The Looper holds a strong reference to the message handler whenever it has
- * a message to deliver to it. Make sure to call Looper::removeMessages
- * to remove any pending messages destined for the handler so that the handler
- * can be destroyed.
- */
-class MessageHandler : public virtual RefBase {
-protected:
- virtual ~MessageHandler() { }
-
-public:
- /**
- * Handles a message.
- */
- virtual void handleMessage(const Message& message) = 0;
-};
-
-
-/**
- * A simple proxy that holds a weak reference to a message handler.
- */
-class WeakMessageHandler : public MessageHandler {
-public:
- WeakMessageHandler(const wp<MessageHandler>& handler);
- virtual void handleMessage(const Message& message);
-
-private:
- wp<MessageHandler> mHandler;
-};
-
-
-/**
- * A polling loop that supports monitoring file descriptor events, optionally
- * using callbacks. The implementation uses epoll() internally.
- *
- * A looper can be associated with a thread although there is no requirement that it must be.
- */
-class Looper : public ALooper, public RefBase {
-protected:
- virtual ~Looper();
-
-public:
- /**
- * Creates a looper.
- *
- * If allowNonCallbaks is true, the looper will allow file descriptors to be
- * registered without associated callbacks. This assumes that the caller of
- * pollOnce() is prepared to handle callback-less events itself.
- */
- Looper(bool allowNonCallbacks);
-
- /**
- * Returns whether this looper instance allows the registration of file descriptors
- * using identifiers instead of callbacks.
- */
- bool getAllowNonCallbacks() const;
-
- /**
- * Waits for events to be available, with optional timeout in milliseconds.
- * Invokes callbacks for all file descriptors on which an event occurred.
- *
- * If the timeout is zero, returns immediately without blocking.
- * If the timeout is negative, waits indefinitely until an event appears.
- *
- * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
- * the timeout expired and no callbacks were invoked and no other file
- * descriptors were ready.
- *
- * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
- *
- * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
- * timeout expired.
- *
- * Returns ALOOPER_POLL_ERROR if an error occurred.
- *
- * Returns a value >= 0 containing an identifier if its file descriptor has data
- * and it has no callback function (requiring the caller here to handle it).
- * In this (and only this) case outFd, outEvents and outData will contain the poll
- * events and data associated with the fd, otherwise they will be set to NULL.
- *
- * This method does not return until it has finished invoking the appropriate callbacks
- * for all file descriptors that were signalled.
- */
- int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
- inline int pollOnce(int timeoutMillis) {
- return pollOnce(timeoutMillis, NULL, NULL, NULL);
- }
-
- /**
- * Like pollOnce(), but performs all pending callbacks until all
- * data has been consumed or a file descriptor is available with no callback.
- * This function will never return ALOOPER_POLL_CALLBACK.
- */
- int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
- inline int pollAll(int timeoutMillis) {
- return pollAll(timeoutMillis, NULL, NULL, NULL);
- }
-
- /**
- * Wakes the poll asynchronously.
- *
- * This method can be called on any thread.
- * This method returns immediately.
- */
- void wake();
-
- /**
- * Adds a new file descriptor to be polled by the looper.
- * If the same file descriptor was previously added, it is replaced.
- *
- * "fd" is the file descriptor to be added.
- * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
- * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
- * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT.
- * "callback" is the function to call when there is an event on the file descriptor.
- * "data" is a private data pointer to supply to the callback.
- *
- * There are two main uses of this function:
- *
- * (1) If "callback" is non-NULL, then this function will be called when there is
- * data on the file descriptor. It should execute any events it has pending,
- * appropriately reading from the file descriptor. The 'ident' is ignored in this case.
- *
- * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
- * when its file descriptor has data available, requiring the caller to take
- * care of processing it.
- *
- * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
- *
- * This method can be called on any thread.
- * This method may block briefly if it needs to wake the poll.
- */
- int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data);
-
- /**
- * Removes a previously added file descriptor from the looper.
- *
- * When this method returns, it is safe to close the file descriptor since the looper
- * will no longer have a reference to it. However, it is possible for the callback to
- * already be running or for it to run one last time if the file descriptor was already
- * signalled. Calling code is responsible for ensuring that this case is safely handled.
- * For example, if the callback takes care of removing itself during its own execution either
- * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
- * again at any later time unless registered anew.
- *
- * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
- *
- * This method can be called on any thread.
- * This method may block briefly if it needs to wake the poll.
- */
- int removeFd(int fd);
-
- /**
- * Enqueues a message to be processed by the specified handler.
- *
- * The handler must not be null.
- * This method can be called on any thread.
- */
- void sendMessage(const sp<MessageHandler>& handler, const Message& message);
-
- /**
- * Enqueues a message to be processed by the specified handler after all pending messages
- * after the specified delay.
- *
- * The time delay is specified in uptime nanoseconds.
- * The handler must not be null.
- * This method can be called on any thread.
- */
- void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
- const Message& message);
-
- /**
- * Enqueues a message to be processed by the specified handler after all pending messages
- * at the specified time.
- *
- * The time is specified in uptime nanoseconds.
- * The handler must not be null.
- * This method can be called on any thread.
- */
- void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
- const Message& message);
-
- /**
- * Removes all messages for the specified handler from the queue.
- *
- * The handler must not be null.
- * This method can be called on any thread.
- */
- void removeMessages(const sp<MessageHandler>& handler);
-
- /**
- * Removes all messages of a particular type for the specified handler from the queue.
- *
- * The handler must not be null.
- * This method can be called on any thread.
- */
- void removeMessages(const sp<MessageHandler>& handler, int what);
-
- /**
- * Prepares a looper associated with the calling thread, and returns it.
- * If the thread already has a looper, it is returned. Otherwise, a new
- * one is created, associated with the thread, and returned.
- *
- * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
- */
- static sp<Looper> prepare(int opts);
-
- /**
- * Sets the given looper to be associated with the calling thread.
- * If another looper is already associated with the thread, it is replaced.
- *
- * If "looper" is NULL, removes the currently associated looper.
- */
- static void setForThread(const sp<Looper>& looper);
-
- /**
- * Returns the looper associated with the calling thread, or NULL if
- * there is not one.
- */
- static sp<Looper> getForThread();
-
-private:
- struct Request {
- int fd;
- int ident;
- ALooper_callbackFunc callback;
- void* data;
- };
-
- struct Response {
- int events;
- Request request;
- };
-
- struct MessageEnvelope {
- MessageEnvelope() : uptime(0) { }
-
- MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
- const Message& message) : uptime(uptime), handler(handler), message(message) {
- }
-
- nsecs_t uptime;
- sp<MessageHandler> handler;
- Message message;
- };
-
- const bool mAllowNonCallbacks; // immutable
-
- int mWakeReadPipeFd; // immutable
- int mWakeWritePipeFd; // immutable
- Mutex mLock;
-
- Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
- bool mSendingMessage; // guarded by mLock
-
-#ifdef LOOPER_USES_EPOLL
- int mEpollFd; // immutable
-
- // Locked list of file descriptor monitoring requests.
- KeyedVector<int, Request> mRequests; // guarded by mLock
-#else
- // The lock guards state used to track whether there is a poll() in progress and whether
- // there are any other threads waiting in wakeAndLock(). The condition variables
- // are used to transfer control among these threads such that all waiters are
- // serviced before a new poll can begin.
- // The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake
- // until mPolling becomes false, then decrements mWaiters again.
- // The poll() method blocks on mResume until mWaiters becomes 0, then sets
- // mPolling to true, blocks until the poll completes, then resets mPolling to false
- // and signals mResume if there are waiters.
- bool mPolling; // guarded by mLock
- uint32_t mWaiters; // guarded by mLock
- Condition mAwake; // guarded by mLock
- Condition mResume; // guarded by mLock
-
- Vector<struct pollfd> mRequestedFds; // must hold mLock and mPolling must be false to modify
- Vector<Request> mRequests; // must hold mLock and mPolling must be false to modify
-
- ssize_t getRequestIndexLocked(int fd);
- void wakeAndLock();
-#endif
-
-#ifdef LOOPER_STATISTICS
- static const int SAMPLED_WAKE_CYCLES_TO_AGGREGATE = 100;
- static const int SAMPLED_POLLS_TO_AGGREGATE = 1000;
-
- nsecs_t mPendingWakeTime;
- int mPendingWakeCount;
-
- int mSampledWakeCycles;
- int mSampledWakeCountSum;
- nsecs_t mSampledWakeLatencySum;
-
- int mSampledPolls;
- int mSampledZeroPollCount;
- int mSampledZeroPollLatencySum;
- int mSampledTimeoutPollCount;
- int mSampledTimeoutPollLatencySum;
-#endif
-
- // This state is only used privately by pollOnce and does not require a lock since
- // it runs on a single thread.
- Vector<Response> mResponses;
- size_t mResponseIndex;
- nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
-
- int pollInner(int timeoutMillis);
- void awoken();
- void pushResponse(int events, const Request& request);
-
- static void initTLSKey();
- static void threadDestructor(void *st);
-};
-
-} // namespace android
-
-#endif // UTILS_LOOPER_H