blob: dba2e89942e48a7c2f29d83c5b1006df3b1d64d3 [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 /**
93 * Result from ALooper_pollOnce() and ALooper_pollAll():
94 * One or more callbacks were executed.
95 */
96 ALOOPER_POLL_CALLBACK = -2,
97
98 /**
99 * Result from ALooper_pollOnce() and ALooper_pollAll():
100 * The timeout expired.
101 */
102 ALOOPER_POLL_TIMEOUT = -3,
103
104 /**
105 * Result from ALooper_pollOnce() and ALooper_pollAll():
106 * An error occurred.
107 */
108 ALOOPER_POLL_ERROR = -4,
109};
110
111/**
112 * Acquire a reference on the given ALooper object. This prevents the object
113 * from being deleted until the reference is removed. This is only needed
114 * to safely hand an ALooper from one thread to another.
115 */
116void ALooper_acquire(ALooper* looper);
117
118/**
119 * Remove a reference that was previously acquired with ALooper_acquire().
120 */
121void ALooper_release(ALooper* looper);
122
123/**
124 * Flags for file descriptor events that a looper can monitor.
125 *
126 * These flag bits can be combined to monitor multiple events at once.
127 */
128enum {
129 /**
130 * The file descriptor is available for read operations.
131 */
132 ALOOPER_EVENT_INPUT = 1 << 0,
133
134 /**
135 * The file descriptor is available for write operations.
136 */
137 ALOOPER_EVENT_OUTPUT = 1 << 1,
138
139 /**
140 * The file descriptor has encountered an error condition.
141 *
142 * The looper always sends notifications about errors; it is not necessary
143 * to specify this event flag in the requested event set.
144 */
145 ALOOPER_EVENT_ERROR = 1 << 2,
146
147 /**
148 * The file descriptor was hung up.
149 * For example, indicates that the remote end of a pipe or socket was closed.
150 *
151 * The looper always sends notifications about hangups; it is not necessary
152 * to specify this event flag in the requested event set.
153 */
154 ALOOPER_EVENT_HANGUP = 1 << 3,
155
156 /**
157 * The file descriptor is invalid.
158 * For example, the file descriptor was closed prematurely.
159 *
160 * The looper always sends notifications about invalid file descriptors; it is not necessary
161 * to specify this event flag in the requested event set.
162 */
163 ALOOPER_EVENT_INVALID = 1 << 4,
164};
165
166/**
167 * For callback-based event loops, this is the prototype of the function
168 * that is called when a file descriptor event occurs.
169 * It is given the file descriptor it is associated with,
170 * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
171 * and the data pointer that was originally supplied.
172 *
173 * Implementations should return 1 to continue receiving callbacks, or 0
174 * to have this file descriptor and callback unregistered from the looper.
175 */
176typedef int (*ALooper_callbackFunc)(int fd, int events, void* data);
177
178/**
179 * Waits for events to be available, with optional timeout in milliseconds.
180 * Invokes callbacks for all file descriptors on which an event occurred.
181 *
182 * If the timeout is zero, returns immediately without blocking.
183 * If the timeout is negative, waits indefinitely until an event appears.
184 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000185 * Returns ALOOPER_POLL_WAKE if the poll was awoken using ALooper_wake() before
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700186 * the timeout expired and no callbacks were invoked and no other file
Dan Albertb06c7fb2024-05-02 20:20:10 +0000187 * descriptors were ready. **All return values may also imply
188 * ALOOPER_POLL_WAKE.**
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700189 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000190 * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. The poll
191 * may also have been explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700192 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000193 * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given timeout
194 * expired. The poll may also have been explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700195 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000196 * Returns ALOOPER_POLL_ERROR if an error occurred. The poll may also have been
197 * explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700198 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000199 * Returns a value >= 0 containing an identifier (the same identifier `ident`
200 * passed to ALooper_addFd()) if its file descriptor has data and it has no
201 * callback function (requiring the caller here to handle it). In this (and
202 * only this) case outFd, outEvents and outData will contain the poll events and
203 * data associated with the fd, otherwise they will be set to NULL. The poll may
204 * also have been explicitly woken by ALooper_wake.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700205 *
206 * This method does not return until it has finished invoking the appropriate callbacks
207 * for all file descriptors that were signalled.
208 */
209int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
210
211/**
212 * Like ALooper_pollOnce(), but performs all pending callbacks until all
213 * data has been consumed or a file descriptor is available with no callback.
214 * This function will never return ALOOPER_POLL_CALLBACK.
Ady Abraham2a6c1862022-07-28 22:54:19 +0000215 *
Dan Albertb06c7fb2024-05-02 20:20:10 +0000216 * This API cannot be used safely, but a safe alternative exists (see below). As
217 * such, new builds will not be able to call this API and must migrate to the
218 * safe API. Binary compatibility is preserved to support already-compiled apps.
219 *
220 * \bug ALooper_pollAll will not wake in response to ALooper_wake calls if it
221 * also handles another event at the same time.
222 *
223 * \deprecated Calls to ALooper_pollAll should be replaced with
224 * ALooper_pollOnce. If you call ALooper_pollOnce in a loop, you *must* treat
225 * all return values as if they also indicate ALOOPER_POLL_WAKE.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700226 */
Dan Albertc47ac842024-05-02 20:19:54 +0000227int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData)
Dan Albertb06c7fb2024-05-02 20:20:10 +0000228 __REMOVED_IN(1,
229 "ALooper_pollAll may ignore wakes. Use ALooper_pollOnce instead. See "
230 "The API documentation for more information");
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700231
232/**
233 * Wakes the poll asynchronously.
234 *
235 * This method can be called on any thread.
236 * This method returns immediately.
237 */
238void ALooper_wake(ALooper* looper);
239
240/**
241 * Adds a new file descriptor to be polled by the looper.
242 * If the same file descriptor was previously added, it is replaced.
243 *
244 * "fd" is the file descriptor to be added.
245 * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
246 * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
247 * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT.
248 * "callback" is the function to call when there is an event on the file descriptor.
249 * "data" is a private data pointer to supply to the callback.
250 *
251 * There are two main uses of this function:
252 *
253 * (1) If "callback" is non-NULL, then this function will be called when there is
254 * data on the file descriptor. It should execute any events it has pending,
255 * appropriately reading from the file descriptor. The 'ident' is ignored in this case.
256 *
257 * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
258 * when its file descriptor has data available, requiring the caller to take
259 * care of processing it.
260 *
261 * Returns 1 if the file descriptor was added or -1 if an error occurred.
262 *
263 * This method can be called on any thread.
264 * This method may block briefly if it needs to wake the poll.
265 */
266int ALooper_addFd(ALooper* looper, int fd, int ident, int events,
267 ALooper_callbackFunc callback, void* data);
268
269/**
270 * Removes a previously added file descriptor from the looper.
271 *
272 * When this method returns, it is safe to close the file descriptor since the looper
273 * will no longer have a reference to it. However, it is possible for the callback to
274 * already be running or for it to run one last time if the file descriptor was already
275 * signalled. Calling code is responsible for ensuring that this case is safely handled.
276 * For example, if the callback takes care of removing itself during its own execution either
277 * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
278 * again at any later time unless registered anew.
279 *
280 * Returns 1 if the file descriptor was removed, 0 if none was previously registered
281 * or -1 if an error occurred.
282 *
283 * This method can be called on any thread.
284 * This method may block briefly if it needs to wake the poll.
285 */
286int ALooper_removeFd(ALooper* looper, int fd);
287
288#ifdef __cplusplus
289};
290#endif
291
Brian Carlstromfe761ab2013-12-12 23:13:18 -0800292#endif // ANDROID_LOOPER_H
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -0700293
294/** @} */