Looper.h revision 905682a19609e862633f01e69bec58384df2cdf7
17901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown/*
27901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Copyright (C) 2010 The Android Open Source Project
37901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown *
47901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
57901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * you may not use this file except in compliance with the License.
67901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * You may obtain a copy of the License at
77901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown *
87901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
97901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown *
107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Unless required by applicable law or agreed to in writing, software
117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * See the License for the specific language governing permissions and
147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * limitations under the License.
157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */
167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#ifndef UTILS_LOOPER_H
187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define UTILS_LOOPER_H
197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/threads.h>
217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/RefBase.h>
227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/KeyedVector.h>
237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <android/looper.h>
257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown/*
277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Declare a concrete type for the NDK's looper forward declaration.
287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */
297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstruct ALooper {
307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown};
317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android {
337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown/**
357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * A polling loop that supports monitoring file descriptor events, optionally
367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * using callbacks.  The implementation uses epoll() internally.
377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown *
387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * A looper can be associated with a thread although there is no requirement that it must be.
397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */
407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownclass Looper : public ALooper, public RefBase {
417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownprotected:
427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    virtual ~Looper();
437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownpublic:
457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Creates a looper.
477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If allowNonCallbaks is true, the looper will allow file descriptors to be
497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * registered without associated callbacks.  This assumes that the caller of
507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * pollOnce() is prepared to handle callback-less events itself.
517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Looper(bool allowNonCallbacks);
537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns whether this looper instance allows the registration of file descriptors
567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * using identifiers instead of callbacks.
577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    bool getAllowNonCallbacks() const;
597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Waits for events to be available, with optional timeout in milliseconds.
627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Invokes callbacks for all file descriptors on which an event occurred.
637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If the timeout is zero, returns immediately without blocking.
657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If the timeout is negative, waits indefinitely until an event appears.
667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * the timeout expired and no callbacks were invoked and no other file
697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * descriptors were ready.
707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * timeout expired.
757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns ALOOPER_POLL_ERROR if an error occurred.
777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns a value >= 0 containing an identifier if its file descriptor has data
797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * and it has no callback function (requiring the caller here to handle it).
807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * In this (and only this) case outFd, outEvents and outData will contain the poll
817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * events and data associated with the fd, otherwise they will be set to NULL.
827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method does not return until it has finished invoking the appropriate callbacks
847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * for all file descriptors that were signalled.
857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
86905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
87905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    inline int pollOnce(int timeoutMillis) {
88905682a19609e862633f01e69bec58384df2cdf7Jeff Brown        return pollOnce(timeoutMillis, NULL, NULL, NULL);
89905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    }
907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Like pollOnce(), but performs all pending callbacks until all
937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * data has been consumed or a file descriptor is available with no callback.
947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This function will never return ALOOPER_POLL_CALLBACK.
957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
96905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
97905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    inline int pollAll(int timeoutMillis) {
98905682a19609e862633f01e69bec58384df2cdf7Jeff Brown        return pollAll(timeoutMillis, NULL, NULL, NULL);
99905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    }
1007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Wakes the poll asynchronously.
1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method can be called on any thread.
1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method returns immediately.
1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    void wake();
1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Adds a new file descriptor to be polled by the looper.
1117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If the same file descriptor was previously added, it is replaced.
1127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "fd" is the file descriptor to be added.
1147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "callback" is the function to call when there is an event on the file descriptor.
1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "data" is a private data pointer to supply to the callback.
1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * There are two main uses of this function:
1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * (1) If "callback" is non-NULL, then this function will be called when there is
1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * data on the file descriptor.  It should execute any events it has pending,
1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
1257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * when its file descriptor has data available, requiring the caller to take
1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * care of processing it.
1297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method can be called on any thread.
1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method may block briefly if it needs to wake the poll.
1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
135905682a19609e862633f01e69bec58384df2cdf7Jeff Brown    int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data);
1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Removes a previously added file descriptor from the looper.
1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * When this method returns, it is safe to close the file descriptor since the looper
1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * will no longer have a reference to it.  However, it is possible for the callback to
1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * already be running or for it to run one last time if the file descriptor was already
1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * signalled.  Calling code is responsible for ensuring that this case is safely handled.
1447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * For example, if the callback takes care of removing itself during its own execution either
1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * again at any later time unless registered anew.
1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method can be called on any thread.
1517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method may block briefly if it needs to wake the poll.
1527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int removeFd(int fd);
1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Prepares a looper associated with the calling thread, and returns it.
1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If the thread already has a looper, it is returned.  Otherwise, a new
1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * one is created, associated with the thread, and returned.
1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static sp<Looper> prepare(int opts);
1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Sets the given looper to be associated with the calling thread.
1667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If another looper is already associated with the thread, it is replaced.
1677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If "looper" is NULL, removes the currently associated looper.
1697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static void setForThread(const sp<Looper>& looper);
1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns the looper associated with the calling thread, or NULL if
1747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * there is not one.
1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static sp<Looper> getForThread();
1777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownprivate:
1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct Request {
1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int fd;
1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int ident;
1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ALooper_callbackFunc callback;
1837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        void* data;
1847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    };
1857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct Response {
1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int events;
1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Request request;
1897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    };
1907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    const bool mAllowNonCallbacks; // immutable
1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int mEpollFd; // immutable
1947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int mWakeReadPipeFd;  // immutable
1957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int mWakeWritePipeFd; // immutable
1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    // Locked list of file descriptor monitoring requests.
1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Mutex mLock;
1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    KeyedVector<int, Request> mRequests;
2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    // This state is only used privately by pollOnce and does not require a lock since
2027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    // it runs on a single thread.
2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Vector<Response> mResponses;
2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    size_t mResponseIndex;
2057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int pollInner(int timeoutMillis);
2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static void threadDestructor(void *st);
2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown};
2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android
2127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif // UTILS_LOOPER_H
214