On Wed, Aug 28, 2019 at 12:37 PM Johannes Berg <johan...@sipsolutions.net> wrote: > > From: Johannes Berg <johannes.b...@intel.com> > > If you try to make a device implementation that can handle multiple > connections and allow disconnections (which requires overriding the > VHOST_USER_NONE handling), then glib will warn that we remove a src > while it's still on the mainloop, and will poll() an FD that doesn't > exist anymore. > > Fix this by making vug_source_new() require pairing with the new > vug_source_destroy() so we can keep the GSource referenced in the > meantime. > > Note that this requires calling the new API in vhost-user-input. > vhost-user-gpu also uses vug_source_new(), but never seems to free > the result at all, so I haven't changed anything there. > > Fixes: 8bb7ddb78a1c ("libvhost-user: add glib source helper") > Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > contrib/libvhost-user/libvhost-user-glib.c | 15 ++++++++++++--- > contrib/libvhost-user/libvhost-user-glib.h | 1 + > contrib/vhost-user-input/main.c | 6 ++---- > 3 files changed, 15 insertions(+), 7 deletions(-) > > diff --git a/contrib/libvhost-user/libvhost-user-glib.c > b/contrib/libvhost-user/libvhost-user-glib.c > index 99edd2f3de45..824c7780de61 100644 > --- a/contrib/libvhost-user/libvhost-user-glib.c > +++ b/contrib/libvhost-user/libvhost-user-glib.c > @@ -91,7 +91,6 @@ vug_source_new(VugDev *gdev, int fd, GIOCondition cond, > g_source_add_poll(gsrc, &src->gfd); > id = g_source_attach(gsrc, NULL); > g_assert(id); > - g_source_unref(gsrc); > > return gsrc; > } > @@ -131,6 +130,16 @@ static void vug_watch(VuDev *dev, int condition, void > *data) > } > } > > +void vug_source_destroy(GSource *src) > +{ > + if (!src) { > + return; > + } > + > + g_source_destroy(src); > + g_source_unref(src); > +} > + > bool > vug_init(VugDev *dev, uint16_t max_queues, int socket, > vu_panic_cb panic, const VuDevIface *iface) > @@ -144,7 +153,7 @@ vug_init(VugDev *dev, uint16_t max_queues, int socket, > } > > dev->fdmap = g_hash_table_new_full(NULL, NULL, NULL, > - (GDestroyNotify) g_source_destroy); > + (GDestroyNotify) vug_source_destroy); > > dev->src = vug_source_new(dev, socket, G_IO_IN, vug_watch, NULL); > > @@ -157,5 +166,5 @@ vug_deinit(VugDev *dev) > g_assert(dev); > > g_hash_table_unref(dev->fdmap); > - g_source_unref(dev->src); > + vug_source_destroy(dev->src); > } > diff --git a/contrib/libvhost-user/libvhost-user-glib.h > b/contrib/libvhost-user/libvhost-user-glib.h > index 64d539d93aba..1a79a4916ef2 100644 > --- a/contrib/libvhost-user/libvhost-user-glib.h > +++ b/contrib/libvhost-user/libvhost-user-glib.h > @@ -31,5 +31,6 @@ void vug_deinit(VugDev *dev); > > GSource *vug_source_new(VugDev *dev, int fd, GIOCondition cond, > vu_watch_cb vu_cb, gpointer data); > +void vug_source_destroy(GSource *src); > > #endif /* LIBVHOST_USER_GLIB_H */ > diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c > index 449fd2171a5a..a990b3ea9e33 100644 > --- a/contrib/vhost-user-input/main.c > +++ b/contrib/vhost-user-input/main.c > @@ -187,7 +187,7 @@ vi_queue_set_started(VuDev *dev, int qidx, bool started) > } > > if (!started && vi->evsrc) { > - g_source_destroy(vi->evsrc); > + vug_source_destroy(vi->evsrc); > vi->evsrc = NULL; > } > } > @@ -401,9 +401,7 @@ main(int argc, char *argv[]) > > vug_deinit(&vi.dev); > > - if (vi.evsrc) { > - g_source_unref(vi.evsrc); > - } > + vug_source_destroy(vi.evsrc); > g_array_free(vi.config, TRUE); > g_free(vi.queue); > return 0; > -- > 2.23.0 > > -- Marc-André Lureau