1 /* Copyright (C) 2010 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #ifndef ANDROID_LOOPER_H 13 #define ANDROID_LOOPER_H 14 15 #include <stddef.h> 16 #include <stdint.h> 17 #include <limits.h> 18 #include <android/utils/system.h> 19 20 /********************************************************************** 21 ********************************************************************** 22 ***** 23 ***** T I M E R E P R E S E N T A T I O N 24 ***** 25 ********************************************************************** 26 **********************************************************************/ 27 28 /* An Duration represents a duration in milliseconds */ 29 typedef int64_t Duration; 30 31 /* A special Duration value used to mean "infinite" */ 32 #define DURATION_INFINITE ((Duration)INT64_MAX) 33 34 /********************************************************************** 35 ********************************************************************** 36 ***** 37 ***** E V E N T L O O P O B J E C T S 38 ***** 39 ********************************************************************** 40 **********************************************************************/ 41 42 43 /* A Looper is an abstraction for an event loop, which can 44 * be implemented in different ways. For example, the UI program may 45 * want to implement a custom event loop on top of the SDL event queue, 46 * while the QEMU core would implement it on top of QEMU's internal 47 * main loop which works differently. 48 * 49 * Once you have a Looper pointer, you can register "watchers" that 50 * will trigger callbacks whenever certain events occur. Supported event 51 * types are: 52 * 53 * - timer expiration 54 * - i/o file descriptor input/output 55 * 56 * See the relevant documentation for these below. 57 * 58 * Once you have registered one or more watchers, you can call looper_run() 59 * which will run the event loop until looper_forceQuit() is called from a 60 * callback, or no more watchers are registered. 61 * 62 * You can register/unregister watchers from a callback, or call various 63 * Looper methods from them (e.g. looper_now(), looper_forceQuit(), etc..) 64 * 65 * You can create a new Looper by calling looper_newGeneric(). This provides 66 * a default implementation that can be used in all threads. 67 * 68 * For the QEMU core, you can grab a Looper pointer by calling 69 * looper_newCore() instead. Its implementation relies on top of 70 * the QEMU event loop instead. 71 */ 72 typedef struct Looper Looper; 73 74 /* Create a new generic looper that can be used in any context / thread. */ 75 Looper* looper_newGeneric(void); 76 77 /* Create a new looper which is implemented on top of the QEMU main event 78 * loop. You should only use this when implementing the emulator UI and Core 79 * features in a single program executable. 80 */ 81 Looper* looper_newCore(void); 82 83 84 typedef struct LoopTimer LoopTimer; 85 typedef void (*LoopTimerFunc)(void* opaque); 86 87 typedef struct LoopIo LoopIo; 88 typedef void (*LoopIoFunc)(void* opaque, int fd, unsigned events); 89 90 struct Looper { 91 Duration (*now) (Looper* looper); 92 void (*timer_init)(Looper* looper, LoopTimer* timer, LoopTimerFunc callback, void* opaque); 93 void (*io_init) (Looper* looper, LoopIo* io, int fd, LoopIoFunc callback, void* opaque); 94 int (*run) (Looper* looper, Duration deadline_ms); 95 void (*forceQuit) (Looper* looper); 96 void (*destroy) (Looper* looper); 97 }; 98 99 100 101 /********************************************************************** 102 ********************************************************************** 103 ***** 104 ***** T I M E R S 105 ***** 106 ********************************************************************** 107 **********************************************************************/ 108 109 110 typedef struct LoopTimerClass LoopTimerClass; 111 112 struct LoopTimer { 113 LoopTimerClass* clazz; 114 void* impl; 115 }; 116 117 struct LoopTimerClass { 118 void (*startRelative)(void* impl, Duration timeout_ms); 119 void (*startAbsolute)(void* impl, Duration deadline_ms); 120 void (*stop) (void* impl); 121 int (*isActive) (void* impl); 122 void (*done) (void* impl); 123 }; 124 125 /* Initialize a LoopTimer with a callback and an 'opaque' value. 126 * Each timer belongs to only one looper object. 127 */ 128 AINLINED void 129 loopTimer_init(LoopTimer* timer, 130 Looper* looper, 131 LoopTimerFunc callback, 132 void* opaque) 133 { 134 looper->timer_init(looper, timer, callback, opaque); 135 } 136 137 /* Finalize a LoopTimer */ 138 AINLINED void 139 loopTimer_done(LoopTimer* timer) 140 { 141 timer->clazz->done(timer->impl); 142 timer->clazz = NULL; 143 timer->impl = NULL; 144 } 145 146 /* Start a timer, i.e. arm it to expire in 'timeout_ms' milliseconds, 147 * unless loopTimer_stop() is called before that, or the timer is 148 * reprogrammed with another loopTimer_startXXX() call. 149 */ 150 AINLINED void 151 loopTimer_startRelative(LoopTimer* timer, Duration timeout_ms) 152 { 153 timer->clazz->startRelative(timer->impl, timeout_ms); 154 } 155 156 /* A variant of loopTimer_startRelative that fires on a given deadline 157 * in milliseconds instead. If the deadline already passed, the timer is 158 * automatically appended to the list of pending event watchers and will 159 * fire as soon as possible. Note that this can cause infinite loops 160 * in your code if you're not careful. 161 */ 162 AINLINED void 163 loopTimer_startAbsolute(LoopTimer* timer, Duration deadline_ms) 164 { 165 timer->clazz->startAbsolute(timer->impl, deadline_ms); 166 } 167 168 /* Stop a given timer */ 169 AINLINED void 170 loopTimer_stop(LoopTimer* timer) 171 { 172 timer->clazz->stop(timer->impl); 173 } 174 175 /* Returns true iff the timer is active / started */ 176 AINLINED int 177 loopTimer_isActive(LoopTimer* timer) 178 { 179 return timer->clazz->isActive(timer->impl); 180 } 181 182 /********************************************************************** 183 ********************************************************************** 184 ***** 185 ***** F I L E D E S C R I P T O R S 186 ***** 187 ********************************************************************** 188 **********************************************************************/ 189 190 typedef struct LoopIoClass LoopIoClass; 191 192 struct LoopIo { 193 LoopIoClass* clazz; 194 void* impl; 195 int fd; 196 }; 197 198 /* Bitmasks about i/o events. Note that errors (e.g. network disconnections) 199 * are mapped to both read and write events. The idea is that a read() or 200 * write() will return 0 or even -1 on non-blocking file descriptors in this 201 * case. 202 * 203 * You can receive several events at the same time on a single LoopIo 204 * 205 * Socket connect()s are mapped to LOOP_IO_WRITE events. 206 * Socket accept()s are mapped to LOOP_IO_READ events. 207 */ 208 enum { 209 LOOP_IO_READ = (1 << 0), 210 LOOP_IO_WRITE = (1 << 1), 211 }; 212 213 struct LoopIoClass { 214 void (*wantRead)(void* impl); 215 void (*wantWrite)(void* impl); 216 void (*dontWantRead)(void* impl); 217 void (*dontWantWrite)(void* impl); 218 unsigned (*poll)(void* impl); 219 void (*done)(void* impl); 220 }; 221 222 AINLINED void 223 loopIo_init(LoopIo* io, Looper* looper, int fd, LoopIoFunc callback, void* opaque) 224 { 225 looper->io_init(looper, io, fd, callback, opaque); 226 io->fd = fd; 227 } 228 229 /* Note: This does not close the file descriptor! */ 230 AINLINED void 231 loopIo_done(LoopIo* io) 232 { 233 io->clazz->done(io->impl); 234 } 235 236 /* The following functions are used to indicate whether you want the callback 237 * to be fired when there is data to be read or when the file is ready to 238 * be written to. */ 239 AINLINED void 240 loopIo_wantRead(LoopIo* io) 241 { 242 io->clazz->wantRead(io->impl); 243 } 244 AINLINED void 245 loopIo_wantWrite(LoopIo* io) 246 { 247 io->clazz->wantWrite(io->impl); 248 } 249 AINLINED void 250 loopIo_dontWantRead(LoopIo* io) 251 { 252 io->clazz->dontWantRead(io->impl); 253 } 254 AINLINED void 255 loopIo_dontWantWrite(LoopIo* io) 256 { 257 io->clazz->dontWantWrite(io->impl); 258 } 259 AINLINED unsigned 260 loopIo_poll(LoopIo* io) 261 { 262 return io->clazz->poll(io->impl); 263 } 264 265 /********************************************************************** 266 ********************************************************************** 267 ***** 268 ***** L O O P E R 269 ***** 270 ********************************************************************** 271 **********************************************************************/ 272 273 AINLINED Duration 274 looper_now(Looper* looper) 275 { 276 return looper->now(looper); 277 } 278 /* Run the event loop, until looper_forceQuit() is called, or there is no 279 * more registered watchers for events/timers in the looper. 280 * 281 * The value returned indicates the reason: 282 * 0 -> normal exit through looper_forceQuit() 283 * EWOULDBLOCK -> there are not more watchers registered (the looper 284 * would loop infinitely) 285 */ 286 AINLINED void 287 looper_run(Looper* looper) 288 { 289 (void) looper->run(looper, DURATION_INFINITE); 290 } 291 292 /* A variant of looper_run() that allows to run the event loop only 293 * until a certain timeout in milliseconds has passed. 294 * 295 * Returns the reason why the looper stopped: 296 * 0 -> normal exit through looper_forceQuit() 297 * EWOULDBLOCK -> there are not more watchers registered (the looper 298 * would loop infinitely) 299 * ETIMEDOUT -> timeout reached 300 * 301 */ 302 AINLINED int 303 looper_runWithTimeout(Looper* looper, Duration timeout_ms) 304 { 305 if (timeout_ms != DURATION_INFINITE) 306 timeout_ms += looper_now(looper); 307 308 return looper->run(looper, timeout_ms); 309 } 310 311 /* Another variant of looper_run() that takes a deadline instead of a 312 * timeout. Same return values than looper_runWithTimeout() 313 */ 314 AINLINED int 315 looper_runWithDeadline(Looper* looper, Duration deadline_ms) 316 { 317 return looper->run(looper, deadline_ms); 318 } 319 320 /* Call this function from within the event loop to force it to quit 321 * as soon as possible. looper_run() / _runWithTimeout() / _runWithDeadline() 322 * will then return 0. 323 */ 324 AINLINED void 325 looper_forceQuit(Looper* looper) 326 { 327 looper->forceQuit(looper); 328 } 329 330 /* Destroy a given looper object. Only works for those created 331 * with looper_new(). Cannot be called within looper_run()!! 332 * 333 * NOTE: This assumes that the user has destroyed all its 334 * timers and ios properly 335 */ 336 AINLINED void 337 looper_free(Looper* looper) 338 { 339 if (looper) 340 looper->destroy(looper); 341 } 342 343 /* */ 344 345 #endif /* ANDROID_LOOPER_H */ 346