Преглед изворни кода

Fix bh_vector extend_vector not locked issue (#1187)

Fix issue that func `extend_vector` isn't locked in vector insert and append.
liang.he пре 3 година
родитељ
комит
565c1c04db
1 измењених фајлова са 29 додато и 15 уклоњено
  1. 29 15
      core/shared/utils/bh_vector.c

+ 29 - 15
core/shared/utils/bh_vector.c

@@ -23,6 +23,10 @@ alloc_vector_data(size_t length, size_t size_elem)
     return data;
 }
 
+/**
+ * every caller of `extend_vector` must provide
+ * a thread-safe environment.
+ */
 static bool
 extend_vector(Vector *vector, size_t length)
 {
@@ -38,15 +42,11 @@ extend_vector(Vector *vector, size_t length)
         return false;
     }
 
-    if (vector->lock)
-        os_mutex_lock(vector->lock);
     memcpy(data, vector->data, vector->size_elem * vector->max_elems);
     BH_FREE(vector->data);
 
     vector->data = data;
     vector->max_elems = length;
-    if (vector->lock)
-        os_mutex_unlock(vector->lock);
     return true;
 }
 
@@ -143,24 +143,26 @@ bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
 {
     size_t i;
     uint8 *p;
+    bool ret = false;
 
     if (!vector || !elem_buf) {
         LOG_ERROR("Insert vector elem failed: vector or elem buf is NULL.\n");
-        return false;
+        goto just_return;
     }
 
     if (index >= vector->num_elems) {
         LOG_ERROR("Insert vector elem failed: invalid elem index.\n");
-        return false;
+        goto just_return;
     }
 
+    if (vector->lock)
+        os_mutex_lock(vector->lock);
+
     if (!extend_vector(vector, vector->num_elems + 1)) {
         LOG_ERROR("Insert vector elem failed: extend vector failed.\n");
-        return false;
+        goto unlock_return;
     }
 
-    if (vector->lock)
-        os_mutex_lock(vector->lock);
     p = vector->data + vector->size_elem * vector->num_elems;
     for (i = vector->num_elems - 1; i > index; i--) {
         memcpy(p, p - vector->size_elem, vector->size_elem);
@@ -169,32 +171,44 @@ bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
 
     memcpy(p, elem_buf, vector->size_elem);
     vector->num_elems++;
+    ret = true;
+
+unlock_return:
     if (vector->lock)
         os_mutex_unlock(vector->lock);
-    return true;
+just_return:
+    return ret;
 }
 
 bool
 bh_vector_append(Vector *vector, const void *elem_buf)
 {
+    bool ret = false;
+
     if (!vector || !elem_buf) {
         LOG_ERROR("Append vector elem failed: vector or elem buf is NULL.\n");
-        return false;
+        goto just_return;
     }
 
+    /* make sure one more slot is used by the thread who allocas it */
+    if (vector->lock)
+        os_mutex_lock(vector->lock);
+
     if (!extend_vector(vector, vector->num_elems + 1)) {
         LOG_ERROR("Append ector elem failed: extend vector failed.\n");
-        return false;
+        goto unlock_return;
     }
 
-    if (vector->lock)
-        os_mutex_lock(vector->lock);
     memcpy(vector->data + vector->size_elem * vector->num_elems, elem_buf,
            vector->size_elem);
     vector->num_elems++;
+    ret = true;
+
+unlock_return:
     if (vector->lock)
         os_mutex_unlock(vector->lock);
-    return true;
+just_return:
+    return ret;
 }
 
 bool