edje: prevent segv when edje_object_signal_emit get nested and edje_object_signal_cal...
authorCedric BAIL <cedric.bail@free.fr>
Wed, 9 May 2012 07:09:59 +0000 (07:09 +0000)
committerCedric BAIL <cedric.bail@free.fr>
Wed, 9 May 2012 07:09:59 +0000 (07:09 +0000)
SVN revision: 70880

legacy/edje/ChangeLog
legacy/edje/NEWS
legacy/edje/src/lib/edje_private.h
legacy/edje/src/lib/edje_program.c

index ed36acc..aa22a7d 100644 (file)
 2012-05-08  Cedric Bail
 
        * Add edje_watch tools to automatically rebuild edc.
+
+2012-05-09  Cedric Bail
+
+       * Fix bug in case of nesting edje_object_signal_emit and edje_object_signal_callback_{add,del}
index 87c57ba..c9bc3e9 100644 (file)
@@ -11,6 +11,7 @@ Improvements:
 
 Fixes:
     * Add missing files in the tarballs.
+    * Prevent crash when running nested edje_object_signal_emit with edje_object_signal_callback_{add,del}.
 
 Edje 1.2.0
 
index 1d5aee9..85c312f 100644 (file)
@@ -1148,9 +1148,10 @@ struct _Edje
       void                  *data;
    } item_provider;
 
+   int                   walking_callbacks;
+
    unsigned int          dirty : 1;
    unsigned int          recalc : 1;
-   unsigned int          walking_callbacks : 1;
    unsigned int          delete_callbacks : 1;
    unsigned int          just_added_callbacks : 1;
    unsigned int          have_objects : 1;
@@ -1807,7 +1808,7 @@ void _edje_textblock_styles_del(Edje *ed);
 void _edje_textblock_style_all_update(Edje *ed);
 void _edje_textblock_style_parse_and_fix(Edje_File *edf);
 void _edje_textblock_style_cleanup(Edje_File *edf);
-Edje_File *_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret);
+Edje_File *_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed);
 void _edje_cache_coll_clean(Edje_File *edf);
 void _edje_cache_coll_flush(Edje_File *edf);
 void _edje_cache_coll_unref(Edje_File *edf, Edje_Part_Collection *edc);
index 575a328..407d213 100644 (file)
@@ -1289,7 +1289,7 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da
    if (ed->just_added_callbacks)
      _edje_callbacks_patterns_clean(ed);
 
-   ed->walking_callbacks = 1;
+   ed->walking_callbacks++;
 
    if (ed->callbacks)
      {
@@ -1321,14 +1321,15 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da
                {
                   escb->func(escb->data, ed->obj, sig, src);
                   if (_edje_block_break(ed))
-                    goto break_prog;
+                    break;
                }
           }
      }
    break_prog:
 
-   ed->walking_callbacks = 0;
-   if ((ed->delete_callbacks) || (ed->just_added_callbacks))
+   ed->walking_callbacks--;
+   if (!ed->walking_callbacks &&
+       ((ed->delete_callbacks) || (ed->just_added_callbacks)))
      {
        ed->delete_callbacks = 0;
        ed->just_added_callbacks = 0;