X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Fdpif-linux.c;h=a85a57b03bf905b4e2d09e22273f41ae29093f87;hb=10dcf8deec96f64e56450bea6cc8801253f15f51;hp=15283b282cb398642f40ea7d111694db8e607d42;hpb=43253595291318833572088595769b45a79c9c54;p=openvswitch diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 15283b28..a85a57b0 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "dpif-provider.h" @@ -35,6 +36,7 @@ #include "ofpbuf.h" #include "poll-loop.h" #include "rtnetlink.h" +#include "shash.h" #include "svec.h" #include "util.h" @@ -52,7 +54,7 @@ struct dpif_linux { /* Change notification. */ int local_ifindex; /* Ifindex of local port. */ - struct svec changed_ports; /* Ports that have changed. */ + struct shash changed_ports; /* Ports that have changed. */ struct rtnetlink_notifier port_notifier; bool change_error; }; @@ -172,7 +174,7 @@ dpif_linux_close(struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); rtnetlink_notifier_unregister(&dpif->port_notifier); - svec_destroy(&dpif->changed_ports); + shash_destroy(&dpif->changed_ports); free(dpif->local_ifname); close(dpif->fd); free(dpif); @@ -330,10 +332,12 @@ dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) if (dpif->change_error) { dpif->change_error = false; - svec_clear(&dpif->changed_ports); + shash_clear(&dpif->changed_ports); return ENOBUFS; - } else if (dpif->changed_ports.n) { - *devnamep = dpif->changed_ports.names[--dpif->changed_ports.n]; + } else if (!shash_is_empty(&dpif->changed_ports)) { + struct shash_node *node = shash_first(&dpif->changed_ports); + *devnamep = xstrdup(node->name); + shash_delete(&dpif->changed_ports, node); return 0; } else { return EAGAIN; @@ -344,7 +348,7 @@ static void dpif_linux_port_poll_wait(const struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); - if (dpif->changed_ports.n || dpif->change_error) { + if (!shash_is_empty(&dpif->changed_ports) || dpif->change_error) { poll_immediate_wake(); } else { rtnetlink_notifier_wait(); @@ -786,7 +790,7 @@ open_minor(int minor, struct dpif **dpifp) dpif->local_ifname = NULL; dpif->minor = minor; dpif->local_ifindex = 0; - svec_init(&dpif->changed_ports); + shash_init(&dpif->changed_ports); dpif->change_error = false; *dpifp = &dpif->dpif; } else { @@ -813,10 +817,7 @@ dpif_linux_port_changed(const struct rtnetlink_change *change, void *dpif_) { /* Our datapath changed, either adding a new port or deleting an * existing one. */ - if (!svec_contains(&dpif->changed_ports, change->ifname)) { - svec_add(&dpif->changed_ports, change->ifname); - svec_sort(&dpif->changed_ports); - } + shash_add_once(&dpif->changed_ports, change->ifname, NULL); } } else { dpif->change_error = true;