Fix decompose() implementations to work with non-starter non-composables
[framework/uifw/harfbuzz.git] / src / hb-common.cc
index 02314b3..a886474 100644 (file)
@@ -162,22 +162,24 @@ struct hb_language_item_t {
   void finish (void) { free (lang); }
 };
 
-static hb_threadsafe_set_t<hb_language_item_t> langs;
+static hb_static_mutex_t langs_lock;
+static hb_lockable_set_t<hb_language_item_t, hb_static_mutex_t> langs;
 
 hb_language_t
 hb_language_from_string (const char *str)
 {
   if (!str || !*str)
-    return NULL;
+    return HB_LANGUAGE_INVALID;
 
-  hb_language_item_t *item = langs.find_or_insert (str);
+  hb_language_item_t *item = langs.find_or_insert (str, langs_lock);
 
-  return likely (item) ? item->lang : NULL;
+  return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
 }
 
 const char *
 hb_language_to_string (hb_language_t language)
 {
+  /* This is actually NULL-safe! */
   return language->s;
 }
 
@@ -293,8 +295,7 @@ hb_script_get_horizontal_direction (hb_script_t script)
  * should switch to using that insted for these too.
  */
 
-/* XXX  this can result in deadlocks because we call user callbacks */
-static hb_static_mutex_t user_data_mutex;
+static hb_static_mutex_t user_data_lock;
 
 bool
 hb_user_data_array_t::set (hb_user_data_key_t *key,
@@ -304,16 +305,12 @@ hb_user_data_array_t::set (hb_user_data_key_t *key,
   if (!key)
     return false;
 
-  hb_mutex_lock (&user_data_mutex);
-
   if (!data && !destroy) {
-    items.remove (key);
+    items.remove (key, user_data_lock);
     return true;
   }
   hb_user_data_item_t item = {key, data, destroy};
-  bool ret = !!items.insert (item);
-
-  hb_mutex_unlock (&user_data_mutex);
+  bool ret = !!items.replace_or_insert (item, user_data_lock);
 
   return ret;
 }
@@ -321,14 +318,15 @@ hb_user_data_array_t::set (hb_user_data_key_t *key,
 void *
 hb_user_data_array_t::get (hb_user_data_key_t *key)
 {
-  hb_mutex_lock (&user_data_mutex);
+  hb_user_data_item_t item = {NULL };
 
-  hb_user_data_item_t *item = items.find (key);
-  void *ret = item ? item->data : NULL;
-
-  hb_mutex_unlock (&user_data_mutex);
+  return items.find (key, &item, user_data_lock) ? item.data : NULL;
+}
 
-  return ret;
+void
+hb_user_data_array_t::finish (void)
+{
+  items.finish (user_data_lock);
 }