From ce729baf05c22da6e68959f02133069bbfc28a34 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 2 Jun 2010 06:20:18 +0000 Subject: [PATCH] Fix ecore_events for recursive main loops This fixes the following scenario: 1) An event handler starts another main loop 2) The new main loop processes all the remaining event_handlers of this event and the remaining events 3) New events are added to the events list 4) A new iteration occurs Prior behavior was that on (4) the events already processed were triggered again. The code added to ecore_suite shows a test case, similar to the one that is fixed now for modal dialogs on WebKit-EFL. I preferred to let the INF() messages in order to be easy to copy, paste and debug outside of the suite if anyone wants to. When the number of tests grows more, we might want to separate them in different files. By: Lucas De Marchi git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@49390 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/ecore/ecore_events.c | 1 + src/tests/ecore_test_ecore.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c index 22d089c..3af4060 100644 --- a/src/lib/ecore/ecore_events.c +++ b/src/lib/ecore/ecore_events.c @@ -575,6 +575,7 @@ _ecore_event_call(void) if (event_handler_current) /* may have changed in recursive main loops */ event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next; } + e->delete_me = 1; } /* if no handlers were set for EXIT signal - then default is */ /* to quit the main loop */ diff --git a/src/tests/ecore_test_ecore.c b/src/tests/ecore_test_ecore.c index 69430ef..d6bbac0 100644 --- a/src/tests/ecore_test_ecore.c +++ b/src/tests/ecore_test_ecore.c @@ -3,10 +3,15 @@ #endif #include +#include #include #include "ecore_suite.h" + +static int _log_dom; +#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__) + static int _quit_cb(void *data) { @@ -271,6 +276,70 @@ START_TEST(ecore_test_ecore_main_loop_event) } END_TEST +static int +_timer_quit_recursive(void *data) +{ + INF(" _timer_quit_recursive: begin"); + ecore_main_loop_quit(); /* quits inner main loop */ + INF(" _timer_quit_recursive: end"); + return 0; +} + +static int +_event_recursive_cb(void *data, int type, void *event) +{ + Ecore_Event *e; + static int guard = 0; + + /* If we enter this callback more than once, it's wrong! */ + fail_if(guard != 0); + guard++; + + INF(" event_recursive_cb: begin"); + + ecore_timer_add(1.0, _timer_quit_recursive, NULL); + INF(" add 1.0s timer (once) to trigger _timer_quit_recursive"); + + INF(" inner main loop begin (recurse)"); + ecore_main_loop_begin(); + INF(" inner main loop end (recurse)"); + + ecore_main_loop_quit(); /* quits outer main loop */ + + INF(" guard = %d", guard); + INF(" event_recursive_cb: end"); + return 0; +} + + +START_TEST(ecore_test_ecore_main_loop_event_recursive) +{ + /* This test tests if the event handlers are really called only once when + * recursive main loops are used and any number of events may have occurred + * between the beginning and the end of recursive main loop. + */ + Ecore_Event *e; + int type; + + _log_dom = eina_log_domain_register("test", EINA_COLOR_CYAN); + + INF("main: begin"); + ecore_init(); + + + type = ecore_event_type_new(); + ecore_event_handler_add(type, _event_recursive_cb, NULL); + e = ecore_event_add(type, NULL, NULL, NULL); + INF(" add event to trigger cb1: event=%p", e); + INF(" main loop begin"); + ecore_main_loop_begin(); + INF(" main loop end"); + + INF("main: end"); + ecore_shutdown(); +} +END_TEST + void ecore_test_ecore(TCase *tc) { tcase_add_test(tc, ecore_test_ecore_init); @@ -282,4 +351,5 @@ void ecore_test_ecore(TCase *tc) tcase_add_test(tc, ecore_test_ecore_main_loop_fd_handler); tcase_add_test(tc, ecore_test_ecore_main_loop_event); tcase_add_test(tc, ecore_test_ecore_main_loop_timer_inner); + tcase_add_test(tc, ecore_test_ecore_main_loop_event_recursive); } -- 2.7.4