diff --git a/src/lib/evas/Evas_Loader.h b/src/lib/evas/Evas_Loader.h index a5d138b35b..19535d5e33 100644 --- a/src/lib/evas/Evas_Loader.h +++ b/src/lib/evas/Evas_Loader.h @@ -134,6 +134,7 @@ typedef Efl_Image_Load_Error Evas_Load_Error; #define EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED EFL_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED #define EVAS_LOAD_ERROR_CORRUPT_FILE EFL_IMAGE_LOAD_ERROR_CORRUPT_FILE #define EVAS_LOAD_ERROR_UNKNOWN_FORMAT EFL_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT +#define EVAS_LOAD_ERROR_CANCELLED EFL_IMAGE_LOAD_ERROR_CANCELLED typedef Emile_Image_Animated_Loop_Hint Evas_Image_Animated_Loop_Hint; @@ -199,6 +200,22 @@ struct _Evas_Image_Load_Func EAPI Eina_Bool evas_module_register (const Evas_Module_Api *module, Evas_Module_Type type); EAPI Eina_Bool evas_module_unregister (const Evas_Module_Api *module, Evas_Module_Type type); +EAPI Eina_Bool evas_module_task_cancelled (void); + +#define EVAS_MODULE_TASK_CHECK(Count, Mask, Error, Error_Handler) \ + do { \ + Count++; \ + if ((Count & Mask) == Mask) \ + { \ + Count = 0; \ + if (evas_module_task_cancelled()) \ + { \ + *Error = EFL_IMAGE_LOAD_ERROR_CANCELLED; \ + goto Error_Handler; \ + } \ + } \ + } while (0) + #define EVAS_MODULE_DEFINE(Type, Tn, Name) \ Eina_Bool evas_##Tn##_##Name##_init(void) \ { \ diff --git a/src/lib/evas/file/evas_module.c b/src/lib/evas/file/evas_module.c index a7d46c2933..5c1f5d6c20 100644 --- a/src/lib/evas/file/evas_module.c +++ b/src/lib/evas/file/evas_module.c @@ -28,6 +28,51 @@ #define EVAS_MODULE_NO_VG_SAVERS 0 #endif +typedef struct _Evas_Module_Task Evas_Module_Task; +struct _Evas_Module_Task +{ + Eina_Bool (*cancelled)(void *data); + void *data; +}; + +static Eina_TLS task = 0; + +EAPI Eina_Bool +evas_module_task_cancelled(void) +{ + Evas_Module_Task *t; + + t = eina_tls_get(task); + if (!t) return EINA_FALSE; + + return t->cancelled(t->data); +} + +EAPI void +evas_module_task_register(Eina_Bool (*cancelled)(void *data), void *data) +{ + Evas_Module_Task *t; + + t = malloc(sizeof (Evas_Module_Task)); + if (!t) return ; + + t->cancelled = cancelled; + t->data = data; + + eina_tls_set(task, t); +} + +EAPI void +evas_module_task_unregister(void) +{ + Evas_Module_Task *t; + + t = eina_tls_get(task); + if (!t) return ; + + eina_tls_set(task, NULL); + free(t); +} static Eina_Hash *evas_modules[6] = { NULL, @@ -318,6 +363,8 @@ evas_module_init(void) evas_engines = eina_array_new(4); + eina_tls_cb_new(&task, (Eina_TLS_Delete_Cb) evas_module_task_unregister); + for (i = 0; evas_static_module[i].init; ++i) evas_static_module[i].init(); } @@ -694,6 +741,8 @@ evas_module_shutdown(void) eina_hash_free(evas_modules[EVAS_MODULE_TYPE_VG_SAVER]); evas_modules[EVAS_MODULE_TYPE_VG_SAVER] = NULL; + eina_tls_free(task); + EINA_LIST_FREE(evas_module_paths, path) free(path); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 1ac7e13848..8e15337e60 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1956,6 +1956,9 @@ Eina_Bool evas_preload_thread_cancelled_is(Evas_Preload_Pthread *thread); void _evas_walk(Evas_Public_Data *e_pd); void _evas_unwalk(Evas_Public_Data *e_pd); +EAPI void evas_module_task_register(Eina_Bool (*cancelled)(void *data), void *data); +EAPI void evas_module_task_unregister(void); + // expose for use in engines EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name); EAPI const char *_evas_module_libdir_get(void);