return TRUE;
}
+struct gio_channel_wrap {
+ GIOChannel *ch;
+ guint source_tag;
+};
+
static int add_fd_watch(int fd, short events, void *user_data)
{
- GIOChannel *ch;
+ struct gio_channel_wrap *ch;
usb_host_context_h ctx = user_data;
GIOCondition condition = 0;
if (events & POLLOUT)
condition |= G_IO_OUT;
- ch = g_io_channel_unix_new(fd);
+ ch = malloc(sizeof(*ch));
if (!ch) {
+ _E("malloc() failed"); //LCOV_EXCL_LINE
+ return USB_HOST_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
+ }
+
+ ch->ch = g_io_channel_unix_new(fd);
+ if (!ch->ch) {
_E("Failed to create gio channel"); //LCOV_EXCL_LINE
+ free(ch); //LCOV_EXCL_LINE
return USB_HOST_ERROR_OUT_OF_MEMORY;
}
- g_io_add_watch(ch, condition, usb_host_poll_cb, ctx);
+ ch->source_tag = g_io_add_watch(ch->ch, condition, usb_host_poll_cb, ctx);
pthread_mutex_lock(&ctx->channel_list_lock);
_I("added fd %d to poll", fd);
static void fd_removed_cb(int fd, void *user_data)
{
- GIOChannel *ch;
+ struct gio_channel_wrap *ch;
usb_host_context_h ctx = user_data;
GList *l, *next;
int rfd;
while (l != NULL) {
ch = l->data;
next = l->next;
- rfd = g_io_channel_unix_get_fd(ch);
+ rfd = g_io_channel_unix_get_fd(ch->ch);
if (fd == rfd) {
- g_io_channel_unref(ch);
+ g_source_remove(ch->source_tag);
+ g_io_channel_unref(ch->ch);
ctx->gio_channels = g_list_delete_link(ctx->gio_channels, l);
+ free(ch);
}
l = next;
struct usb_host_context_s *_ctx;
const struct libusb_pollfd **pollfds = NULL;
GList *l, *next;
- GIOChannel *ch;
+ struct gio_channel_wrap *ch;
if (!usb_host_feature_enabled())
return USB_HOST_ERROR_NOT_SUPPORTED;
while (l != NULL) {
ch = l->data;
next = l->next;
- g_io_channel_unref(ch);
+ g_io_channel_unref(ch->ch);
l = next;
+ free(ch);
}
g_list_free(_ctx->gio_channels);
int usb_host_destroy(usb_host_context_h context)
{
- GIOChannel *ch;
+ struct gio_channel_wrap *ch;
GList *l, *next;
+ int fd;
if (!usb_host_feature_enabled())
return USB_HOST_ERROR_NOT_SUPPORTED;
while (l != NULL) {
ch = l->data;
next = l->next;
- g_io_channel_unref(ch);
+ fd = g_io_channel_unix_get_fd(ch->ch);
+ g_source_remove(ch->source_tag);
+ g_io_channel_unref(ch->ch);
l = next;
+ free(ch);
+ _I("removed fd %d", fd);
}
g_list_free(context->gio_channels);