diff options
author | Vladimir Chtchetkine <vchtchetkine@google.com> | 2012-03-16 09:21:02 -0700 |
---|---|---|
committer | Vladimir Chtchetkine <vchtchetkine@google.com> | 2012-03-16 09:21:02 -0700 |
commit | 10bc04fd968d7f80258bf1eec665babf28e9e47d (patch) | |
tree | 30269c62a7f2d6658b6c6ebc2ad2fcf7c1d9ddb0 | |
parent | facee1d1d0c3029915f5443c788cd32b9f5b9c83 (diff) | |
download | external_qemu-10bc04fd968d7f80258bf1eec665babf28e9e47d.zip external_qemu-10bc04fd968d7f80258bf1eec665babf28e9e47d.tar.gz external_qemu-10bc04fd968d7f80258bf1eec665babf28e9e47d.tar.bz2 |
Fixes a hack that was enabling multi-touch emulation on Mac.
The issue was that on Mac there is a bug in select() implementation, that caused select()
to fail with EINVAL on condition that timeout exceeds 100000000 secods. So the real fix
was to clamp timout value to that limit when select() is called on Mac.
Change-Id: Icb9ead00a0060028957af1e6e22911d5e8e231c6
-rw-r--r-- | android/android-device.c | 71 | ||||
-rw-r--r-- | iolooper-select.c | 2 | ||||
-rw-r--r-- | qemu-common.h | 13 |
3 files changed, 38 insertions, 48 deletions
diff --git a/android/android-device.c b/android/android-device.c index e91185d..40ec294 100644 --- a/android/android-device.c +++ b/android/android-device.c @@ -597,60 +597,35 @@ _android_dev_socket_recv(AndroidDevSocket* ads, char* buf, int bufsize) return -1; } - /* XXX: This is a hack that implements a blocked line read on an async - * event socket! Redo this ASAP! */ - if (ads->type == ADS_TYPE_EVENT) { - AndroidEventSocket* adsevent = (AndroidEventSocket*)ads; - asyncLineReader_init(&adsevent->alr, buf, bufsize, adsevent->io); - /* Default EOL for the line reader was '\n'. */ - asyncLineReader_setEOL(&adsevent->alr, '\0'); - AsyncStatus status = ASYNC_NEED_MORE; - - while (status == ASYNC_NEED_MORE) { - status = asyncLineReader_read(&adsevent->alr); - if (status == ASYNC_COMPLETE) { - recvd = adsevent->alr.pos; - break; - } else if (status == ASYNC_ERROR) { - if (errno == ENOMEM) { - recvd = adsevent->alr.pos; - } else { - recvd = -1; - } - break; - } + iolooper_add_read(_ads_io_looper(ads), ads->fd); + do { + int res = socket_recv(ads->fd, buf + recvd, bufsize - recvd); + if (res == 0) { + /* Disconnection. */ + errno = ECONNRESET; + recvd = -1; + break; } - } else { - iolooper_add_read(_ads_io_looper(ads), ads->fd); - do { - int res = socket_recv(ads->fd, buf + recvd, bufsize - recvd); - if (res == 0) { - /* Disconnection. */ - errno = ECONNRESET; - recvd = -1; - break; + + if (res < 0) { + if (errno == EINTR) { + /* loop on EINTR */ + continue; } - if (res < 0) { - if (errno == EINTR) { - /* loop on EINTR */ + if (errno == EWOULDBLOCK || errno == EAGAIN) { + res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline); + if (res > 0) { + /* Ready to read. */ continue; } - - if (errno == EWOULDBLOCK || errno == EAGAIN) { - res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline); - if (res > 0) { - /* Ready to read. */ - continue; - } - } - recvd = -1; - break; } - recvd += res; - } while (recvd < bufsize); - iolooper_del_read(_ads_io_looper(ads), ads->fd); - } + recvd = -1; + break; + } + recvd += res; + } while (recvd < bufsize); + iolooper_del_read(_ads_io_looper(ads), ads->fd); /* In case of an I/O failure we have to invoke failure callback. Note that we * report I/O failures only on registered sockets. */ diff --git a/iolooper-select.c b/iolooper-select.c index 955204d..5024c9a 100644 --- a/iolooper-select.c +++ b/iolooper-select.c @@ -175,6 +175,8 @@ iolooper_wait( IoLooper* iol, int64_t duration ) if (count == 0) return 0; + CLAMP_MAC_TIMEOUT(duration); + if (duration < 0) tm = NULL; else { diff --git a/qemu-common.h b/qemu-common.h index 897d510..79ac779 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -395,4 +395,17 @@ typedef enum DisplayType DT_NOGRAPHIC, } DisplayType; +/* + * A fixer for timeout value passed to select() on Mac. The issue is that Mac's + * version of select() will return EINVAL on timeouts larger than 100000000 + * seconds, even though it should have just clamped it. So, for Mac we should + * make sure that timeout value is bound to 100000000 seconds before passing it + * to select(). + */ +#if _DARWIN_C_SOURCE +#define CLAMP_MAC_TIMEOUT(to) do { if (to > 100000000000LL) to = 100000000000LL; } while (0) +#else +#define CLAMP_MAC_TIMEOUT(to) ((void)0) +#endif // _DARWIN_C_SOURCE + #endif |