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 <lucas.demarchi@profusion.mobi>



SVN revision: 49390
This commit is contained in:
Lucas De Marchi 2010-06-02 06:20:18 +00:00
parent 7a935a6eac
commit c3dd8fa055
2 changed files with 71 additions and 0 deletions

View File

@ -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 */

View File

@ -3,10 +3,15 @@
#endif
#include <Ecore.h>
#include <Eina.h>
#include <unistd.h>
#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);
}