edje: fix huge memory leak.
authorcedric <cedric>
Wed, 22 Jun 2011 14:51:53 +0000 (14:51 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 22 Jun 2011 14:51:53 +0000 (14:51 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/edje@60593 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/edje_main.c
src/lib/edje_private.h
src/lib/edje_util.c

index 708f851..1b52eb8 100644 (file)
@@ -150,7 +150,7 @@ static Eina_Bool
 _text_class_member_free(const Eina_Hash *hash __UNUSED__,
                        const void *key,
                        void *data,
-                       void *fdata)
+                       void *fdata __UNUSED__)
 {
    _edje_text_class_member_direct_del(key, data);
    return EINA_TRUE;
index 9fe1ada..e2ebd43 100644 (file)
@@ -1545,7 +1545,7 @@ void              _edje_color_class_hash_free(void);
 Edje_Text_Class  *_edje_text_class_find(Edje *ed, const char *text_class);
 void              _edje_text_class_member_add(Edje *ed, const char *text_class);
 void              _edje_text_class_member_del(Edje *ed, const char *text_class);
-void              _edje_text_class_member_direct_del(const char *text_class, Eina_List *lookup);
+void              _edje_text_class_member_direct_del(const char *text_class, void *lookup);
 void              _edje_text_class_members_free(void);
 void              _edje_text_class_hash_free(void);
 
index cb76781..dc887ce 100644 (file)
@@ -32,6 +32,14 @@ struct _Edje_List_Foreach_Data
    Eina_List *list;
 };
 
+typedef struct _Edje_List_Refcount Edje_List_Refcount;
+struct _Edje_List_Refcount
+{
+   EINA_REFCOUNT;
+
+   Eina_List *lookup;
+};
+
 static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
 static Eina_Bool _edje_text_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
 static void _edje_object_image_preload_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
@@ -3711,34 +3719,46 @@ _edje_text_class_find(Edje *ed, const char *text_class)
 
 void
 _edje_text_class_member_direct_del(const char *text_class,
-                                   Eina_List *lookup)
+                                   void *l)
 {
+   Edje_List_Refcount *lookup = l;
    Eina_List *members;
 
    members = eina_hash_find(_edje_text_class_member_hash, text_class);
-   members = eina_list_remove_list(members, lookup);
+   members = eina_list_remove_list(members, lookup->lookup);
    eina_hash_set(_edje_text_class_member_hash, text_class, members);
+   free(lookup);
 }
 
 void
 _edje_text_class_member_add(Edje *ed, const char *text_class)
 {
+   Edje_List_Refcount *lookup;
    Eina_List *members;
 
    if ((!ed) || (!text_class)) return;
 
+   lookup = eina_hash_find(ed->members, text_class);
+   if (lookup)
+     {
+        EINA_REFCOUNT_REF(lookup);
+        return;
+     }
+
+   lookup = malloc(sizeof (Edje_List_Refcount));
+   if (!lookup) return ;
+   EINA_REFCOUNT_INIT(lookup);
+
    /* Get members list */
    members = eina_hash_find(_edje_text_class_member_hash, text_class);
 
    /* Update the member list */
-   members = eina_list_prepend(members, ed);
-   if (eina_list_count(members) > 50000)
-      printf("ERRRRRRRRRROR. CEDRIC BROKE ME! I NOW LEAK TEXTCLASSES\n");
+   lookup->lookup = members = eina_list_prepend(members, ed);
 
    /* Don't loose track of members list */
    if (!ed->members)
      ed->members = eina_hash_string_small_new(NULL);
-   eina_hash_set(ed->members, text_class, members);
+   eina_hash_add(ed->members, text_class, lookup);
 
    /* Reset the member list to the right pointer */
    if (!_edje_text_class_member_hash)
@@ -3749,21 +3769,24 @@ _edje_text_class_member_add(Edje *ed, const char *text_class)
 void
 _edje_text_class_member_del(Edje *ed, const char *text_class)
 {
+   Edje_List_Refcount *lookup;
    Eina_List *members;
-   Eina_List *lookup;
 
    if ((!ed) || (!text_class)) return;
    members = eina_hash_find(_edje_text_class_member_hash, text_class);
    if (!members) return;
 
    lookup = eina_hash_find(ed->members, text_class);
-
    if (!lookup) return ;
 
-   eina_hash_del(ed->members, text_class, lookup);
-   members = eina_list_remove_list(members, lookup);
+   EINA_REFCOUNT_UNREF(lookup)
+   {
+      members = eina_list_remove_list(members, lookup->lookup);
+      eina_hash_set(_edje_text_class_member_hash, text_class, members);
 
-   eina_hash_set(_edje_text_class_member_hash, text_class, members);
+      eina_hash_del(ed->members, text_class, lookup);
+      free(lookup);
+   }
 }
 
 void