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