mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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>
This commit is contained in:
committed by
Samuel Thibault
parent
625a526b32
commit
1ab67b98cd
@@ -302,4 +302,19 @@ void qemu_fd_register(int fd);
|
||||
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
|
||||
void qemu_bh_schedule_idle(QEMUBH *bh);
|
||||
|
||||
enum {
|
||||
MAIN_LOOP_POLL_FILL,
|
||||
MAIN_LOOP_POLL_ERR,
|
||||
MAIN_LOOP_POLL_OK,
|
||||
};
|
||||
|
||||
typedef struct MainLoopPoll {
|
||||
int state;
|
||||
uint32_t timeout;
|
||||
GArray *pollfds;
|
||||
} MainLoopPoll;
|
||||
|
||||
void main_loop_poll_add_notifier(Notifier *notify);
|
||||
void main_loop_poll_remove_notifier(Notifier *notify);
|
||||
|
||||
#endif
|
||||
|
||||
+24
@@ -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) {
|
||||
|
||||
+2
-2
@@ -63,9 +63,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
|
||||
void *opaque);
|
||||
void slirp_cleanup(Slirp *slirp);
|
||||
|
||||
void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
|
||||
void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
|
||||
|
||||
void slirp_pollfds_poll(GArray *pollfds, int select_error);
|
||||
void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
|
||||
|
||||
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
|
||||
|
||||
|
||||
+309
-328
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,6 @@ stub-obj-y += qtest.o
|
||||
stub-obj-y += replay.o
|
||||
stub-obj-y += runstate-check.o
|
||||
stub-obj-y += set-fd-handler.o
|
||||
stub-obj-y += slirp.o
|
||||
stub-obj-y += sysbus.o
|
||||
stub-obj-y += tpm.o
|
||||
stub-obj-y += trace-control.o
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "slirp/libslirp.h"
|
||||
|
||||
void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
|
||||
{
|
||||
}
|
||||
|
||||
void slirp_pollfds_poll(GArray *pollfds, int select_error)
|
||||
{
|
||||
}
|
||||
|
||||
+24
-6
@@ -469,25 +469,42 @@ static int os_host_main_loop_wait(int64_t timeout)
|
||||
}
|
||||
#endif
|
||||
|
||||
static NotifierList main_loop_poll_notifiers =
|
||||
NOTIFIER_LIST_INITIALIZER(main_loop_poll_notifiers);
|
||||
|
||||
void main_loop_poll_add_notifier(Notifier *notify)
|
||||
{
|
||||
notifier_list_add(&main_loop_poll_notifiers, notify);
|
||||
}
|
||||
|
||||
void main_loop_poll_remove_notifier(Notifier *notify)
|
||||
{
|
||||
notifier_remove(notify);
|
||||
}
|
||||
|
||||
void main_loop_wait(int nonblocking)
|
||||
{
|
||||
MainLoopPoll mlpoll = {
|
||||
.state = MAIN_LOOP_POLL_FILL,
|
||||
.timeout = UINT32_MAX,
|
||||
.pollfds = gpollfds,
|
||||
};
|
||||
int ret;
|
||||
uint32_t timeout = UINT32_MAX;
|
||||
int64_t timeout_ns;
|
||||
|
||||
if (nonblocking) {
|
||||
timeout = 0;
|
||||
mlpoll.timeout = 0;
|
||||
}
|
||||
|
||||
/* poll any events */
|
||||
g_array_set_size(gpollfds, 0); /* reset for new iteration */
|
||||
/* XXX: separate device handlers from system ones */
|
||||
slirp_pollfds_fill(gpollfds, &timeout);
|
||||
notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
|
||||
|
||||
if (timeout == UINT32_MAX) {
|
||||
if (mlpoll.timeout == UINT32_MAX) {
|
||||
timeout_ns = -1;
|
||||
} else {
|
||||
timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS);
|
||||
timeout_ns = (uint64_t)mlpoll.timeout * (int64_t)(SCALE_MS);
|
||||
}
|
||||
|
||||
timeout_ns = qemu_soonest_timeout(timeout_ns,
|
||||
@@ -495,7 +512,8 @@ void main_loop_wait(int nonblocking)
|
||||
&main_loop_tlg));
|
||||
|
||||
ret = os_host_main_loop_wait(timeout_ns);
|
||||
slirp_pollfds_poll(gpollfds, (ret < 0));
|
||||
mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK;
|
||||
notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
|
||||
|
||||
/* CPU thread can infinitely wait for event after
|
||||
missing the warp */
|
||||
|
||||
Reference in New Issue
Block a user