aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2019-01-17 15:43:55 +0400
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2019-02-07 15:49:08 +0200
commit1ab67b98cdd78b94ce818a7d0a964e3e4d7a4538 (patch)
tree6170bef3ba22ffbe442ccd9e0336bbbbc0e49297 /net
parent625a526b3298ce593983923b4d10fa582555f26d (diff)
downloadqemu-1ab67b98cdd78b94ce818a7d0a964e3e4d7a4538.zip
qemu-1ab67b98cdd78b94ce818a7d0a964e3e4d7a4538.tar.gz
qemu-1ab67b98cdd78b94ce818a7d0a964e3e4d7a4538.tar.bz2
slirp: replace global polling with per-instance & notifier
Remove hard-coded dependency on slirp in main-loop, and use a "poll" notifier instead. The notifier is registered per slirp instance. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Diffstat (limited to 'net')
-rw-r--r--net/slirp.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/net/slirp.c b/net/slirp.c
index 664ff1c..4d55f64 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -86,6 +86,7 @@ typedef struct SlirpState {
NetClientState nc;
QTAILQ_ENTRY(SlirpState) entry;
Slirp *slirp;
+ Notifier poll_notifier;
Notifier exit_notifier;
#ifndef _WIN32
gchar *smb_dir;
@@ -144,6 +145,7 @@ static void net_slirp_cleanup(NetClientState *nc)
SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
g_slist_free_full(s->fwd, slirp_free_fwd);
+ main_loop_poll_remove_notifier(&s->poll_notifier);
slirp_cleanup(s->slirp);
if (s->exit_notifier.notify) {
qemu_remove_exit_notifier(&s->exit_notifier);
@@ -209,6 +211,25 @@ static const SlirpCb slirp_cb = {
.notify = qemu_notify_event,
};
+static void net_slirp_poll_notify(Notifier *notifier, void *data)
+{
+ MainLoopPoll *poll = data;
+ SlirpState *s = container_of(notifier, SlirpState, poll_notifier);
+
+ switch (poll->state) {
+ case MAIN_LOOP_POLL_FILL:
+ slirp_pollfds_fill(s->slirp, poll->pollfds, &poll->timeout);
+ break;
+ case MAIN_LOOP_POLL_OK:
+ case MAIN_LOOP_POLL_ERR:
+ slirp_pollfds_poll(s->slirp, poll->pollfds,
+ poll->state == MAIN_LOOP_POLL_ERR);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static int net_slirp_init(NetClientState *peer, const char *model,
const char *name, int restricted,
bool ipv4, const char *vnetwork, const char *vhost,
@@ -429,6 +450,9 @@ static int net_slirp_init(NetClientState *peer, const char *model,
&slirp_cb, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
+ s->poll_notifier.notify = net_slirp_poll_notify;
+ main_loop_poll_add_notifier(&s->poll_notifier);
+
for (config = slirp_configs; config; config = config->next) {
if (config->flags & SLIRP_CFG_HOSTFWD) {
if (slirp_hostfwd(s, config->str, errp) < 0) {