blob: 8cf13965bb424479f3ae3f4d46dc5df4b34cb697 [file] [log] [blame]
Mathias Agopiane1c61d32012-03-23 14:19:36 -07001/*
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
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -070017/**
18 * @addtogroup Looper
19 * @{
20 */
21
22/**
23 * @file looper.h
24 */
Mathias Agopiane1c61d32012-03-23 14:19:36 -070025
26#ifndef ANDROID_LOOPER_H
27#define ANDROID_LOOPER_H
28
Prashanth Swaminathan1aa9f862023-07-11 10:48:18 -070029#include <sys/cdefs.h>
30
Mathias Agopiane1c61d32012-03-23 14:19:36 -070031#ifdef __cplusplus
32extern "C" {
33#endif
34
Prashanth Swaminathan1aa9f862023-07-11 10:48:18 -070035// This file may also be built on glibc or on Windows/MacOS libc's, so
36// deprecated definitions are provided.
37#if !defined(__REMOVED_IN)
Dan Albertc47ac842024-05-02 20:19:54 +000038#define __REMOVED_IN(__api_level, msg) __attribute__((__deprecated__(msg)))
Prashanth Swaminathan1aa9f862023-07-11 10:48:18 -070039#endif
40
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -070041struct ALooper;
Mathias Agopiane1c61d32012-03-23 14:19:36 -070042/**
43 * ALooper
44 *
45 * A looper is the state tracking an event loop for a thread.
46 * Loopers do not define event structures or other such things; rather
47 * they are a lower-level facility to attach one or more discrete objects
48 * listening for an event. An "event" here is simply data available on
49 * a file descriptor: each attached object has an associated file descriptor,
50 * and waiting for "events" means (internally) polling on all of these file
51 * descriptors until one or more of them have data available.
52 *
53 * A thread can have only one ALooper associated with it.
54 */
Mathias Agopiane1c61d32012-03-23 14:19:36 -070055typedef struct ALooper ALooper;
56
57/**
58 * Returns the looper associated with the calling thread, or NULL if
59 * there is not one.
60 */
61ALooper* ALooper_forThread();
62
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -070063/** Option for for ALooper_prepare(). */
Mathias Agopiane1c61d32012-03-23 14:19:36 -070064enum {
65 /**
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -070066 * This looper will accept calls to ALooper_addFd() that do not
67 * have a callback (that is provide NULL for the callback). In
68 * this case the caller of ALooper_pollOnce() or ALooper_pollAll()
69 * MUST check the return from these functions to discover when
70 * data is available on such fds and process it.
Mathias Agopiane1c61d32012-03-23 14:19:36 -070071 */
72 ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1<<0
73};
74
75/**
76 * Prepares a looper associated with the calling thread, and returns it.
77 * If the thread already has a looper, it is returned. Otherwise, a new
78 * one is created, associated with the thread, and returned.
79 *
80 * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
81 */
82ALooper* ALooper_prepare(int opts);
83
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -070084/** Result from ALooper_pollOnce() and ALooper_pollAll(). */
Mathias Agopiane1c61d32012-03-23 14:19:36 -070085enum {
86 /**
Mathias Agopiane1c61d32012-03-23 14:19:36 -070087 * The poll was awoken using wake() before the timeout expired
88 * and no callbacks were executed and no other file descriptors were ready.
89 */
90 ALOOPER_POLL_WAKE = -1,
91
92 /**
Dan Albert726c1b12024-11-14 20:33:29 +000093 * Result from ALooper_pollOnce():
94 * One or more callbacks were executed. The poll may also have been
95 * explicitly woken by ALooper_wake().
Mathias Agopiane1c61d32012-03-23 14:19:36 -070096 */
97 ALOOPER_POLL_CALLBACK = -2,
98
99 /**
100 * Result from ALooper_pollOnce() and ALooper_pollAll():
Dan Albert726c1b12024-11-14 20:33:29 +0000101 * The timeout expired. The poll may also have been explicitly woken by
102 * ALooper_wake().
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700103 */
104 ALOOPER_POLL_TIMEOUT = -3,
105
106 /**
107 * Result from ALooper_pollOnce() and ALooper_pollAll():
Dan Albert726c1b12024-11-14 20:33:29 +0000108 * An error occurred. The poll may also have been explicitly woken by
109 * ALooper_wake(()).
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700110 */
111 ALOOPER_POLL_ERROR = -4,
112};
113
114/**
115 * Acquire a reference on the given ALooper object. This prevents the object
116 * from being deleted until the reference is removed. This is only needed
117 * to safely hand an ALooper from one thread to another.
118 */
119void ALooper_acquire(ALooper* looper);
120
121/**
122 * Remove a reference that was previously acquired with ALooper_acquire().
123 */
124void ALooper_release(ALooper* looper);
125
126/**
127 * Flags for file descriptor events that a looper can monitor.
128 *
129 * These flag bits can be combined to monitor multiple events at once.
130 */
131enum {
132 /**
133 * The file descriptor is available for read operations.
134 */
135 ALOOPER_EVENT_INPUT = 1 << 0,
136
137 /**
138 * The file descriptor is available for write operations.
139 */
140 ALOOPER_EVENT_OUTPUT = 1 << 1,
141
142 /**
143 * The file descriptor has encountered an error condition.
144 *
145 * The looper always sends notifications about errors; it is not necessary
146 * to specify this event flag in the requested event set.
147 */
148 ALOOPER_EVENT_ERROR = 1 << 2,
149
150 /**
151 * The file descriptor was hung up.
152 * For example, indicates that the remote end of a pipe or socket was closed.
153 *
154 * The looper always sends notifications about hangups; it is not necessary
155 * to specify this event flag in the requested event set.
156 */
157 ALOOPER_EVENT_HANGUP = 1 << 3,
158
159 /**
160 * The file descriptor is invalid.
161 * For example, the file descriptor was closed prematurely.
162 *
163 * The looper always sends notifications about invalid file descriptors; it is not necessary
164 * to specify this event flag in the requested event set.
165 */
166 ALOOPER_EVENT_INVALID = 1 << 4,
167};
168
169/**
170 * For callback-based event loops, this is the prototype of the function
171 * that is called when a file descriptor event occurs.
172 * It is given the file descriptor it is associated with,
173 * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
174 * and the data pointer that was originally supplied.
175 *
176 * Implementations should return 1 to continue receiving callbacks, or 0
177 * to have this file descriptor and callback unregistered from the looper.
178 */
179typedef int (*ALooper_callbackFunc)(int fd, int events, void* data);
180
181/**
182 * Waits for events to be available, with optional timeout in milliseconds.
183 * Invokes callbacks for all file descriptors on which an event occurred.
184 *
185 * If the timeout is zero, returns immediately without blocking.
186 * If the timeout is negative, waits indefinitely until an event appears.
187 *
Dan Albert726c1b12024-11-14 20:33:29 +0000188 * **All return values may also imply ALOOPER_POLL_WAKE.** If you call this in a
189 * loop, you must treat all return values as if they also indicated
190 * ALOOPER_POLL_WAKE.
191 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000192 * Returns ALOOPER_POLL_WAKE if the poll was awoken using ALooper_wake() before
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700193 * the timeout expired and no callbacks were invoked and no other file
Dan Albert726c1b12024-11-14 20:33:29 +0000194 * descriptors were ready.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700195 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000196 * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. The poll
197 * may also have been explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700198 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000199 * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given timeout
200 * expired. The poll may also have been explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700201 *
Dan Albert26620a62024-05-02 23:11:20 +0000202 * Returns ALOOPER_POLL_ERROR if the calling thread has no associated Looper or
203 * for unrecoverable internal errors. The poll may also have been explicitly
204 * woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700205 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000206 * Returns a value >= 0 containing an identifier (the same identifier `ident`
207 * passed to ALooper_addFd()) if its file descriptor has data and it has no
208 * callback function (requiring the caller here to handle it). In this (and
209 * only this) case outFd, outEvents and outData will contain the poll events and
210 * data associated with the fd, otherwise they will be set to NULL. The poll may
211 * also have been explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700212 *
213 * This method does not return until it has finished invoking the appropriate callbacks
214 * for all file descriptors that were signalled.
215 */
216int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
217
218/**
219 * Like ALooper_pollOnce(), but performs all pending callbacks until all
220 * data has been consumed or a file descriptor is available with no callback.
221 * This function will never return ALOOPER_POLL_CALLBACK.
Ady Abraham2a6c1862022-07-28 22:54:19 +0000222 *
Dan Albert726c1b12024-11-14 20:33:29 +0000223 * This API will not reliably respond to ALooper_wake. As such, this API is
224 * hidden and callers should migrate to ALooper_pollOnce. Binary compatibility
225 * is preserved to support already-compiled apps.
Dan Albertb06c7fb2024-05-02 20:20:10 +0000226 *
227 * \bug ALooper_pollAll will not wake in response to ALooper_wake calls if it
228 * also handles another event at the same time.
229 *
230 * \deprecated Calls to ALooper_pollAll should be replaced with
231 * ALooper_pollOnce. If you call ALooper_pollOnce in a loop, you *must* treat
232 * all return values as if they also indicate ALOOPER_POLL_WAKE.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700233 */
Dan Albertc47ac842024-05-02 20:19:54 +0000234int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData)
Dan Albertb06c7fb2024-05-02 20:20:10 +0000235 __REMOVED_IN(1,
236 "ALooper_pollAll may ignore wakes. Use ALooper_pollOnce instead. See "
237 "The API documentation for more information");
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700238
239/**
240 * Wakes the poll asynchronously.
241 *
242 * This method can be called on any thread.
243 * This method returns immediately.
Dan Albert726c1b12024-11-14 20:33:29 +0000244 *
245 * \bug ALooper_pollAll will not reliably wake in response to ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700246 */
247void ALooper_wake(ALooper* looper);
248
249/**
250 * Adds a new file descriptor to be polled by the looper.
251 * If the same file descriptor was previously added, it is replaced.
252 *
253 * "fd" is the file descriptor to be added.
254 * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
255 * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
256 * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT.
257 * "callback" is the function to call when there is an event on the file descriptor.
258 * "data" is a private data pointer to supply to the callback.
259 *
260 * There are two main uses of this function:
261 *
262 * (1) If "callback" is non-NULL, then this function will be called when there is
263 * data on the file descriptor. It should execute any events it has pending,
264 * appropriately reading from the file descriptor. The 'ident' is ignored in this case.
265 *
266 * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
267 * when its file descriptor has data available, requiring the caller to take
268 * care of processing it.
269 *
270 * Returns 1 if the file descriptor was added or -1 if an error occurred.
271 *
272 * This method can be called on any thread.
273 * This method may block briefly if it needs to wake the poll.
274 */
275int ALooper_addFd(ALooper* looper, int fd, int ident, int events,
276 ALooper_callbackFunc callback, void* data);
277
278/**
279 * Removes a previously added file descriptor from the looper.
280 *
281 * When this method returns, it is safe to close the file descriptor since the looper
282 * will no longer have a reference to it. However, it is possible for the callback to
283 * already be running or for it to run one last time if the file descriptor was already
284 * signalled. Calling code is responsible for ensuring that this case is safely handled.
285 * For example, if the callback takes care of removing itself during its own execution either
286 * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
287 * again at any later time unless registered anew.
288 *
289 * Returns 1 if the file descriptor was removed, 0 if none was previously registered
290 * or -1 if an error occurred.
291 *
292 * This method can be called on any thread.
293 * This method may block briefly if it needs to wake the poll.
294 */
295int ALooper_removeFd(ALooper* looper, int fd);
296
297#ifdef __cplusplus
298};
299#endif
300
Brian Carlstromfe761ab2013-12-12 23:13:18 -0800301#endif // ANDROID_LOOPER_H
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -0700302
303/** @} */