looper-qemu.c revision aa8236dc1b1ea300ab18716db5b8fab42aca3ca7
17a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/* Copyright (C) 2010 The Android Open Source Project 27a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** 37a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** This software is licensed under the terms of the GNU General Public 47a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** License version 2, as published by the Free Software Foundation, and 57a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** may be copied, distributed, and modified under those terms. 67a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** 77a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** This program is distributed in the hope that it will be useful, 87a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** but WITHOUT ANY WARRANTY; without even the implied warranty of 97a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 107a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner** GNU General Public License for more details. 117a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner*/ 127a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 137a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/* Implement the Looper interface on top of the QEMU main event loop */ 147a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 157a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner#include <android/looper.h> 161bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner#include <android/utils/panic.h> 177a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner#include "qemu-common.h" 187a78db75ad42aea283f5073f51891464104a9fc3David 'Digit' Turner#include "qemu/timer.h" 19e7216d82dbaa19892ad62b07402d512234559a6eDavid 'Digit' Turner#include "sysemu/char.h" 20cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "android/sockets.h" /* for socket_set_nonblock() */ 217a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 227a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/********************************************************************** 237a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ********************************************************************** 247a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ***** 257a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ***** T I M E R S 267a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ***** 277a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ********************************************************************** 287a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner **********************************************************************/ 297a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 307a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/* Model a timer simple as a QEMUTimer for the host_clock */ 317a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 327a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 337a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooptimer_startRelative(void* impl, Duration timeout_ms) 347a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 357a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QEMUTimer* tt = impl; 367a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (timeout_ms == DURATION_INFINITE) 377a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_del_timer(tt); 387a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner else 395973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner qemu_mod_timer(tt, qemu_get_clock_ms(host_clock) + timeout_ms); 407a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 417a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 427a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 437a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooptimer_startAbsolute(void* impl, Duration deadline_ms) 447a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 457a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QEMUTimer* tt = impl; 467a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (deadline_ms == DURATION_INFINITE) 477a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_del_timer(tt); 487a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner else 4914a4131fde5542634aede4f358cfb4761330b69aVladimir Chtchetkine qemu_mod_timer(tt, deadline_ms); 507a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 517a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 527a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 537a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooptimer_stop(void* impl) 547a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 557a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QEMUTimer* tt = impl; 567a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_del_timer(tt); 577a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 587a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 597a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic int 607a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooptimer_isActive(void* impl) 617a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 627a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QEMUTimer* tt = impl; 637a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner return qemu_timer_pending(tt); 647a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 657a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 667a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 677a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooptimer_free(void* impl) 687a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 697a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QEMUTimer* tt = impl; 707a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_free_timer(tt); 717a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 727a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 737a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic const LoopTimerClass qlooptimer_class = { 747a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooptimer_startRelative, 757a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooptimer_startAbsolute, 767a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooptimer_stop, 777a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooptimer_isActive, 787a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooptimer_free 797a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner}; 807a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 817a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 827a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_timer_init(Looper* looper, 837a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner LoopTimer* timer, 847a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner LoopTimerFunc callback, 857a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner void* opaque) 867a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 877a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner timer->clazz = (LoopTimerClass*) &qlooptimer_class; 885973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner timer->impl = qemu_new_timer_ms(host_clock, callback, opaque); 897a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 907a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 917a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/********************************************************************** 927a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ********************************************************************** 937a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ***** 947a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ***** F I L E D E S C R I P T O R S 957a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ***** 967a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ********************************************************************** 977a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner **********************************************************************/ 987a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 997a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/* Modeling the LoopIo is a bit more complex because the main event loop 1007a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * will call different functions for read and write readiness, while our 1017a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * users expect a single call with a mask of ready events. 1027a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 1037a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * Since the QEMU main event loop looks like the following: 1047a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 1057a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 1/ perform select() 1067a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 2/ for each file descriptor: 1077a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * if readReady: 1087a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * call readHandler() 1097a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * if writeReady: 1107a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * call writeHandler() 1117a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 3/ run timers 1127a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 4/ run bottom-half handlers 1137a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 1147a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * We're going to provide simple read and write handlers that only mark 1157a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * the file descriptor for readiness, and put it on a "pending list". 1167a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * 1177a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * Then, we're going to schedule a bottom-half handler when such a pending 1187a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * i/o event occurs, in order to call the user callback with the correct 1197a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * flags. 1207a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner */ 1217a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1227a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnertypedef struct QLoopIo QLoopIo; 1237a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1247a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnertypedef struct QLooper QLooper; 1257a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1267a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstruct QLoopIo { 1277a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner int fd; 1287a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner LoopIoFunc user_callback; 1297a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner void* user_opaque; 1307a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner unsigned wanted; 1317a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner unsigned ready; 1327a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLooper* looper; 1337a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* pendingNext; 1347a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* next; 1357a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner}; 1367a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1377a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void qlooper_addIo(QLooper* looper, QLoopIo* io); 1387a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void qlooper_delIo(QLooper* looper, QLoopIo* io); 1397a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1407a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic QLoopIo* 1417a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_new(int fd, LoopIoFunc callback, void* opaque, QLooper* qlooper) 1427a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 143aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner QLoopIo* io = g_malloc(sizeof(*io)); 1447a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1457a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->fd = fd; 1467a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->user_callback = callback; 1477a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->user_opaque = opaque; 1487a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->wanted = 0; 1497a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->ready = 0; 1507a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->looper = qlooper; 1517a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->pendingNext = NULL; 1527a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1537a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooper_addIo(qlooper, io); 1547a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1557a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner return io; 1567a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 1577a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1587a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void qlooper_addPendingIo(QLooper* qlooper, QLoopIo* io); 1597a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void qlooper_delPendingIo(QLooper* qlooper, QLoopIo* io); 1607a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1617a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 1627a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_removePending(QLoopIo* io) 1637a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 1647a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (io->ready != 0) { 1657a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooper_delPendingIo(io->looper, io); 1667a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->ready = 0; 1677a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 1687a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 1697a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1707a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 1717a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_setReady(QLoopIo* io, unsigned flag) 1727a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 1737a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (io->ready == 0) { 1747a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooper_addPendingIo(io->looper, io); 1757a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 1767a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->ready |= flag; 1777a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 1787a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1797a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 1807a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_handleRead(void* opaque) 1817a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 1827a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = opaque; 1837a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_setReady(io, LOOP_IO_READ); 1847a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 1857a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1867a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 1877a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_handleWrite(void* opaque) 1887a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 1897a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = opaque; 1907a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_setReady(io, LOOP_IO_WRITE); 1917a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 1927a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 1937a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 1947a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_modify(QLoopIo* io, unsigned wanted) 1957a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 1967a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* no change, don't bother */ 1977a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (wanted == io->wanted) 1987a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner return; 1997a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2007a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* if we're pending, but the new mask doesn't care about 2017a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * out state, remove from pending list */ 202e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine if (io->ready && (io->ready & wanted) == 0) { 2037a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_removePending(io); 204e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine } 2057a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2067a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* recompute read/write handlers for QEMU */ 2077a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner IOHandler* fd_read = (wanted & LOOP_IO_READ) ? qloopio_handleRead : NULL; 2087a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner IOHandler* fd_write = (wanted & LOOP_IO_WRITE) ? qloopio_handleWrite : NULL; 2097a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_set_fd_handler(io->fd, fd_read, fd_write, io); 210e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine io->wanted = wanted; 2117a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2127a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2137a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2147a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_wantRead(void* impl) 2157a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2167a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = impl; 2177a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_modify(io, io->wanted | LOOP_IO_READ); 2187a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2197a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2207a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2217a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_wantWrite(void* impl) 2227a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2237a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = impl; 2247a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_modify(io, io->wanted | LOOP_IO_WRITE); 2257a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2267a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2277a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2287a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_dontWantRead(void* impl) 2297a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2307a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = impl; 2317a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_modify(io, io->wanted & ~LOOP_IO_READ); 2327a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2337a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2347a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2357a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_dontWantWrite(void* impl) 2367a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2377a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = impl; 2387a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_modify(io, io->wanted & ~LOOP_IO_WRITE); 2397a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2407a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2417a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2427a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqloopio_free(void* impl) 2437a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2447a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = impl; 2457a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (io->ready) 2467a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_removePending(io); 2477a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2487a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* remove from global list */ 2497a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qlooper_delIo(io->looper, io); 2507a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2517a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* make QEMU forget about this fd */ 2527a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_set_fd_handler(io->fd, NULL, NULL, NULL); 2537a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->fd = -1; 254aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(io); 2557a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2567a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 257a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turnerstatic unsigned 258a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turnerqloopio_poll(void* impl) 259a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turner{ 260a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turner QLoopIo* io = impl; 261a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turner return io->ready; 262a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turner} 263a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turner 2647a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic const LoopIoClass qlooper_io_class = { 2657a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_wantRead, 2667a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_wantWrite, 2677a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_dontWantRead, 2687a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_dontWantWrite, 269a65e41529e4e3900372d54859f8c559cf79d953cDavid 'Digit' Turner qloopio_poll, 2707a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_free 2717a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner}; 2727a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2737a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2747a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_io_init(Looper* looper, 2757a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner LoopIo* loopio, 2767a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner int fd, 2777a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner LoopIoFunc callback, 2787a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner void* opaque) 2797a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2807a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io = qloopio_new(fd, callback, opaque, (QLooper*)looper); 2817a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2827a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner socket_set_nonblock(fd); 2837a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2847a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner loopio->clazz = (LoopIoClass*) &qlooper_io_class; 2857a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner loopio->impl = io; 2867a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 2877a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2887a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstruct QLooper { 2897a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner Looper looper; 2907a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io_list; 2917a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io_pending; 2927a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QEMUBH* io_bh; 2937a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner}; 2947a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 2957a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 2967a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_addIo(QLooper* looper, QLoopIo* io) 2977a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 2987a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->next = looper->io_list; 2997a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->io_list = io; 3007a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3017a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3027a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 3037a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_delIo(QLooper* looper, QLoopIo* io) 3047a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3057a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo** pnode = &looper->io_list; 3067a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner for (;;) { 3077a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (*pnode == NULL) 3087a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner break; 3097a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (*pnode == io) { 3107a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner *pnode = io->next; 3117a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->next = NULL; 3127a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner break; 3137a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 3147a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner pnode = &(*pnode)->next; 3157a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 3167a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3177a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3187a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 3197a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_addPendingIo(QLooper* looper, QLoopIo* io) 3207a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3217a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (looper->io_pending == NULL) { 3227a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_bh_schedule(looper->io_bh); 3237a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 3247a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->pendingNext = looper->io_pending; 325e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine looper->io_pending = io; 3267a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3277a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3287a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 3297a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_delPendingIo(QLooper* looper, QLoopIo* io) 3307a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3317a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo** pnode = &looper->io_pending; 3327a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner for (;;) { 3337a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (*pnode == NULL) 3347a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner break; 3357a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner if (*pnode == io) { 3367a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner *pnode = io->pendingNext; 3377a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner break; 3387a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 3397a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner pnode = &(*pnode)->pendingNext; 3407a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 3417a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->pendingNext = NULL; 3427a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3437a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3447a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner/* This function is called by the main event loop when pending i/o 3457a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * events were registered with qlooper_addPendingIo(). It will parse 3467a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * the list of pending QLoopIo and call the user callback with the 3477a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * appropriate flags. 3487a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner */ 3497a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 3507a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_handle_io_bh(void* opaque) 3517a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3527a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLooper* looper = opaque; 3537a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io; 3547a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3557a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner while ((io = looper->io_pending) != NULL) { 3567a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner unsigned ready; 3577a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* extract from list */ 3587a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->io_pending = io->pendingNext; 3597a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->pendingNext = NULL; 3607a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner /* call the user callback, clear io->ready before to 3617a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * indicate that the item is not on the pending list 3627a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner * anymore. 3637a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner */ 3647a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner ready = io->ready; 3657a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->ready = 0; 3667a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner io->user_callback(io->user_opaque, io->fd, ready); 3677a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner } 3687a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3697a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3707a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic Duration 3717a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_now(Looper* ll) 3727a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3735973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner return qemu_get_clock_ms(host_clock); 3747a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3757a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3767a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerextern void qemu_system_shutdown_request(void); 3777a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3787a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 3797a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_forceQuit(Looper* ll) 3807a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3817a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_system_shutdown_request(); 3827a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 3837a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3841bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner/* The user cannot call looper_run on the core event loop, because it 3851bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner * is started by qemu_main() explicitely instead, so just panic. */ 3861bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turnerint 3871bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turnerqlooper_run(Looper* ll, Duration deadline_ms) 3881bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner{ 3891bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner APANIC("Trying to run the QEMU main event loop explicitely!"); 3901bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner return EINVAL; 3911bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner} 3921bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner 3937a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerstatic void 3947a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerqlooper_destroy(Looper* ll) 3957a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 3967a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLooper* looper = (QLooper*)ll; 3977a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner QLoopIo* io; 3987a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 3997a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner while ((io = looper->io_list) != NULL) 4007a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qloopio_free(io); 4017a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 4027a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner qemu_bh_delete(looper->io_bh); 403aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(looper); 4047a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 4057a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 4067a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' TurnerLooper* 4077a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnerlooper_newCore(void) 4087a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{ 409aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner QLooper* looper = g_malloc0(sizeof(*looper)); 4107a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 4117a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->io_list = NULL; 4127a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->io_pending = NULL; 4137a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->io_bh = qemu_bh_new(qlooper_handle_io_bh, looper); 4147a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 4157a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->looper.now = qlooper_now; 4167a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->looper.timer_init = qlooper_timer_init; 4177a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->looper.io_init = qlooper_io_init; 4181bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner looper->looper.run = qlooper_run; 4197a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->looper.forceQuit = qlooper_forceQuit; 4207a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner looper->looper.destroy = qlooper_destroy; 4217a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner 4227a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner return &looper->looper; 4237a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner} 424