slirp: use polling callbacks, drop glib requirement
It would be legitimate to use libslirp without glib. Let's add_poll/get_revents pair of callbacks to provide the same functionality. 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:
parent
6e513a78ea
commit
deaeb3f71d
72
net/slirp.c
72
net/slirp.c
|
@ -211,6 +211,71 @@ static const SlirpCb slirp_cb = {
|
||||||
.notify = qemu_notify_event,
|
.notify = qemu_notify_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int slirp_poll_to_gio(int events)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (events & SLIRP_POLL_IN) {
|
||||||
|
ret |= G_IO_IN;
|
||||||
|
}
|
||||||
|
if (events & SLIRP_POLL_OUT) {
|
||||||
|
ret |= G_IO_OUT;
|
||||||
|
}
|
||||||
|
if (events & SLIRP_POLL_PRI) {
|
||||||
|
ret |= G_IO_PRI;
|
||||||
|
}
|
||||||
|
if (events & SLIRP_POLL_ERR) {
|
||||||
|
ret |= G_IO_ERR;
|
||||||
|
}
|
||||||
|
if (events & SLIRP_POLL_HUP) {
|
||||||
|
ret |= G_IO_HUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int net_slirp_add_poll(int fd, int events, void *opaque)
|
||||||
|
{
|
||||||
|
GArray *pollfds = opaque;
|
||||||
|
GPollFD pfd = {
|
||||||
|
.fd = fd,
|
||||||
|
.events = slirp_poll_to_gio(events),
|
||||||
|
};
|
||||||
|
int idx = pollfds->len;
|
||||||
|
g_array_append_val(pollfds, pfd);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int slirp_gio_to_poll(int events)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (events & G_IO_IN) {
|
||||||
|
ret |= SLIRP_POLL_IN;
|
||||||
|
}
|
||||||
|
if (events & G_IO_OUT) {
|
||||||
|
ret |= SLIRP_POLL_OUT;
|
||||||
|
}
|
||||||
|
if (events & G_IO_PRI) {
|
||||||
|
ret |= SLIRP_POLL_PRI;
|
||||||
|
}
|
||||||
|
if (events & G_IO_ERR) {
|
||||||
|
ret |= SLIRP_POLL_ERR;
|
||||||
|
}
|
||||||
|
if (events & G_IO_HUP) {
|
||||||
|
ret |= SLIRP_POLL_HUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int net_slirp_get_revents(int idx, void *opaque)
|
||||||
|
{
|
||||||
|
GArray *pollfds = opaque;
|
||||||
|
|
||||||
|
return slirp_gio_to_poll(g_array_index(pollfds, GPollFD, idx).revents);
|
||||||
|
}
|
||||||
|
|
||||||
static void net_slirp_poll_notify(Notifier *notifier, void *data)
|
static void net_slirp_poll_notify(Notifier *notifier, void *data)
|
||||||
{
|
{
|
||||||
MainLoopPoll *poll = data;
|
MainLoopPoll *poll = data;
|
||||||
|
@ -218,12 +283,13 @@ static void net_slirp_poll_notify(Notifier *notifier, void *data)
|
||||||
|
|
||||||
switch (poll->state) {
|
switch (poll->state) {
|
||||||
case MAIN_LOOP_POLL_FILL:
|
case MAIN_LOOP_POLL_FILL:
|
||||||
slirp_pollfds_fill(s->slirp, poll->pollfds, &poll->timeout);
|
slirp_pollfds_fill(s->slirp, &poll->timeout,
|
||||||
|
net_slirp_add_poll, poll->pollfds);
|
||||||
break;
|
break;
|
||||||
case MAIN_LOOP_POLL_OK:
|
case MAIN_LOOP_POLL_OK:
|
||||||
case MAIN_LOOP_POLL_ERR:
|
case MAIN_LOOP_POLL_ERR:
|
||||||
slirp_pollfds_poll(s->slirp, poll->pollfds,
|
slirp_pollfds_poll(s->slirp, poll->state == MAIN_LOOP_POLL_ERR,
|
||||||
poll->state == MAIN_LOOP_POLL_ERR);
|
net_slirp_get_revents, poll->pollfds);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef LIBSLIRP_H
|
#ifndef LIBSLIRP_H
|
||||||
#define LIBSLIRP_H
|
#define LIBSLIRP_H
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
@ -15,8 +14,18 @@
|
||||||
|
|
||||||
typedef struct Slirp Slirp;
|
typedef struct Slirp Slirp;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SLIRP_POLL_IN = 1 << 0,
|
||||||
|
SLIRP_POLL_OUT = 1 << 1,
|
||||||
|
SLIRP_POLL_PRI = 1 << 2,
|
||||||
|
SLIRP_POLL_ERR = 1 << 3,
|
||||||
|
SLIRP_POLL_HUP = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
|
typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
|
||||||
typedef void (*SlirpTimerCb)(void *opaque);
|
typedef void (*SlirpTimerCb)(void *opaque);
|
||||||
|
typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
|
||||||
|
typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callbacks from slirp
|
* Callbacks from slirp
|
||||||
|
@ -63,9 +72,11 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
void slirp_cleanup(Slirp *slirp);
|
void slirp_cleanup(Slirp *slirp);
|
||||||
|
|
||||||
void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
|
void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
|
||||||
|
SlirpAddPollCb add_poll, void *opaque);
|
||||||
|
|
||||||
void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
|
void slirp_pollfds_poll(Slirp *slirp, int select_error,
|
||||||
|
SlirpGetREventsCb get_revents, void *opaque);
|
||||||
|
|
||||||
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
|
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
|
||||||
|
|
||||||
|
|
|
@ -386,7 +386,8 @@ static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout)
|
||||||
*timeout = t;
|
*timeout = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
|
||||||
|
SlirpAddPollCb add_poll, void *opaque)
|
||||||
{
|
{
|
||||||
struct socket *so, *so_next;
|
struct socket *so, *so_next;
|
||||||
|
|
||||||
|
@ -428,12 +429,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
||||||
* Set for reading sockets which are accepting
|
* Set for reading sockets which are accepting
|
||||||
*/
|
*/
|
||||||
if (so->so_state & SS_FACCEPTCONN) {
|
if (so->so_state & SS_FACCEPTCONN) {
|
||||||
GPollFD pfd = {
|
so->pollfds_idx = add_poll(so->s,
|
||||||
.fd = so->s,
|
SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
|
||||||
.events = G_IO_IN | G_IO_HUP | G_IO_ERR,
|
|
||||||
};
|
|
||||||
so->pollfds_idx = pollfds->len;
|
|
||||||
g_array_append_val(pollfds, pfd);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,12 +438,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
||||||
* Set for writing sockets which are connecting
|
* Set for writing sockets which are connecting
|
||||||
*/
|
*/
|
||||||
if (so->so_state & SS_ISFCONNECTING) {
|
if (so->so_state & SS_ISFCONNECTING) {
|
||||||
GPollFD pfd = {
|
so->pollfds_idx = add_poll(so->s,
|
||||||
.fd = so->s,
|
SLIRP_POLL_OUT | SLIRP_POLL_ERR, opaque);
|
||||||
.events = G_IO_OUT | G_IO_ERR,
|
|
||||||
};
|
|
||||||
so->pollfds_idx = pollfds->len;
|
|
||||||
g_array_append_val(pollfds, pfd);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +448,7 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
||||||
* we have something to send
|
* we have something to send
|
||||||
*/
|
*/
|
||||||
if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
|
if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
|
||||||
events |= G_IO_OUT | G_IO_ERR;
|
events |= SLIRP_POLL_OUT | SLIRP_POLL_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -464,16 +457,12 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
||||||
*/
|
*/
|
||||||
if (CONN_CANFRCV(so) &&
|
if (CONN_CANFRCV(so) &&
|
||||||
(so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
|
(so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
|
||||||
events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
|
events |= SLIRP_POLL_IN | SLIRP_POLL_HUP |
|
||||||
|
SLIRP_POLL_ERR | SLIRP_POLL_PRI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events) {
|
if (events) {
|
||||||
GPollFD pfd = {
|
so->pollfds_idx = add_poll(so->s, events, opaque);
|
||||||
.fd = so->s,
|
|
||||||
.events = events,
|
|
||||||
};
|
|
||||||
so->pollfds_idx = pollfds->len;
|
|
||||||
g_array_append_val(pollfds, pfd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,12 +497,8 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
||||||
* (XXX <= 4 ?)
|
* (XXX <= 4 ?)
|
||||||
*/
|
*/
|
||||||
if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
|
if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
|
||||||
GPollFD pfd = {
|
so->pollfds_idx = add_poll(so->s,
|
||||||
.fd = so->s,
|
SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
|
||||||
.events = G_IO_IN | G_IO_HUP | G_IO_ERR,
|
|
||||||
};
|
|
||||||
so->pollfds_idx = pollfds->len;
|
|
||||||
g_array_append_val(pollfds, pfd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,19 +523,16 @@ void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (so->so_state & SS_ISFCONNECTED) {
|
if (so->so_state & SS_ISFCONNECTED) {
|
||||||
GPollFD pfd = {
|
so->pollfds_idx = add_poll(so->s,
|
||||||
.fd = so->s,
|
SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
|
||||||
.events = G_IO_IN | G_IO_HUP | G_IO_ERR,
|
|
||||||
};
|
|
||||||
so->pollfds_idx = pollfds->len;
|
|
||||||
g_array_append_val(pollfds, pfd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slirp_update_timeout(slirp, timeout);
|
slirp_update_timeout(slirp, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
void slirp_pollfds_poll(Slirp *slirp, int select_error,
|
||||||
|
SlirpGetREventsCb get_revents, void *opaque)
|
||||||
{
|
{
|
||||||
struct socket *so, *so_next;
|
struct socket *so, *so_next;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -587,8 +569,7 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
||||||
|
|
||||||
revents = 0;
|
revents = 0;
|
||||||
if (so->pollfds_idx != -1) {
|
if (so->pollfds_idx != -1) {
|
||||||
revents = g_array_index(pollfds, GPollFD,
|
revents = get_revents(so->pollfds_idx, opaque);
|
||||||
so->pollfds_idx).revents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (so->so_state & SS_NOFDREF || so->s == -1) {
|
if (so->so_state & SS_NOFDREF || so->s == -1) {
|
||||||
|
@ -598,9 +579,9 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
||||||
/*
|
/*
|
||||||
* Check for URG data
|
* Check for URG data
|
||||||
* This will soread as well, so no need to
|
* This will soread as well, so no need to
|
||||||
* test for G_IO_IN below if this succeeds
|
* test for SLIRP_POLL_IN below if this succeeds
|
||||||
*/
|
*/
|
||||||
if (revents & G_IO_PRI) {
|
if (revents & SLIRP_POLL_PRI) {
|
||||||
ret = sorecvoob(so);
|
ret = sorecvoob(so);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* Socket error might have resulted in the socket being
|
/* Socket error might have resulted in the socket being
|
||||||
|
@ -611,7 +592,8 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
||||||
/*
|
/*
|
||||||
* Check sockets for reading
|
* Check sockets for reading
|
||||||
*/
|
*/
|
||||||
else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
|
else if (revents &
|
||||||
|
(SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR)) {
|
||||||
/*
|
/*
|
||||||
* Check for incoming connections
|
* Check for incoming connections
|
||||||
*/
|
*/
|
||||||
|
@ -636,7 +618,7 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
||||||
* Check sockets for writing
|
* Check sockets for writing
|
||||||
*/
|
*/
|
||||||
if (!(so->so_state & SS_NOFDREF) &&
|
if (!(so->so_state & SS_NOFDREF) &&
|
||||||
(revents & (G_IO_OUT | G_IO_ERR))) {
|
(revents & (SLIRP_POLL_OUT | SLIRP_POLL_ERR))) {
|
||||||
/*
|
/*
|
||||||
* Check for non-blocking, still-connecting sockets
|
* Check for non-blocking, still-connecting sockets
|
||||||
*/
|
*/
|
||||||
|
@ -689,12 +671,11 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
||||||
|
|
||||||
revents = 0;
|
revents = 0;
|
||||||
if (so->pollfds_idx != -1) {
|
if (so->pollfds_idx != -1) {
|
||||||
revents = g_array_index(pollfds, GPollFD,
|
revents = get_revents(so->pollfds_idx, opaque);
|
||||||
so->pollfds_idx).revents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (so->s != -1 &&
|
if (so->s != -1 &&
|
||||||
(revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
|
(revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
|
||||||
sorecvfrom(so);
|
sorecvfrom(so);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -710,12 +691,11 @@ void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
|
||||||
|
|
||||||
revents = 0;
|
revents = 0;
|
||||||
if (so->pollfds_idx != -1) {
|
if (so->pollfds_idx != -1) {
|
||||||
revents = g_array_index(pollfds, GPollFD,
|
revents = get_revents(so->pollfds_idx, opaque);
|
||||||
so->pollfds_idx).revents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (so->s != -1 &&
|
if (so->s != -1 &&
|
||||||
(revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
|
(revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
|
||||||
icmp_receive(so);
|
icmp_receive(so);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue