clang: Add annotations for thread safety check.
[sliver-openvswitch.git] / lib / ofp-msgs.c
index 47d7615..d136f73 100644 (file)
@@ -23,6 +23,7 @@
 #include "ofpbuf.h"
 #include "openflow/nicira-ext.h"
 #include "openflow/openflow.h"
+#include "ovs-thread.h"
 #include "vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(ofp_msgs);
@@ -109,8 +110,11 @@ static enum ofperr ofpraw_from_ofphdrs(enum ofpraw *, const struct ofphdrs *);
 static ovs_be32
 alloc_xid(void)
 {
-    static uint32_t next_xid = 1;
-    return htonl(next_xid++);
+    static atomic_uint32_t next_xid = ATOMIC_VAR_INIT(1);
+    uint32_t xid;
+
+    atomic_add(&next_xid, 1, &xid);
+    return htonl(xid);
 }
 \f
 static uint32_t
@@ -320,6 +324,23 @@ ofpraw_decode(enum ofpraw *raw, const struct ofp_header *oh)
     return ofpraw_pull(raw, &msg);
 }
 
+/* Does the same job as ofpraw_decode(), except that it assert-fails if
+ * ofpraw_decode() would have reported an error.  Thus, it's able to use the
+ * return value for the OFPRAW_* message type instead of an error code.
+ *
+ * (It only makes sense to use this function if you previously called
+ * ofpraw_decode() on the message and thus know that it's OK.) */
+enum ofpraw
+ofpraw_decode_assert(const struct ofp_header *oh)
+{
+    enum ofperr error;
+    enum ofpraw raw;
+
+    error = ofpraw_decode(&raw, oh);
+    ovs_assert(!error);
+    return raw;
+}
+
 /* Determines the OFPRAW_* type of the OpenFlow message in 'msg', which starts
  * at 'msg->data' and has length 'msg->size' bytes.  On success, returns 0 and
  * stores the type into '*rawp'.  On failure, returns an OFPERR_* error code
@@ -403,11 +424,11 @@ ofpraw_pull(enum ofpraw *rawp, struct ofpbuf *msg)
 }
 
 /* Does the same job as ofpraw_pull(), except that it assert-fails if
- * ofpbuf_pull() would have reported an error.  Thus, it's able to use the
+ * ofpraw_pull() would have reported an error.  Thus, it's able to use the
  * return value for the OFPRAW_* message type instead of an error code.
  *
  * (It only makes sense to use this function if you previously called
- * ofpbuf_decode() on the message and thus know that it's OK.) */
+ * ofpraw_decode() on the message and thus know that it's OK.) */
 enum ofpraw
 ofpraw_pull_assert(struct ofpbuf *msg)
 {
@@ -834,6 +855,8 @@ ofpmp_reserve(struct list *replies, size_t len)
 
         next = ofpbuf_new(MAX(1024, hdrs_len + len));
         ofpbuf_put(next, msg->data, hdrs_len);
+        next->l2 = next->data;
+        next->l3 = ofpbuf_tail(next);
         list_push_back(replies, &next->list_node);
 
         *ofpmp_flags__(msg->data) |= htons(OFPSF_REPLY_MORE);
@@ -969,9 +992,10 @@ ofpraw_from_ofphdrs(enum ofpraw *raw, const struct ofphdrs *hdrs)
 static void
 ofpmsgs_init(void)
 {
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
     const struct raw_info *info;
 
-    if (raw_instance_map.buckets) {
+    if (!ovsthread_once_start(&once)) {
         return;
     }
 
@@ -989,4 +1013,6 @@ ofpmsgs_init(void)
                         ofphdrs_hash(&inst->hdrs));
         }
     }
+
+    ovsthread_once_done(&once);
 }