aboutsummaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2010-11-18 16:16:01 +0100
committerDavid 'Digit' Turner <digit@android.com>2010-11-19 15:06:50 +0100
commite654412d45c41d9dc83a87fce42f1d283fe0c55b (patch)
tree7698cf573691f0fbf7685e0c735915749544c9d1 /android
parent6d448806a80bcc2557ae0a38e7fd206967cf844e (diff)
downloadexternal_qemu-e654412d45c41d9dc83a87fce42f1d283fe0c55b.zip
external_qemu-e654412d45c41d9dc83a87fce42f1d283fe0c55b.tar.gz
external_qemu-e654412d45c41d9dc83a87fce42f1d283fe0c55b.tar.bz2
Parallelize -list-cores implementation.
Modify the implementation of list_cores() to perform all 16 connection requests in parallel, using a generic looper and and asyncConsoleConnector per probed port, with a global timeout of half a second. This is also a demonstration of the new asynchronous helpers. Change-Id: Ib09adf44b00d0694ec29d7ed0b26b44eef77f88a
Diffstat (limited to 'android')
-rw-r--r--android/main.c160
1 files changed, 63 insertions, 97 deletions
diff --git a/android/main.c b/android/main.c
index ffdd821..e1ad576 100644
--- a/android/main.c
+++ b/android/main.c
@@ -746,124 +746,92 @@ _adjustPartitionSize( const char* description,
// Socket timeout in millisec (set to half a second)
#define CORE_PORT_TIMEOUT_MS 500
-/* Checks if emulator core runs at the end of the given socket.
- * Param:
- * sockaddr Socket address addressing emulator's console.
- * Return:
- * 0 in case that core has been found for the socket, or -1 otherwise.
- */
-static int
-check_for_running_core(SockAddress* sockaddr)
+#include "android/async-console.h"
+
+typedef struct {
+ LoopIo io[1];
+ int port;
+ int ok;
+ AsyncConsoleConnector connector[1];
+} CoreConsole;
+
+static void
+coreconsole_io_func(void* opaque, int fd, unsigned events)
{
- IoLooper* looper = iolooper_new();
- int connect_status;
- char buf[512];
- int ret = -1;
+ CoreConsole* cc = opaque;
+ AsyncStatus status;
+ status = asyncConsoleConnector_run(cc->connector, cc->io);
+ if (status == ASYNC_COMPLETE) {
+ cc->ok = 1;
+ }
+}
+static void
+coreconsole_init(CoreConsole* cc, const SockAddress* address, Looper* looper)
+{
int fd = socket_create_inet(SOCKET_STREAM);
- if (fd < 0) {
- return -1;
- }
-
- socket_set_xreuseaddr(fd);
- socket_set_nonblock(fd);
- connect_status = socket_connect(fd, sockaddr);
- if (connect_status < 0 && errno == EINPROGRESS) {
- // Wait till connection occurs.
- iolooper_add_write(looper, fd);
- connect_status = iolooper_wait(looper, CORE_PORT_TIMEOUT_MS);
- if (connect_status > 0) {
- iolooper_del_write(looper, fd);
- } else {
- connect_status = -1;
- }
- }
- if (connect_status >= 0) {
- iolooper_add_read(looper, fd);
- // Read the handshake message from the core's console.
- if (iolooper_wait(looper, CORE_PORT_TIMEOUT_MS) > 0 &&
- iolooper_is_read(looper, fd)) {
- int read_bytes = read(fd, buf, sizeof(buf));
- // Check for the console handshake.
- if (read_bytes > 15 && !strncmp(buf, "Android Console", 15)) {
- ret = 0;
- }
+ AsyncStatus status;
+ cc->port = sock_address_get_port(address);
+ cc->ok = 0;
+ loopIo_init(cc->io, looper, fd, coreconsole_io_func, cc);
+ if (fd >= 0) {
+ status = asyncConsoleConnector_connect(cc->connector, address, cc->io);
+ if (status == ASYNC_ERROR) {
+ cc->ok = 0;
}
}
+}
- socket_close( fd );
- iolooper_free(looper);
- return ret;
+static void
+coreconsole_done(CoreConsole* cc)
+{
+ socket_close(cc->io->fd);
+ loopIo_done(cc->io);
}
-/* List emulator core processes running on the given machine.
- * This routine is called from main() if -list-cores parameter is set in the
- * command line.
- * Param:
- * host Value passed with -list-core parameter. Must be either "localhost", or
- * an IP address of a machine where core processes must be enumerated.
- */
static void
list_running_cores(const char* host)
{
- int iter;
- int port_iter;
- int found_cores = 0;
-
- // Convert host name into socket address list.
- SockAddress** sockaddr_list = sock_address_list_create(host, NULL, 0);
- if (sockaddr_list == NULL) {
- derror("Unable to resolve hostname %s: %s\n", host, errno_str);
+ Looper* looper;
+ CoreConsole cores[MAX_CORE_PROCS];
+ SockAddress address;
+ int nn, found;
+
+ if (sock_address_init_resolve(&address, host, CORE_BASE_PORT, 0) < 0) {
+ derror("Unable to resolve hostname %s: %s", host, errno_str);
return;
}
- /* Since core's console is not a UNIX socket, lets make sure that UNIX
- * socket is not the only family in the list. */
- for (iter = 0; sockaddr_list[iter] != NULL; iter++) {
- if (sock_address_get_family(sockaddr_list[iter]) != SOCKET_UNIX) {
- break;
- }
- }
- if (sockaddr_list[iter] == NULL) {
- derror("Unix socket is an invalid parameter for -list-cores option.\n");
- sock_address_list_free(sockaddr_list);
- return;
+ looper = looper_newGeneric();
+
+ for (nn = 0; nn < MAX_CORE_PROCS; nn++) {
+ int port = CORE_BASE_PORT + nn*2;
+ sock_address_set_port(&address, port);
+ coreconsole_init(&cores[nn], &address, looper);
}
- /* List running core processes. To enum core processes we will loop
- * through socket ports 5554-5584, where we assume that successful
- * conection to a socket means that there is a core process running
- * at the other end of that socket. In order to make sure that it's
- * emulator console at the other end of that socket, we will read from
- * the socket, expecting "Android Console" string at the beginning of
- * the data read from the socket. */
- for (port_iter = 0; port_iter < MAX_CORE_PROCS; port_iter++) {
- int port_num = CORE_BASE_PORT + port_iter * 2;
- for (iter = 0; sockaddr_list[iter] != NULL; iter++) {
- if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_UNIX) {
- continue;
- }
- sock_address_set_port(sockaddr_list[iter], port_num);
- if (!check_for_running_core(sockaddr_list[iter])) {
- // This is a core process at the other end of the socket.
- found_cores++;
- if (found_cores == 1) {
- fprintf(stdout, "Running emulator core processes:\n");
- }
- fprintf(stdout, "Emulator console port %d\n", port_num);
+ looper_runWithTimeout(looper, CORE_PORT_TIMEOUT_MS*2);
+
+ found = 0;
+ for (nn = 0; nn < MAX_CORE_PROCS; nn++) {
+ int port = CORE_BASE_PORT + nn*2;
+ if (cores[nn].ok) {
+ if (found == 0) {
+ fprintf(stdout, "Running emulator core processes:\n");
}
- // Go through this loop just once, for a non-Unix socket address.
- break;
+ fprintf(stdout, "Emulator console port %d\n", port);
+ found++;
}
+ coreconsole_done(&cores[nn]);
}
+ looper_free(looper);
- sock_address_list_free(sockaddr_list);
-
- if (!found_cores) {
+ if (found == 0) {
fprintf(stdout, "There were no running emulator core processes found on %s.\n",
host);
}
}
+
#endif // CONFIG_STANDALONE_UI
int main(int argc, char **argv)
@@ -955,9 +923,7 @@ int main(int argc, char **argv)
#ifdef CONFIG_STANDALONE_UI
// Lets see if user just wants to list core process.
if (opts->list_cores) {
- fprintf(stdout, "Enumerating running core processes.\n"
- "This make take up to %d seconds...\n\n",
- (MAX_CORE_PROCS * CORE_PORT_TIMEOUT_MS) / 1000 + 1);
+ fprintf(stdout, "Enumerating running core processes.\n");
list_running_cores(opts->list_cores);
exit(0);
}