chardev: use a child source for qio input source
GLib child source were added with version 2.28. We can use them now that we bumped our requirement to 2.40. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
95e30b2a13
commit
a7077b8e35
|
@ -33,7 +33,6 @@ typedef struct IOWatchPoll {
|
||||||
IOCanReadHandler *fd_can_read;
|
IOCanReadHandler *fd_can_read;
|
||||||
GSourceFunc fd_read;
|
GSourceFunc fd_read;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
GMainContext *context;
|
|
||||||
} IOWatchPoll;
|
} IOWatchPoll;
|
||||||
|
|
||||||
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
|
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
|
||||||
|
@ -55,47 +54,24 @@ static gboolean io_watch_poll_prepare(GSource *source,
|
||||||
iwp->src = qio_channel_create_watch(
|
iwp->src = qio_channel_create_watch(
|
||||||
iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
|
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_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
|
||||||
g_source_attach(iwp->src, iwp->context);
|
g_source_add_child_source(source, iwp->src);
|
||||||
} else {
|
|
||||||
g_source_destroy(iwp->src);
|
|
||||||
g_source_unref(iwp->src);
|
g_source_unref(iwp->src);
|
||||||
|
} else {
|
||||||
|
g_source_remove_child_source(source, iwp->src);
|
||||||
iwp->src = NULL;
|
iwp->src = NULL;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean io_watch_poll_check(GSource *source)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
|
static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
abort();
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
|
||||||
|
|
||||||
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 GSourceFuncs io_watch_poll_funcs = {
|
static GSourceFuncs io_watch_poll_funcs = {
|
||||||
.prepare = io_watch_poll_prepare,
|
.prepare = io_watch_poll_prepare,
|
||||||
.check = io_watch_poll_check,
|
|
||||||
.dispatch = io_watch_poll_dispatch,
|
.dispatch = io_watch_poll_dispatch,
|
||||||
.finalize = io_watch_poll_finalize,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GSource *io_add_watch_poll(Chardev *chr,
|
GSource *io_add_watch_poll(Chardev *chr,
|
||||||
|
@ -115,7 +91,6 @@ GSource *io_add_watch_poll(Chardev *chr,
|
||||||
iwp->ioc = ioc;
|
iwp->ioc = ioc;
|
||||||
iwp->fd_read = (GSourceFunc) fd_read;
|
iwp->fd_read = (GSourceFunc) fd_read;
|
||||||
iwp->src = NULL;
|
iwp->src = NULL;
|
||||||
iwp->context = context;
|
|
||||||
|
|
||||||
name = g_strdup_printf("chardev-iowatch-%s", chr->label);
|
name = g_strdup_printf("chardev-iowatch-%s", chr->label);
|
||||||
g_source_set_name((GSource *)iwp, name);
|
g_source_set_name((GSource *)iwp, name);
|
||||||
|
@ -126,23 +101,10 @@ GSource *io_add_watch_poll(Chardev *chr,
|
||||||
return (GSource *)iwp;
|
return (GSource *)iwp;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_fd_in_watch(Chardev *chr)
|
void remove_fd_in_watch(Chardev *chr)
|
||||||
{
|
{
|
||||||
if (chr->gsource) {
|
if (chr->gsource) {
|
||||||
io_remove_watch_poll(chr->gsource);
|
g_source_destroy(chr->gsource);
|
||||||
chr->gsource = NULL;
|
chr->gsource = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue