Looks good to me.
On Thu, Aug 1, 2013 at 2:29 PM, Ben Pfaff <b...@nicira.com> wrote: > When an upcoming commit introduces thread safety into the netdev API, this > allows netdev-dummy to avoid adding more internal locking by taking > advantage of netdev_get_devices() refcounting. > > Signed-off-by: Ben Pfaff <b...@nicira.com> > --- > lib/netdev-dummy.c | 48 ++++++++++++++++++++++++++++++++++-------------- > 1 file changed, 34 insertions(+), 14 deletions(-) > > diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c > index e7dfe9f..dc3ddf8 100644 > --- a/lib/netdev-dummy.c > +++ b/lib/netdev-dummy.c > @@ -60,6 +60,8 @@ struct netdev_dummy { > struct list rxes; /* List of child "netdev_rx_dummy"s. */ > }; > > +static const struct netdev_class dummy_class; > + > /* Max 'recv_queue_len' in struct netdev_dummy. */ > #define NETDEV_DUMMY_MAX_QUEUE 100 > > @@ -71,8 +73,6 @@ struct netdev_rx_dummy { > bool listening; > }; > > -static struct shash dummy_netdevs = SHASH_INITIALIZER(&dummy_netdevs); > - > static const struct netdev_rx_class netdev_rx_dummy_class; > > static unixctl_cb_func netdev_dummy_set_admin_state; > @@ -106,8 +106,11 @@ netdev_rx_dummy_cast(const struct netdev_rx *rx) > static void > netdev_dummy_run(void) > { > + struct shash dummy_netdevs; > struct shash_node *node; > > + shash_init(&dummy_netdevs); > + netdev_get_devices(&dummy_class, &dummy_netdevs); > SHASH_FOR_EACH (node, &dummy_netdevs) { > struct netdev_dummy *dev = node->data; > size_t i; > @@ -202,7 +205,10 @@ netdev_dummy_run(void) > dev->streams[i] = dev->streams[--dev->n_streams]; > } > } > + > + netdev_close(&dev->up); > } > + shash_destroy(&dummy_netdevs); > } > > static void > @@ -216,8 +222,11 @@ dummy_stream_close(struct dummy_stream *s) > static void > netdev_dummy_wait(void) > { > + struct shash dummy_netdevs; > struct shash_node *node; > > + shash_init(&dummy_netdevs); > + netdev_get_devices(&dummy_class, &dummy_netdevs); > SHASH_FOR_EACH (node, &dummy_netdevs) { > struct netdev_dummy *dev = node->data; > size_t i; > @@ -234,7 +243,9 @@ netdev_dummy_wait(void) > } > stream_recv_wait(s->stream); > } > + netdev_close(&dev->up); > } > + shash_destroy(&dummy_netdevs); > } > > static int > @@ -265,8 +276,6 @@ netdev_dummy_create(const struct netdev_class *class, > const char *name, > > list_init(&netdev->rxes); > > - shash_add(&dummy_netdevs, name, netdev); > - > *netdevp = &netdev->up; > > return 0; > @@ -278,8 +287,6 @@ netdev_dummy_destroy(struct netdev *netdev_) > struct netdev_dummy *netdev = netdev_dummy_cast(netdev_); > size_t i; > > - shash_find_and_delete(&dummy_netdevs, > - netdev_get_name(netdev_)); > pstream_close(netdev->pstream); > for (i = 0; i < netdev->n_streams; i++) { > dummy_stream_close(&netdev->streams[i]); > @@ -677,13 +684,15 @@ netdev_dummy_receive(struct unixctl_conn *conn, > int argc, const char *argv[], void *aux OVS_UNUSED) > { > struct netdev_dummy *dummy_dev; > + struct netdev *netdev; > int i; > > - dummy_dev = shash_find_data(&dummy_netdevs, argv[1]); > - if (!dummy_dev) { > + netdev = netdev_from_name(argv[1]); > + if (!netdev || !is_dummy_class(netdev->netdev_class)) { > unixctl_command_reply_error(conn, "no such dummy netdev"); > - return; > + goto exit; > } > + dummy_dev = netdev_dummy_cast(netdev); > > for (i = 2; i < argc; i++) { > struct ofpbuf *packet; > @@ -691,7 +700,7 @@ netdev_dummy_receive(struct unixctl_conn *conn, > packet = eth_from_packet_or_flow(argv[i]); > if (!packet) { > unixctl_command_reply_error(conn, "bad packet syntax"); > - return; > + goto exit; > } > > dummy_dev->stats.rx_packets++; > @@ -701,6 +710,9 @@ netdev_dummy_receive(struct unixctl_conn *conn, > } > > unixctl_command_reply(conn, NULL); > + > +exit: > + netdev_close(netdev); > } > > static void > @@ -731,21 +743,29 @@ netdev_dummy_set_admin_state(struct unixctl_conn > *conn, int argc, > } > > if (argc > 2) { > - struct netdev_dummy *dummy_dev; > + struct netdev *netdev = netdev_from_name(argv[1]); > + if (netdev && is_dummy_class(netdev->netdev_class)) { > + struct netdev_dummy *dummy_dev = netdev_dummy_cast(netdev); > > - dummy_dev = shash_find_data(&dummy_netdevs, argv[1]); > - if (dummy_dev) { > netdev_dummy_set_admin_state__(dummy_dev, up); > + netdev_close(netdev); > } else { > unixctl_command_reply_error(conn, "Unknown Dummy Interface"); > + netdev_close(netdev); > return; > } > } else { > + struct shash dummy_netdevs; > struct shash_node *node; > > + shash_init(&dummy_netdevs); > + netdev_get_devices(&dummy_class, &dummy_netdevs); > SHASH_FOR_EACH (node, &dummy_netdevs) { > - netdev_dummy_set_admin_state__(node->data, up); > + struct netdev *netdev = node->data; > + netdev_dummy_set_admin_state__(netdev_dummy_cast(netdev), up); > + netdev_close(netdev); > } > + shash_destroy(&dummy_netdevs); > } > unixctl_command_reply(conn, "OK"); > } > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev >
_______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev