Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef UTILS_LOOPER_H
     18 #define UTILS_LOOPER_H
     19 
     20 #include <utils/threads.h>
     21 #include <utils/RefBase.h>
     22 #include <utils/KeyedVector.h>
     23 #include <utils/Timers.h>
     24 
     25 #include <android/looper.h>
     26 
     27 #include <sys/epoll.h>
     28 
     29 /*
     30  * Declare a concrete type for the NDK's looper forward declaration.
     31  */
     32 struct ALooper {
     33 };
     34 
     35 namespace android {
     36 
     37 /**
     38  * A message that can be posted to a Looper.
     39  */
     40 struct Message {
     41     Message() : what(0) { }
     42     Message(int what) : what(what) { }
     43 
     44     /* The message type. (interpretation is left up to the handler) */
     45     int what;
     46 };
     47 
     48 
     49 /**
     50  * Interface for a Looper message handler.
     51  *
     52  * The Looper holds a strong reference to the message handler whenever it has
     53  * a message to deliver to it.  Make sure to call Looper::removeMessages
     54  * to remove any pending messages destined for the handler so that the handler
     55  * can be destroyed.
     56  */
     57 class MessageHandler : public virtual RefBase {
     58 protected:
     59     virtual ~MessageHandler() { }
     60 
     61 public:
     62     /**
     63      * Handles a message.
     64      */
     65     virtual void handleMessage(const Message& message) = 0;
     66 };
     67 
     68 
     69 /**
     70  * A simple proxy that holds a weak reference to a message handler.
     71  */
     72 class WeakMessageHandler : public MessageHandler {
     73 protected:
     74     virtual ~WeakMessageHandler();
     75 
     76 public:
     77     WeakMessageHandler(const wp<MessageHandler>& handler);
     78     virtual void handleMessage(const Message& message);
     79 
     80 private:
     81     wp<MessageHandler> mHandler;
     82 };
     83 
     84 
     85 /**
     86  * A looper callback.
     87  */
     88 class LooperCallback : public virtual RefBase {
     89 protected:
     90     virtual ~LooperCallback() { }
     91 
     92 public:
     93     /**
     94      * Handles a poll event for the given file descriptor.
     95      * It is given the file descriptor it is associated with,
     96      * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
     97      * and the data pointer that was originally supplied.
     98      *
     99      * Implementations should return 1 to continue receiving callbacks, or 0
    100      * to have this file descriptor and callback unregistered from the looper.
    101      */
    102     virtual int handleEvent(int fd, int events, void* data) = 0;
    103 };
    104 
    105 
    106 /**
    107  * Wraps a ALooper_callbackFunc function pointer.
    108  */
    109 class SimpleLooperCallback : public LooperCallback {
    110 protected:
    111     virtual ~SimpleLooperCallback();
    112 
    113 public:
    114     SimpleLooperCallback(ALooper_callbackFunc callback);
    115     virtual int handleEvent(int fd, int events, void* data);
    116 
    117 private:
    118     ALooper_callbackFunc mCallback;
    119 };
    120 
    121 
    122 /**
    123  * A polling loop that supports monitoring file descriptor events, optionally
    124  * using callbacks.  The implementation uses epoll() internally.
    125  *
    126  * A looper can be associated with a thread although there is no requirement that it must be.
    127  */
    128 class Looper : public ALooper, public RefBase {
    129 protected:
    130     virtual ~Looper();
    131 
    132 public:
    133     /**
    134      * Creates a looper.
    135      *
    136      * If allowNonCallbaks is true, the looper will allow file descriptors to be
    137      * registered without associated callbacks.  This assumes that the caller of
    138      * pollOnce() is prepared to handle callback-less events itself.
    139      */
    140     Looper(bool allowNonCallbacks);
    141 
    142     /**
    143      * Returns whether this looper instance allows the registration of file descriptors
    144      * using identifiers instead of callbacks.
    145      */
    146     bool getAllowNonCallbacks() const;
    147 
    148     /**
    149      * Waits for events to be available, with optional timeout in milliseconds.
    150      * Invokes callbacks for all file descriptors on which an event occurred.
    151      *
    152      * If the timeout is zero, returns immediately without blocking.
    153      * If the timeout is negative, waits indefinitely until an event appears.
    154      *
    155      * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
    156      * the timeout expired and no callbacks were invoked and no other file
    157      * descriptors were ready.
    158      *
    159      * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
    160      *
    161      * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
    162      * timeout expired.
    163      *
    164      * Returns ALOOPER_POLL_ERROR if an error occurred.
    165      *
    166      * Returns a value >= 0 containing an identifier if its file descriptor has data
    167      * and it has no callback function (requiring the caller here to handle it).
    168      * In this (and only this) case outFd, outEvents and outData will contain the poll
    169      * events and data associated with the fd, otherwise they will be set to NULL.
    170      *
    171      * This method does not return until it has finished invoking the appropriate callbacks
    172      * for all file descriptors that were signalled.
    173      */
    174     int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
    175     inline int pollOnce(int timeoutMillis) {
    176         return pollOnce(timeoutMillis, NULL, NULL, NULL);
    177     }
    178 
    179     /**
    180      * Like pollOnce(), but performs all pending callbacks until all
    181      * data has been consumed or a file descriptor is available with no callback.
    182      * This function will never return ALOOPER_POLL_CALLBACK.
    183      */
    184     int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
    185     inline int pollAll(int timeoutMillis) {
    186         return pollAll(timeoutMillis, NULL, NULL, NULL);
    187     }
    188 
    189     /**
    190      * Wakes the poll asynchronously.
    191      *
    192      * This method can be called on any thread.
    193      * This method returns immediately.
    194      */
    195     void wake();
    196 
    197     /**
    198      * Adds a new file descriptor to be polled by the looper.
    199      * If the same file descriptor was previously added, it is replaced.
    200      *
    201      * "fd" is the file descriptor to be added.
    202      * "ident" is an identifier for this event, which is returned from pollOnce().
    203      * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
    204      * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
    205      * "callback" is the function to call when there is an event on the file descriptor.
    206      * "data" is a private data pointer to supply to the callback.
    207      *
    208      * There are two main uses of this function:
    209      *
    210      * (1) If "callback" is non-NULL, then this function will be called when there is
    211      * data on the file descriptor.  It should execute any events it has pending,
    212      * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
    213      *
    214      * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
    215      * when its file descriptor has data available, requiring the caller to take
    216      * care of processing it.
    217      *
    218      * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
    219      *
    220      * This method can be called on any thread.
    221      * This method may block briefly if it needs to wake the poll.
    222      *
    223      * The callback may either be specified as a bare function pointer or as a smart
    224      * pointer callback object.  The smart pointer should be preferred because it is
    225      * easier to avoid races when the callback is removed from a different thread.
    226      * See removeFd() for details.
    227      */
    228     int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data);
    229     int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data);
    230 
    231     /**
    232      * Removes a previously added file descriptor from the looper.
    233      *
    234      * When this method returns, it is safe to close the file descriptor since the looper
    235      * will no longer have a reference to it.  However, it is possible for the callback to
    236      * already be running or for it to run one last time if the file descriptor was already
    237      * signalled.  Calling code is responsible for ensuring that this case is safely handled.
    238      * For example, if the callback takes care of removing itself during its own execution either
    239      * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
    240      * again at any later time unless registered anew.
    241      *
    242      * A simple way to avoid this problem is to use the version of addFd() that takes
    243      * a sp<LooperCallback> instead of a bare function pointer.  The LooperCallback will
    244      * be released at the appropriate time by the Looper.
    245      *
    246      * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
    247      *
    248      * This method can be called on any thread.
    249      * This method may block briefly if it needs to wake the poll.
    250      */
    251     int removeFd(int fd);
    252 
    253     /**
    254      * Enqueues a message to be processed by the specified handler.
    255      *
    256      * The handler must not be null.
    257      * This method can be called on any thread.
    258      */
    259     void sendMessage(const sp<MessageHandler>& handler, const Message& message);
    260 
    261     /**
    262      * Enqueues a message to be processed by the specified handler after all pending messages
    263      * after the specified delay.
    264      *
    265      * The time delay is specified in uptime nanoseconds.
    266      * The handler must not be null.
    267      * This method can be called on any thread.
    268      */
    269     void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
    270             const Message& message);
    271 
    272     /**
    273      * Enqueues a message to be processed by the specified handler after all pending messages
    274      * at the specified time.
    275      *
    276      * The time is specified in uptime nanoseconds.
    277      * The handler must not be null.
    278      * This method can be called on any thread.
    279      */
    280     void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
    281             const Message& message);
    282 
    283     /**
    284      * Removes all messages for the specified handler from the queue.
    285      *
    286      * The handler must not be null.
    287      * This method can be called on any thread.
    288      */
    289     void removeMessages(const sp<MessageHandler>& handler);
    290 
    291     /**
    292      * Removes all messages of a particular type for the specified handler from the queue.
    293      *
    294      * The handler must not be null.
    295      * This method can be called on any thread.
    296      */
    297     void removeMessages(const sp<MessageHandler>& handler, int what);
    298 
    299     /**
    300      * Return whether this looper's thread is currently idling -- that is, whether it
    301      * stopped waiting for more work to do.  Note that this is intrinsically racy, since
    302      * its state can change before you get the result back.
    303      */
    304     bool isIdling() const;
    305 
    306     /**
    307      * Prepares a looper associated with the calling thread, and returns it.
    308      * If the thread already has a looper, it is returned.  Otherwise, a new
    309      * one is created, associated with the thread, and returned.
    310      *
    311      * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
    312      */
    313     static sp<Looper> prepare(int opts);
    314 
    315     /**
    316      * Sets the given looper to be associated with the calling thread.
    317      * If another looper is already associated with the thread, it is replaced.
    318      *
    319      * If "looper" is NULL, removes the currently associated looper.
    320      */
    321     static void setForThread(const sp<Looper>& looper);
    322 
    323     /**
    324      * Returns the looper associated with the calling thread, or NULL if
    325      * there is not one.
    326      */
    327     static sp<Looper> getForThread();
    328 
    329 private:
    330     struct Request {
    331         int fd;
    332         int ident;
    333         sp<LooperCallback> callback;
    334         void* data;
    335     };
    336 
    337     struct Response {
    338         int events;
    339         Request request;
    340     };
    341 
    342     struct MessageEnvelope {
    343         MessageEnvelope() : uptime(0) { }
    344 
    345         MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
    346                 const Message& message) : uptime(uptime), handler(handler), message(message) {
    347         }
    348 
    349         nsecs_t uptime;
    350         sp<MessageHandler> handler;
    351         Message message;
    352     };
    353 
    354     const bool mAllowNonCallbacks; // immutable
    355 
    356     int mWakeReadPipeFd;  // immutable
    357     int mWakeWritePipeFd; // immutable
    358     Mutex mLock;
    359 
    360     Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
    361     bool mSendingMessage; // guarded by mLock
    362 
    363     // Whether we are currently waiting for work.  Not protected by a lock,
    364     // any use of it is racy anyway.
    365     volatile bool mIdling;
    366 
    367     int mEpollFd; // immutable
    368 
    369     // Locked list of file descriptor monitoring requests.
    370     KeyedVector<int, Request> mRequests;  // guarded by mLock
    371 
    372     // This state is only used privately by pollOnce and does not require a lock since
    373     // it runs on a single thread.
    374     Vector<Response> mResponses;
    375     size_t mResponseIndex;
    376     nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
    377 
    378     int pollInner(int timeoutMillis);
    379     void awoken();
    380     void pushResponse(int events, const Request& request);
    381 
    382     static void initTLSKey();
    383     static void threadDestructor(void *st);
    384 };
    385 
    386 } // namespace android
    387 
    388 #endif // UTILS_LOOPER_H
    389