static void io_remove_watch_poll(GSource *source) { IOWatchPoll *iwp; iwp = io_watch_poll_from_source(source); if (iwp->src) { g_source_destroy(iwp->src); g_source_unref(iwp->src); iwp->src = NULL; } g_source_destroy(&iwp->parent); }
static void io_watch_poll_finalize(GSource *source) { /* Due to a glib bug, removing the last reference to a source * inside a finalize callback causes recursive locking (and a * deadlock). This is not a problem inside other callbacks, * including dispatch callbacks, so we call io_remove_watch_poll * to remove this source. At this point, iwp->src must * be NULL, or we would leak it. * * This would be solved much more elegantly by child sources, * but we support older glib versions that do not have them. */ IOWatchPoll *iwp = io_watch_poll_from_source(source); assert(iwp->src == NULL); }
static gboolean io_watch_poll_prepare(GSource *source, gint *timeout) { IOWatchPoll *iwp = io_watch_poll_from_source(source); bool now_active = iwp->fd_can_read(iwp->opaque) > 0; bool was_active = iwp->src != NULL; if (was_active == now_active) { return FALSE; } if (now_active) { iwp->src = qio_channel_create_watch( iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL); g_source_add_child_source(source, iwp->src); g_source_unref(iwp->src); } else { g_source_remove_child_source(source, iwp->src); iwp->src = NULL; } return FALSE; }