blob: 6a02916fb30d304e0b500dc143427226a495ba46 [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 *
185 * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
186 * the timeout expired and no callbacks were invoked and no other file
187 * descriptors were ready.
188 *
189 * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
190 *
191 * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
192 * timeout expired.
193 *
194 * Returns ALOOPER_POLL_ERROR if an error occurred.
195 *
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -0700196 * Returns a value >= 0 containing an identifier (the same identifier
197 * `ident` passed to ALooper_addFd()) if its file descriptor has data
198 * and it has no callback function (requiring the caller here to
199 * handle it). In this (and only this) case outFd, outEvents and
200 * outData will contain the poll events and data associated with the
201 * fd, otherwise they will be set to NULL.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700202 *
203 * This method does not return until it has finished invoking the appropriate callbacks
204 * for all file descriptors that were signalled.
205 */
206int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
207
208/**
209 * Like ALooper_pollOnce(), but performs all pending callbacks until all
210 * data has been consumed or a file descriptor is available with no callback.
211 * This function will never return ALOOPER_POLL_CALLBACK.
Ady Abraham2a6c1862022-07-28 22:54:19 +0000212 *
213 * Removed in API 34 as ALooper_pollAll can swallow ALooper_wake calls.
214 * Use ALooper_pollOnce instead.
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700215 */
Dan Albertc47ac842024-05-02 20:19:54 +0000216int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData)
217 __REMOVED_IN(1, "ALooper_pollAll may ignore wakes. Use ALooper_pollOnce instead. See https://github.com/android/ndk/discussions/2020 for more information");
Mathias Agopiane1c61d32012-03-23 14:19:36 -0700218
219/**
220 * Wakes the poll asynchronously.
221 *
222 * This method can be called on any thread.
223 * This method returns immediately.
224 */
225void ALooper_wake(ALooper* looper);
226
227/**
228 * Adds a new file descriptor to be polled by the looper.
229 * If the same file descriptor was previously added, it is replaced.
230 *
231 * "fd" is the file descriptor to be added.
232 * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
233 * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
234 * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT.
235 * "callback" is the function to call when there is an event on the file descriptor.
236 * "data" is a private data pointer to supply to the callback.
237 *
238 * There are two main uses of this function:
239 *
240 * (1) If "callback" is non-NULL, then this function will be called when there is
241 * data on the file descriptor. It should execute any events it has pending,
242 * appropriately reading from the file descriptor. The 'ident' is ignored in this case.
243 *
244 * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
245 * when its file descriptor has data available, requiring the caller to take
246 * care of processing it.
247 *
248 * Returns 1 if the file descriptor was added or -1 if an error occurred.
249 *
250 * This method can be called on any thread.
251 * This method may block briefly if it needs to wake the poll.
252 */
253int ALooper_addFd(ALooper* looper, int fd, int ident, int events,
254 ALooper_callbackFunc callback, void* data);
255
256/**
257 * Removes a previously added file descriptor from the looper.
258 *
259 * When this method returns, it is safe to close the file descriptor since the looper
260 * will no longer have a reference to it. However, it is possible for the callback to
261 * already be running or for it to run one last time if the file descriptor was already
262 * signalled. Calling code is responsible for ensuring that this case is safely handled.
263 * For example, if the callback takes care of removing itself during its own execution either
264 * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
265 * again at any later time unless registered anew.
266 *
267 * Returns 1 if the file descriptor was removed, 0 if none was previously registered
268 * or -1 if an error occurred.
269 *
270 * This method can be called on any thread.
271 * This method may block briefly if it needs to wake the poll.
272 */
273int ALooper_removeFd(ALooper* looper, int fd);
274
275#ifdef __cplusplus
276};
277#endif
278
Brian Carlstromfe761ab2013-12-12 23:13:18 -0800279#endif // ANDROID_LOOPER_H
Johan Euphrosinebf6d5e02015-03-27 17:15:43 -0700280
281/** @} */