Looper.h revision 7901eb25c60b1df00050d6c3772505d8dcfcdab9
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     */
867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int pollOnce(int timeoutMillis,
877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int* outFd = NULL, int* outEvents = NULL, void** outData = NULL);
887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Like pollOnce(), but performs all pending callbacks until all
917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * data has been consumed or a file descriptor is available with no callback.
927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This function will never return ALOOPER_POLL_CALLBACK.
937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int pollAll(int timeoutMillis,
957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int* outFd = NULL, int* outEvents = NULL, void** outData = NULL);
967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Wakes the poll asynchronously.
997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method can be called on any thread.
1017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method returns immediately.
1027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    void wake();
1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Adds a new file descriptor to be polled by the looper.
1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If the same file descriptor was previously added, it is replaced.
1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "fd" is the file descriptor to be added.
1107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
1117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
1127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
1137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "callback" is the function to call when there is an event on the file descriptor.
1147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * "data" is a private data pointer to supply to the callback.
1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * There are two main uses of this function:
1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * (1) If "callback" is non-NULL, then this function will be called when there is
1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * data on the file descriptor.  It should execute any events it has pending,
1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * when its file descriptor has data available, requiring the caller to take
1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * care of processing it.
1257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method can be called on any thread.
1297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method may block briefly if it needs to wake the poll.
1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int addFd(int fd, int ident,
1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int events, ALooper_callbackFunc callback, void* data = NULL);
1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Removes a previously added file descriptor from the looper.
1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * When this method returns, it is safe to close the file descriptor since the looper
1387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * will no longer have a reference to it.  However, it is possible for the callback to
1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * already be running or for it to run one last time if the file descriptor was already
1407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * signalled.  Calling code is responsible for ensuring that this case is safely handled.
1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * For example, if the callback takes care of removing itself during its own execution either
1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * again at any later time unless registered anew.
1447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method can be called on any thread.
1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * This method may block briefly if it needs to wake the poll.
1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int removeFd(int fd);
1517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Prepares a looper associated with the calling thread, and returns it.
1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If the thread already has a looper, it is returned.  Otherwise, a new
1557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * one is created, associated with the thread, and returned.
1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static sp<Looper> prepare(int opts);
1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Sets the given looper to be associated with the calling thread.
1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If another looper is already associated with the thread, it is replaced.
1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     *
1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * If "looper" is NULL, removes the currently associated looper.
1667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static void setForThread(const sp<Looper>& looper);
1687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    /**
1707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * Returns the looper associated with the calling thread, or NULL if
1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     * there is not one.
1727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown     */
1737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static sp<Looper> getForThread();
1747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownprivate:
1767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct Request {
1777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int fd;
1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int ident;
1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ALooper_callbackFunc callback;
1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        void* data;
1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    };
1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct Response {
1847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int events;
1857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Request request;
1867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    };
1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    const bool mAllowNonCallbacks; // immutable
1897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int mEpollFd; // immutable
1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int mWakeReadPipeFd;  // immutable
1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int mWakeWritePipeFd; // immutable
1937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    // Locked list of file descriptor monitoring requests.
1957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Mutex mLock;
1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    KeyedVector<int, Request> mRequests;
1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    // This state is only used privately by pollOnce and does not require a lock since
1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    // it runs on a single thread.
2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Vector<Response> mResponses;
2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    size_t mResponseIndex;
2027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int pollInner(int timeoutMillis);
2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    static void threadDestructor(void *st);
2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown};
2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android
2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif // UTILS_LOOPER_H
211