diff options
author | Vladimir Chtchetkine <vchtchetkine@google.com> | 2011-01-20 11:22:32 -0800 |
---|---|---|
committer | Vladimir Chtchetkine <vchtchetkine@google.com> | 2011-01-20 11:22:32 -0800 |
commit | 6ee1c4edbd30b7c7aff9d6e13793207278aa1660 (patch) | |
tree | 6b0c00f806dfb8432cb7468bc725f9698d6b617b /android | |
parent | a228e1347525147daa619b99ad4f832b78788cd1 (diff) | |
download | external_qemu-6ee1c4edbd30b7c7aff9d6e13793207278aa1660.zip external_qemu-6ee1c4edbd30b7c7aff9d6e13793207278aa1660.tar.gz external_qemu-6ee1c4edbd30b7c7aff9d6e13793207278aa1660.tar.bz2 |
Fix framebuffer and user events service disconnection bug.
FB and UE services overwrite the socket's read callbacks, making the console
unavare of the fact that console client gets disconnected. As the result,
console clients for FB and UE stays alive after UI has exited, making it
impossible to attach another UI. To fix this, we add socket read callbacks
to the FB and UE service that monitor the disconnection event and destroy
their console clients on such events.
Change-Id: I82e714f33ccc81bc04ca47eda6fbb8fab4a313f9
Diffstat (limited to 'android')
-rw-r--r-- | android/console.c | 16 | ||||
-rw-r--r-- | android/framebuffer-core.c | 15 | ||||
-rw-r--r-- | android/user-events-core.c | 6 |
3 files changed, 37 insertions, 0 deletions
diff --git a/android/console.c b/android/console.c index 6f9e26b..4c3548a 100644 --- a/android/console.c +++ b/android/console.c @@ -2550,6 +2550,14 @@ do_create_framebuffer_service( ControlClient client, char* args ) return 0; } +void +destroy_control_fb_client(void) +{ + if (framebuffer_client != NULL) { + control_client_destroy(framebuffer_client); + } +} + static int do_create_user_events_service( ControlClient client, char* args ) { @@ -2575,6 +2583,14 @@ do_create_user_events_service( ControlClient client, char* args ) return 0; } + +void +destroy_control_ue_client(void) +{ + if (user_events_client != NULL) { + control_client_destroy(user_events_client); + } +} #endif // CONFIG_STANDALONE_CORE static const CommandDefRec qemu_commands[] = diff --git a/android/framebuffer-core.c b/android/framebuffer-core.c index 978bfc0..3eb7665 100644 --- a/android/framebuffer-core.c +++ b/android/framebuffer-core.c @@ -136,6 +136,9 @@ fbupdatenotify_delete(FBUpdateNotify* desc) } } +/* Implemented in android/console.c */ +extern void destroy_control_fb_client(void); + /* * Asynchronous I/O callback launched when writing framebuffer notifications * to the socket. @@ -147,6 +150,15 @@ corefb_io_func(void* opaque, int fd, unsigned events) { CoreFramebuffer* core_fb = opaque; + if (events & LOOP_IO_READ) { + // We don't expect the UI client to write anything here, except when + // the client gets disconnected. + loopIo_dontWantWrite(&core_fb->io); + loopIo_dontWantRead(&core_fb->io); + destroy_control_fb_client(); + return; + } + while (core_fb->fb_update_head != NULL) { FBUpdateNotify* current_update = core_fb->fb_update_head; // Lets continue writing of the current notification. @@ -192,6 +204,9 @@ corefb_create(int sock, const char* protocol, QFrameBuffer* fb) ret->sock = sock; ret->looper = looper_newCore(); loopIo_init(&ret->io, ret->looper, sock, corefb_io_func, ret); + // Since we're overriding the read callback with our looper's I/O routine, + // we need to have set our read callback here to monitor disconnections. + loopIo_wantRead(&ret->io); ret->fb = fb; ret->fb_update_head = NULL; ret->fb_update_tail = NULL; diff --git a/android/user-events-core.c b/android/user-events-core.c index a732791..3b97c00 100644 --- a/android/user-events-core.c +++ b/android/user-events-core.c @@ -57,6 +57,8 @@ struct CoreUserEvents { }; }; +/* Implemented in android/console.c */ +extern void destroy_control_ue_client(void); /* * Asynchronous I/O callback launched when reading user events from the socket. @@ -135,6 +137,10 @@ coreue_io_func(void* opaque, int fd, unsigned events) break; case ASYNC_ERROR: loopIo_dontWantRead(&ue->io); + if (errno == ECONNRESET) { + // UI has exited. We need to destroy user event service. + destroy_control_ue_client(); + } break; case ASYNC_NEED_MORE: |