4 * Copyright (c) 2016 Nutanix Inc. All rights reserved.
5 * Copyright (c) 2017 Red Hat, Inc.
8 * Marc-André Lureau <mlureau@redhat.com>
9 * Felipe Franciosi <felipe@nutanix.com>
11 * This work is licensed under the terms of the GNU GPL, version 2 or
12 * later. See the COPYING file in the top-level directory.
15 #include "qemu/osdep.h"
17 #include "libvhost-user-glib.h"
19 /* glib event loop integration for libvhost-user and misc callbacks */
21 G_STATIC_ASSERT((int)G_IO_IN
== (int)VU_WATCH_IN
);
22 G_STATIC_ASSERT((int)G_IO_OUT
== (int)VU_WATCH_OUT
);
23 G_STATIC_ASSERT((int)G_IO_PRI
== (int)VU_WATCH_PRI
);
24 G_STATIC_ASSERT((int)G_IO_ERR
== (int)VU_WATCH_ERR
);
25 G_STATIC_ASSERT((int)G_IO_HUP
== (int)VU_WATCH_HUP
);
27 typedef struct VugSrc
{
34 vug_src_prepare(GSource
*gsrc
, gint
*timeout
)
43 vug_src_check(GSource
*gsrc
)
45 VugSrc
*src
= (VugSrc
*)gsrc
;
49 return src
->gfd
.revents
& src
->gfd
.events
;
53 vug_src_dispatch(GSource
*gsrc
, GSourceFunc cb
, gpointer data
)
55 VugSrc
*src
= (VugSrc
*)gsrc
;
59 ((vu_watch_cb
)cb
)(src
->dev
, src
->gfd
.revents
, data
);
61 return G_SOURCE_CONTINUE
;
64 static GSourceFuncs vug_src_funcs
= {
72 vug_source_new(VuDev
*dev
, int fd
, GIOCondition cond
,
73 vu_watch_cb vu_cb
, gpointer data
)
83 gsrc
= g_source_new(&vug_src_funcs
, sizeof(VugSrc
));
84 g_source_set_callback(gsrc
, (GSourceFunc
)vu_cb
, data
, NULL
);
88 src
->gfd
.events
= cond
;
90 g_source_add_poll(gsrc
, &src
->gfd
);
91 id
= g_source_attach(gsrc
, NULL
);
99 set_watch(VuDev
*vu_dev
, int fd
, int vu_evt
, vu_watch_cb cb
, void *pvt
)
108 dev
= container_of(vu_dev
, VugDev
, parent
);
109 src
= vug_source_new(vu_dev
, fd
, vu_evt
, cb
, pvt
);
110 g_hash_table_replace(dev
->fdmap
, GINT_TO_POINTER(fd
), src
);
114 remove_watch(VuDev
*vu_dev
, int fd
)
121 dev
= container_of(vu_dev
, VugDev
, parent
);
122 g_hash_table_remove(dev
->fdmap
, GINT_TO_POINTER(fd
));
126 static void vug_watch(VuDev
*dev
, int condition
, void *data
)
128 if (!vu_dispatch(dev
) != 0) {
129 dev
->panic(dev
, "Error processing vhost message");
134 vug_init(VugDev
*dev
, int socket
,
135 vu_panic_cb panic
, const VuDevIface
*iface
)
140 vu_init(&dev
->parent
, socket
, panic
, set_watch
, remove_watch
, iface
);
141 dev
->fdmap
= g_hash_table_new_full(NULL
, NULL
, NULL
,
142 (GDestroyNotify
) g_source_destroy
);
144 dev
->src
= vug_source_new(&dev
->parent
, socket
, G_IO_IN
, vug_watch
, NULL
);
148 vug_deinit(VugDev
*dev
)
152 g_hash_table_unref(dev
->fdmap
);
153 g_source_unref(dev
->src
);