summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2017-03-09 15:51:00 -0800
committerCedric BAIL <cedric@osg.samsung.com>2017-03-09 16:17:58 -0800
commit614c255f3b96a1f22d51b237aabfdd086fa29446 (patch)
treeac3b5e5f56fce88336ae43335251b267e89be8ed
parentadf9608387892fbea82cd8440808c90aa0215fee (diff)
ecore: add ecore_event_type_flush.
During shutdown it is possible that some event are still in ecore events queue and get processed after the shutdown of the module that did emit them. This would lead to crash in some case. The answer to this problem is to normally manually track all ecore event in the queue and destroy them before shutdown... Of course that make the API difficult to use and basically nobody got it right. This new API do actually as it says remove all the ecore event of a certain type from ecore events queue. It is to be called on shutdown. @fix
-rw-r--r--src/lib/ecore/Ecore_Common.h20
-rw-r--r--src/lib/ecore/ecore_events.c54
2 files changed, 74 insertions, 0 deletions
diff --git a/src/lib/ecore/Ecore_Common.h b/src/lib/ecore/Ecore_Common.h
index fe3c9bd3da..49e7e1ce1d 100644
--- a/src/lib/ecore/Ecore_Common.h
+++ b/src/lib/ecore/Ecore_Common.h
@@ -748,6 +748,26 @@ EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *dat
748EAPI int ecore_event_type_new(void); 748EAPI int ecore_event_type_new(void);
749 749
750/** 750/**
751 * @brief Forcefully flush all pending type without processing them
752 * @param Serie of Ecore_Event finished by ECORE_EVENT_NONE.
753 *
754 * This function is to be called before calling ecore_shutdown() if any event
755 * has still a chance to be in the ecore event queue.
756 */
757EAPI void ecore_event_type_flush_internal(int type, ...);
758
759/**
760 * @brief Forcefully flush all pending type without processing them
761 * @param Serie of Ecore_Event.
762 *
763 * This function is to be called before calling ecore_shutdown() if any event
764 * has still a chance to be in the ecore event queue.
765 */
766#define ecore_event_type_flush(...) \
767 ecore_event_type_flush_internal(__VA_ARGS__, ECORE_EVENT_NONE);
768
769
770/**
751 * @brief Adds a filter the current event queue. 771 * @brief Adds a filter the current event queue.
752 * 772 *
753 * @param func_start Function to call just before filtering and return data 773 * @param func_start Function to call just before filtering and return data
diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c
index aa4bde56ed..96c48bb93a 100644
--- a/src/lib/ecore/ecore_events.c
+++ b/src/lib/ecore/ecore_events.c
@@ -606,3 +606,57 @@ _ecore_event_signal_realtime_new(void)
606 return calloc(1, sizeof(Ecore_Event_Signal_Realtime)); 606 return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
607} 607}
608 608
609EAPI void
610ecore_event_type_flush_internal(int type, ...)
611{
612 Eina_Inarray types;
613 Ecore_Event *event;
614 Eina_Inlist *l;
615 int *itr;
616 va_list args;
617 Eina_Bool wrong_type = EINA_FALSE;
618
619 eina_inarray_step_set(&types, sizeof (Eina_Inarray), sizeof (int), 4);
620
621 eina_inarray_push(&types, &type);
622
623 // In case of an empty list of event
624 if (type != ECORE_EVENT_NONE) return ;
625
626 va_start(args, type);
627 do
628 {
629 type = va_arg(args, int);
630 if (type == ECORE_EVENT_NONE) break ;
631 eina_inarray_push(&types, &type);
632 }
633 while (1);
634 va_end(args);
635
636 EINA_INARRAY_FOREACH(&types, itr)
637 {
638 if (*itr >= 0 && *itr < event_id_max) continue;
639
640 ERR("Invalide event flush requested %i\n", *itr);
641 wrong_type = EINA_TRUE;
642 }
643
644 if (wrong_type) return ;
645
646 EINA_INLIST_FOREACH_SAFE((Eina_Inlist *) events, l, event)
647 {
648 Eina_Bool found = EINA_FALSE;
649
650 EINA_INARRAY_FOREACH(&types, itr)
651 if (event->type == *itr)
652 found = EINA_TRUE;
653 if (!found) continue ;
654
655 if (event->delete_me) continue ;
656 event->delete_me = 1;
657 }
658
659 _ecore_event_purge_deleted();
660
661 eina_inarray_flush(&types);
662}