This change is a replicate of the previous one. Signed-off-by: Fam Zheng <f...@redhat.com> --- slirp/slirp.c | 95 ++++++++++++++++++++++++----------------------------------- 1 file changed, 39 insertions(+), 56 deletions(-)
diff --git a/slirp/slirp.c b/slirp/slirp.c index f648e6c..a031240 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -286,6 +286,44 @@ static void slirp_update_timeout(uint32_t *timeout) *timeout = t; } +static void slirp_udb_read(void *opaque) +{ + struct socket *so = opaque; + sorecvfrom(so); +} + +static bool slirp_poll_update_udb(struct socket *so) +{ + bool ret = false; + bool old, new; + /* + * See if it's timed out + */ + if (so->so_expire) { + if (so->so_expire <= curtime) { + udp_detach(so); + qemu_set_fd_handler(so->s, NULL, NULL, NULL); + return ret; + } else { + ret = true; + } + } + + new = so->so_state & SS_ISFCONNECTED && so->so_queued <= 4; + old = so->poll_events == G_IO_IN; + if (old != new) { + /* Need update */ + if (new) { + so->poll_events = G_IO_IN; + qemu_set_fd_handler(so->s, slirp_udb_read, NULL, so); + } else { + so->poll_events = 0; + qemu_set_fd_handler(so->s, NULL, NULL, NULL); + } + } + return ret; +} + static void slirp_icmp_read(void *opaque) { struct socket *so = opaque; @@ -428,39 +466,7 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) { so_next = so->so_next; - - so->pollfds_idx = -1; - - /* - * See if it's timed out - */ - if (so->so_expire) { - if (so->so_expire <= curtime) { - udp_detach(so); - continue; - } else { - slirp->do_slowtimo = true; /* Let socket expire */ - } - } - - /* - * When UDP packets are received from over the - * link, they're sendto()'d straight away, so - * no need for setting for writing - * Limit the number of packets queued by this session - * to 4. Note that even though we try and limit this - * to 4 packets, the session could have more queued - * if the packets needed to be fragmented - * (XXX <= 4 ?) - */ - if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { - GPollFD pfd = { - .fd = so->s, - .events = G_IO_IN | G_IO_HUP | G_IO_ERR, - }; - so->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); - } + slirp->do_slowtimo |= slirp_poll_update_udb(so); } /* @@ -595,29 +601,6 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) */ } } - - /* - * Now UDP sockets. - * Incoming packets are sent straight away, they're not buffered. - * Incoming UDP data isn't buffered either. - */ - for (so = slirp->udb.so_next; so != &slirp->udb; - so = so_next) { - int revents; - - so_next = so->so_next; - - revents = 0; - if (so->pollfds_idx != -1) { - revents = g_array_index(pollfds, GPollFD, - so->pollfds_idx).revents; - } - - if (so->s != -1 && - (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) { - sorecvfrom(so); - } - } } if_start(slirp); -- 2.4.2