Home | History | Annotate | Download | only in android
      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 /**
     18  * @addtogroup Looper
     19  * @{
     20  */
     21 
     22 /**
     23  * @file looper.h
     24  */
     25 
     26 #ifndef ANDROID_LOOPER_H
     27 #define ANDROID_LOOPER_H
     28 
     29 #ifdef __cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 struct ALooper;
     34 /**
     35  * ALooper
     36  *
     37  * A looper is the state tracking an event loop for a thread.
     38  * Loopers do not define event structures or other such things; rather
     39  * they are a lower-level facility to attach one or more discrete objects
     40  * listening for an event.  An "event" here is simply data available on
     41  * a file descriptor: each attached object has an associated file descriptor,
     42  * and waiting for "events" means (internally) polling on all of these file
     43  * descriptors until one or more of them have data available.
     44  *
     45  * A thread can have only one ALooper associated with it.
     46  */
     47 typedef struct ALooper ALooper;
     48 
     49 /**
     50  * Returns the looper associated with the calling thread, or NULL if
     51  * there is not one.
     52  */
     53 ALooper* ALooper_forThread();
     54 
     55 /** Option for for ALooper_prepare(). */
     56 enum {
     57     /**
     58      * This looper will accept calls to ALooper_addFd() that do not
     59      * have a callback (that is provide NULL for the callback).  In
     60      * this case the caller of ALooper_pollOnce() or ALooper_pollAll()
     61      * MUST check the return from these functions to discover when
     62      * data is available on such fds and process it.
     63      */
     64     ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1<<0
     65 };
     66 
     67 /**
     68  * Prepares a looper associated with the calling thread, and returns it.
     69  * If the thread already has a looper, it is returned.  Otherwise, a new
     70  * one is created, associated with the thread, and returned.
     71  *
     72  * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
     73  */
     74 ALooper* ALooper_prepare(int opts);
     75 
     76 /** Result from ALooper_pollOnce() and ALooper_pollAll(). */
     77 enum {
     78     /**
     79      * The poll was awoken using wake() before the timeout expired
     80      * and no callbacks were executed and no other file descriptors were ready.
     81      */
     82     ALOOPER_POLL_WAKE = -1,
     83 
     84     /**
     85      * Result from ALooper_pollOnce() and ALooper_pollAll():
     86      * One or more callbacks were executed.
     87      */
     88     ALOOPER_POLL_CALLBACK = -2,
     89 
     90     /**
     91      * Result from ALooper_pollOnce() and ALooper_pollAll():
     92      * The timeout expired.
     93      */
     94     ALOOPER_POLL_TIMEOUT = -3,
     95 
     96     /**
     97      * Result from ALooper_pollOnce() and ALooper_pollAll():
     98      * An error occurred.
     99      */
    100     ALOOPER_POLL_ERROR = -4,
    101 };
    102 
    103 /**
    104  * Acquire a reference on the given ALooper object.  This prevents the object
    105  * from being deleted until the reference is removed.  This is only needed
    106  * to safely hand an ALooper from one thread to another.
    107  */
    108 void ALooper_acquire(ALooper* looper);
    109 
    110 /**
    111  * Remove a reference that was previously acquired with ALooper_acquire().
    112  */
    113 void ALooper_release(ALooper* looper);
    114 
    115 /**
    116  * Flags for file descriptor events that a looper can monitor.
    117  *
    118  * These flag bits can be combined to monitor multiple events at once.
    119  */
    120 enum {
    121     /**
    122      * The file descriptor is available for read operations.
    123      */
    124     ALOOPER_EVENT_INPUT = 1 << 0,
    125 
    126     /**
    127      * The file descriptor is available for write operations.
    128      */
    129     ALOOPER_EVENT_OUTPUT = 1 << 1,
    130 
    131     /**
    132      * The file descriptor has encountered an error condition.
    133      *
    134      * The looper always sends notifications about errors; it is not necessary
    135      * to specify this event flag in the requested event set.
    136      */
    137     ALOOPER_EVENT_ERROR = 1 << 2,
    138 
    139     /**
    140      * The file descriptor was hung up.
    141      * For example, indicates that the remote end of a pipe or socket was closed.
    142      *
    143      * The looper always sends notifications about hangups; it is not necessary
    144      * to specify this event flag in the requested event set.
    145      */
    146     ALOOPER_EVENT_HANGUP = 1 << 3,
    147 
    148     /**
    149      * The file descriptor is invalid.
    150      * For example, the file descriptor was closed prematurely.
    151      *
    152      * The looper always sends notifications about invalid file descriptors; it is not necessary
    153      * to specify this event flag in the requested event set.
    154      */
    155     ALOOPER_EVENT_INVALID = 1 << 4,
    156 };
    157 
    158 /**
    159  * For callback-based event loops, this is the prototype of the function
    160  * that is called when a file descriptor event occurs.
    161  * It is given the file descriptor it is associated with,
    162  * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
    163  * and the data pointer that was originally supplied.
    164  *
    165  * Implementations should return 1 to continue receiving callbacks, or 0
    166  * to have this file descriptor and callback unregistered from the looper.
    167  */
    168 typedef int (*ALooper_callbackFunc)(int fd, int events, void* data);
    169 
    170 /**
    171  * Waits for events to be available, with optional timeout in milliseconds.
    172  * Invokes callbacks for all file descriptors on which an event occurred.
    173  *
    174  * If the timeout is zero, returns immediately without blocking.
    175  * If the timeout is negative, waits indefinitely until an event appears.
    176  *
    177  * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
    178  * the timeout expired and no callbacks were invoked and no other file
    179  * descriptors were ready.
    180  *
    181  * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
    182  *
    183  * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
    184  * timeout expired.
    185  *
    186  * Returns ALOOPER_POLL_ERROR if an error occurred.
    187  *
    188  * Returns a value >= 0 containing an identifier (the same identifier
    189  * `ident` passed to ALooper_addFd()) if its file descriptor has data
    190  * and it has no callback function (requiring the caller here to
    191  * handle it).  In this (and only this) case outFd, outEvents and
    192  * outData will contain the poll events and data associated with the
    193  * fd, otherwise they will be set to NULL.
    194  *
    195  * This method does not return until it has finished invoking the appropriate callbacks
    196  * for all file descriptors that were signalled.
    197  */
    198 int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
    199 
    200 /**
    201  * Like ALooper_pollOnce(), but performs all pending callbacks until all
    202  * data has been consumed or a file descriptor is available with no callback.
    203  * This function will never return ALOOPER_POLL_CALLBACK.
    204  */
    205 int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
    206 
    207 /**
    208  * Wakes the poll asynchronously.
    209  *
    210  * This method can be called on any thread.
    211  * This method returns immediately.
    212  */
    213 void ALooper_wake(ALooper* looper);
    214 
    215 /**
    216  * Adds a new file descriptor to be polled by the looper.
    217  * If the same file descriptor was previously added, it is replaced.
    218  *
    219  * "fd" is the file descriptor to be added.
    220  * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
    221  * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
    222  * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
    223  * "callback" is the function to call when there is an event on the file descriptor.
    224  * "data" is a private data pointer to supply to the callback.
    225  *
    226  * There are two main uses of this function:
    227  *
    228  * (1) If "callback" is non-NULL, then this function will be called when there is
    229  * data on the file descriptor.  It should execute any events it has pending,
    230  * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
    231  *
    232  * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
    233  * when its file descriptor has data available, requiring the caller to take
    234  * care of processing it.
    235  *
    236  * Returns 1 if the file descriptor was added or -1 if an error occurred.
    237  *
    238  * This method can be called on any thread.
    239  * This method may block briefly if it needs to wake the poll.
    240  */
    241 int ALooper_addFd(ALooper* looper, int fd, int ident, int events,
    242         ALooper_callbackFunc callback, void* data);
    243 
    244 /**
    245  * Removes a previously added file descriptor from the looper.
    246  *
    247  * When this method returns, it is safe to close the file descriptor since the looper
    248  * will no longer have a reference to it.  However, it is possible for the callback to
    249  * already be running or for it to run one last time if the file descriptor was already
    250  * signalled.  Calling code is responsible for ensuring that this case is safely handled.
    251  * For example, if the callback takes care of removing itself during its own execution either
    252  * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
    253  * again at any later time unless registered anew.
    254  *
    255  * Returns 1 if the file descriptor was removed, 0 if none was previously registered
    256  * or -1 if an error occurred.
    257  *
    258  * This method can be called on any thread.
    259  * This method may block briefly if it needs to wake the poll.
    260  */
    261 int ALooper_removeFd(ALooper* looper, int fd);
    262 
    263 #ifdef __cplusplus
    264 };
    265 #endif
    266 
    267 #endif // ANDROID_LOOPER_H
    268 
    269 /** @} */
    270