netdev: New function netdev_reopen().
authorBen Pfaff <blp@nicira.com>
Thu, 8 Apr 2010 18:18:07 +0000 (11:18 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 8 Apr 2010 19:31:47 +0000 (12:31 -0700)
In the new wdp layer it is convenient to pass around copies of struct
wdp_port, which contains a struct netdev *.  To make this efficient
it makes sense to maintain a reference count in struct netdev itself, so
that copying and freeing copies of a netdev become just incrementing and
decrementing the reference count.  This commit adds that ability.

lib/netdev-provider.h
lib/netdev.c
lib/netdev.h

index 1eb1b1e..828b093 100644 (file)
@@ -73,6 +73,8 @@ struct netdev {
 
     enum netdev_flags save_flags;    /* Initial device flags. */
     enum netdev_flags changed_flags; /* Flags that we changed. */
+
+    int ref_cnt;                     /* Times this 'netdev' was opened. */
 };
 
 void netdev_init(struct netdev *, struct netdev_dev *);
index 4bdb7f1..ddec15a 100644 (file)
@@ -303,7 +303,6 @@ create_device(struct netdev_options *options, struct netdev_dev **netdev_devp)
  * If the 'may_open' flag is set then the call will succeed even if another
  * caller has already opened it.  It may be to false if the device should not
  * currently be open. */
-
 int
 netdev_open(struct netdev_options *options, struct netdev **netdevp)
 {
@@ -370,6 +369,14 @@ netdev_open_default(const char *name, struct netdev **netdevp)
     return netdev_open(&options, netdevp);
 }
 
+/* Increments the reference count on 'netdev'.  Returns 'netdev'. */
+struct netdev *
+netdev_reopen(struct netdev *netdev)
+{
+    netdev->ref_cnt++;
+    return netdev;
+}
+
 /* Reconfigures the device 'netdev' with 'args'.  'args' may be empty
  * or NULL if none are needed. */
 int
@@ -395,11 +402,13 @@ netdev_reconfigure(struct netdev *netdev, const struct shash *args)
     return 0;
 }
 
-/* Closes and destroys 'netdev'. */
+/* Decrements the reference count on 'netdev'.  If the reference count reaches
+ * zero, closes and destroys 'netdev'. */
 void
 netdev_close(struct netdev *netdev)
 {
-    if (netdev) {
+    assert(!netdev || netdev->ref_cnt > 0);
+    if (netdev && !--netdev->ref_cnt) {
         struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
 
         assert(netdev_dev->ref_cnt);
@@ -1062,6 +1071,7 @@ netdev_init(struct netdev *netdev, struct netdev_dev *netdev_dev)
 {
     memset(netdev, 0, sizeof *netdev);
     netdev->netdev_dev = netdev_dev;
+    netdev->ref_cnt = 1;
     list_push_back(&netdev_list, &netdev->node);
 }
 
index 27eb82e..8b75962 100644 (file)
@@ -101,6 +101,7 @@ void netdev_enumerate_types(struct svec *types);
 
 int netdev_open(struct netdev_options *, struct netdev **);
 int netdev_open_default(const char *name, struct netdev **);
+struct netdev *netdev_reopen(struct netdev *);
 int netdev_reconfigure(struct netdev *, const struct shash *args);
 void netdev_close(struct netdev *);