diff options
author | Ziv Hendel <ziv@primesense.com> | 2013-03-24 18:10:52 +0200 |
---|---|---|
committer | Adam Hampson <ahampson@google.com> | 2013-03-25 14:12:18 -0700 |
commit | f75ea8d082ff39e316bd4d73979b610cc4b5e4bc (patch) | |
tree | 4bb2e90c8749dcdf04bbff66020ab5fc11cf1170 /libusbhost | |
parent | fb39c0d19860fe48bc598d5d180a8cce9f59e33b (diff) | |
download | system_core-f75ea8d082ff39e316bd4d73979b610cc4b5e4bc.zip system_core-f75ea8d082ff39e316bd4d73979b610cc4b5e4bc.tar.gz system_core-f75ea8d082ff39e316bd4d73979b610cc4b5e4bc.tar.bz2 |
Properly handle cases of multiple inotify events
Bug: 8469799
Change-Id: Ie10242dd05becd142cc84651d5e5795e4c02270d
Signed-off-by: Igor Murashkin <iam@google.com>
Signed-off-by: Adam Hampson <ahampson@google.com>
Diffstat (limited to 'libusbhost')
-rw-r--r-- | libusbhost/usbhost.c | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c index 167fa60..b967342 100644 --- a/libusbhost/usbhost.c +++ b/libusbhost/usbhost.c @@ -223,56 +223,61 @@ int usb_host_read_event(struct usb_host_context *context) char event_buf[512]; char path[100]; int i, ret, done = 0; - int j, event_size; + int offset = 0; int wd; ret = read(context->fd, event_buf, sizeof(event_buf)); if (ret >= (int)sizeof(struct inotify_event)) { - event = (struct inotify_event *)event_buf; - wd = event->wd; - if (wd == context->wdd) { - if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) { - watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT); - done = find_existing_devices(context->cb_added, context->data); - } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) { - for (i = 0; i < MAX_USBFS_WD_COUNT; i++) { - if (context->wds[i] >= 0) { + while (offset < ret) { + event = (struct inotify_event*)&event_buf[offset]; + done = 0; + wd = event->wd; + if (wd == context->wdd) { + if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) { + watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT); + done = find_existing_devices(context->cb_added, context->data); + } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) { + for (i = 0; i < MAX_USBFS_WD_COUNT; i++) { + if (context->wds[i] >= 0) { + inotify_rm_watch(context->fd, context->wds[i]); + context->wds[i] = -1; + } + } + } + } else if (wd == context->wds[0]) { + i = atoi(event->name); + snprintf(path, sizeof(path), USB_FS_DIR "/%s", event->name); + D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ? + "new" : "gone", path, i); + if (i > 0 && i < MAX_USBFS_WD_COUNT) { + if (event->mask & IN_CREATE) { + ret = inotify_add_watch(context->fd, path, + IN_CREATE | IN_DELETE); + if (ret >= 0) + context->wds[i] = ret; + done = find_existing_devices_bus(path, context->cb_added, + context->data); + } else if (event->mask & IN_DELETE) { inotify_rm_watch(context->fd, context->wds[i]); context->wds[i] = -1; } } - } - } else if (wd == context->wds[0]) { - i = atoi(event->name); - snprintf(path, sizeof(path), USB_FS_DIR "/%s", event->name); - D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ? - "new" : "gone", path, i); - if (i > 0 && i < MAX_USBFS_WD_COUNT) { - if (event->mask & IN_CREATE) { - ret = inotify_add_watch(context->fd, path, - IN_CREATE | IN_DELETE); - if (ret >= 0) - context->wds[i] = ret; - done = find_existing_devices_bus(path, context->cb_added, - context->data); - } else if (event->mask & IN_DELETE) { - inotify_rm_watch(context->fd, context->wds[i]); - context->wds[i] = -1; - } - } - } else { - for (i = 1; (i < MAX_USBFS_WD_COUNT) && !done; i++) { - if (wd == context->wds[i]) { - snprintf(path, sizeof(path), USB_FS_DIR "/%03d/%s", i, event->name); - if (event->mask == IN_CREATE) { - D("new device %s\n", path); - done = context->cb_added(path, context->data); - } else if (event->mask == IN_DELETE) { - D("gone device %s\n", path); - done = context->cb_removed(path, context->data); + } else { + for (i = 1; (i < MAX_USBFS_WD_COUNT) && !done; i++) { + if (wd == context->wds[i]) { + snprintf(path, sizeof(path), USB_FS_DIR "/%03d/%s", i, event->name); + if (event->mask == IN_CREATE) { + D("new device %s\n", path); + done = context->cb_added(path, context->data); + } else if (event->mask == IN_DELETE) { + D("gone device %s\n", path); + done = context->cb_removed(path, context->data); + } } } } + + offset += sizeof(struct inotify_event) + event->len; } } |