diff options
author | Cedric Bail <cedric.bail@samsung.com> | 2013-08-09 20:49:52 +0900 |
---|---|---|
committer | Cedric Bail <cedric.bail@samsung.com> | 2013-08-09 20:50:54 +0900 |
commit | 7506faaca2f5f7500426d4edaf3aaaef0e0ed707 (patch) | |
tree | 775622e59b72f45436e991251f42a92dceae30ea | |
parent | 861823848a853ae2646f45180f597775896e680e (diff) | |
download | efl-7506faaca2f5f7500426d4edaf3aaaef0e0ed707.tar.gz |
edje: add edje_file_mmap_set.
This reduce the number of system call to stat especially when using GROUP
and reduce the risk of a race condition when using GROUP.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/lib/edje/Edje_Eo.h | 14 | ||||
-rw-r--r-- | src/lib/edje/Edje_Legacy.h | 36 | ||||
-rw-r--r-- | src/lib/edje/edje_cache.c | 30 | ||||
-rw-r--r-- | src/lib/edje/edje_load.c | 79 | ||||
-rw-r--r-- | src/lib/edje/edje_private.h | 5 | ||||
-rw-r--r-- | src/lib/edje/edje_smart.c | 29 |
8 files changed, 145 insertions, 53 deletions
@@ -1,3 +1,7 @@ +2013-08-09 Cedric Bail + + * Edje: add edje_object_mmap_set(). + 2013-08-08 Tom Hacohen * Evas textblock: Make the ellipsis format the same as the surrounding. @@ -128,6 +128,7 @@ Additions: - support edc map color set - Add threshold support to Edje draggable part. - Reduce load time of Edje_Object using Evas_Object_Textblock and many styles. + - Add edje_object_mmap_set. * Eeze: - Add a dummy libmount replacement for when libmount is not there. * Ecore_Con: diff --git a/src/lib/edje/Edje_Eo.h b/src/lib/edje/Edje_Eo.h index 941aee4bb8..6678a96d02 100644 --- a/src/lib/edje/Edje_Eo.h +++ b/src/lib/edje/Edje_Eo.h @@ -132,6 +132,7 @@ enum EDJE_OBJ_SUB_ID_PART_EXTERNAL_PARAM_TYPE_GET, EDJE_OBJ_SUB_ID_FILE_SET, + EDJE_OBJ_SUB_ID_MMAP_SET, EDJE_OBJ_SUB_ID_FILE_GET, EDJE_OBJ_SUB_ID_LOAD_ERROR_GET, @@ -612,6 +613,19 @@ enum #define edje_obj_file_set(file, group, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_FILE_SET), EO_TYPECHECK(const char*, file), EO_TYPECHECK(const char *, group), EO_TYPECHECK(Eina_Bool *, ret) /** + * @def edje_obj_mmap_set + * @since 1.8 + * + * @param[in] file in + * @param[in] group in + * @param[in] nested in + * @param[out] ret out + * + * @see edje_object_file_set + */ +#define edje_obj_mmap_set(file, group, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MMAP_SET), EO_TYPECHECK(Eina_File*, file), EO_TYPECHECK(const char *, group), EO_TYPECHECK(Eina_Bool *, ret) + +/** * @def edje_obj_file_get * @since 1.8 * diff --git a/src/lib/edje/Edje_Legacy.h b/src/lib/edje/Edje_Legacy.h index 3b0ccabb3c..196e498a39 100644 --- a/src/lib/edje/Edje_Legacy.h +++ b/src/lib/edje/Edje_Legacy.h @@ -1770,10 +1770,46 @@ EAPI const char *edje_object_data_get (const Evas_Object *obj, const * * @see edje_object_add() * @see edje_object_file_get() + * @see edje_object_mmap_set() */ EAPI Eina_Bool edje_object_file_set (Evas_Object *obj, const char *file, const char *group); /** + * @brief Sets the @b EDJ file (and group within it) to load an Edje + * object's contents from + * + * @param obj A handle to an Edje object + * @param file The Eina_File pointing to the EDJ file to load @p from + * @param group The name of the group, in @p file, which implements an + * Edje object + * @return @c EINA_TRUE, on success or @c EINA_FALSE, on errors (check + * edje_object_load_error_get() after this call to get errors causes) + * + * Edje expects EDJ files, which are theming objects' descriptions and + * resources packed together in an EET file, to read Edje object + * definitions from. They usually are created with the @c .edj + * extension. EDJ files, in turn, are assembled from @b textual object + * description files, where one describes Edje objects declaratively + * -- the EDC files (see @ref edcref "the syntax" for those files). + * + * Those description files were designed so that many Edje object + * definitions -- also called @b groups (or collections) -- could be + * packed together <b>in the same EDJ file</b>, so that a whole + * application's theme could be packed in one file only. This is the + * reason for the @p group argument. + * + * Use this function after you instantiate a new Edje object, so that + * you can "give him life", telling where to get its contents from. + * + * @see edje_object_add() + * @see edje_object_file_get() + * @see edje_object_mmap_set() + * @since 1.8 + */ +EAPI Eina_Bool edje_object_mmap_set(Evas_Object *obj, Eina_File *file, const char *group); + + +/** * @brief Get the file and group name that a given Edje object is bound to * * @param obj A handle to an Edje object diff --git a/src/lib/edje/edje_cache.c b/src/lib/edje/edje_cache.c index aa7e075c5d..100ca556d3 100644 --- a/src/lib/edje/edje_cache.c +++ b/src/lib/edje/edje_cache.c @@ -399,32 +399,22 @@ _edje_file_dangling(Edje_File *edf) #endif Edje_File * -_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed) +_edje_cache_file_coll_open(Eina_File *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed) { - Eina_File *f; Edje_File *edf; Eina_List *l, *hist; Edje_Part_Collection *edc; Edje_Part *ep; - f = eina_file_open(file, EINA_FALSE); - if (!f) - { - *error_ret = EDJE_LOAD_ERROR_DOES_NOT_EXIST; - return NULL; - } - if (!_edje_file_hash) { _edje_file_hash = eina_hash_pointer_new(NULL); goto find_list; } - edf = eina_hash_find(_edje_file_hash, f); + edf = eina_hash_find(_edje_file_hash, file); if (edf) { - eina_file_close(f); - edf->references++; goto open; } @@ -432,23 +422,17 @@ _edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, E find_list: EINA_LIST_FOREACH(_edje_file_cache, l, edf) { - if (edf->f == f) + if (edf->f == file) { - eina_file_close(f); - edf->references = 1; _edje_file_cache = eina_list_remove_list(_edje_file_cache, l); - eina_hash_direct_add(_edje_file_hash, f, edf); + eina_hash_direct_add(_edje_file_hash, file, edf); goto open; } } - edf = _edje_file_open(f, coll, error_ret, edc_ret, eina_file_mtime_get(f)); - if (!edf) - { - eina_file_close(f); - return NULL; - } + edf = _edje_file_open(file, coll, error_ret, edc_ret, eina_file_mtime_get(file)); + if (!edf) return NULL; #ifdef HAVE_EIO if (ed) edf->edjes = eina_list_append(edf->edjes, ed); @@ -456,7 +440,7 @@ find_list: (void) ed; #endif - eina_hash_direct_add(_edje_file_hash, f, edf); + eina_hash_direct_add(_edje_file_hash, file, edf); /* return edf; */ open: diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 331dab57be..a65dbd5332 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -24,6 +24,8 @@ struct _Edje_Drag_Items } page; }; +void _edje_file_add(Edje *ed, Eina_File *f); + /* START - Nested part support */ #define _edje_smart_nested_type "Evas_Smart_Nested" typedef struct _Edje_Nested_Support Edje_Nested_Support; @@ -80,6 +82,16 @@ edje_object_file_set(Evas_Object *obj, const char *file, const char *group) return ret; } +EAPI Eina_Bool +edje_object_mmap_set(Evas_Object *obj, Eina_File *file, const char *group) +{ + if (!obj) return EINA_FALSE; + Eina_Bool ret = EINA_FALSE; + + eo_do(obj, edje_obj_mmap_set(file, group, &ret)); + return ret; +} + EAPI void edje_object_file_get(const Evas_Object *obj, const char **file, const char **group) { @@ -149,11 +161,14 @@ EAPI Eina_List * edje_file_collection_list(const char *file) { Eina_List *lst = NULL; + Eina_File *f; Edje_File *edf; int error_ret = 0; if ((!file) || (!*file)) return NULL; - edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL, NULL); + f = eina_file_open(file, EINA_FALSE); + if (!f) return NULL; + edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL); if (edf) { Eina_Iterator *i; @@ -168,6 +183,7 @@ edje_file_collection_list(const char *file) _edje_cache_file_unref(edf); } + eina_file_close(f); return lst; } @@ -185,6 +201,7 @@ EAPI Eina_Bool edje_file_group_exists(const char *file, const char *glob) { Edje_File *edf; + Eina_File *f; int error_ret = 0; Eina_Bool succeed = EINA_FALSE; Eina_Bool is_glob = EINA_FALSE; @@ -193,9 +210,11 @@ edje_file_group_exists(const char *file, const char *glob) if ((!file) || (!*file) || (!glob)) return EINA_FALSE; - edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL, NULL); - if (!edf) - return EINA_FALSE; + f = eina_file_open(file, EINA_FALSE); + if (!f) return EINA_FALSE; + + edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL); + if (!edf) goto on_error; for (p = glob; *p; p++) { @@ -240,6 +259,8 @@ edje_file_group_exists(const char *file, const char *glob) DBG("edje_file_group_exists: '%s', '%s': %i.", file, glob, succeed); + on_error: + eina_file_close(f); return succeed; } @@ -248,12 +269,16 @@ EAPI char * edje_file_data_get(const char *file, const char *key) { Edje_File *edf; + Eina_File *f; char *str = NULL; int error_ret = 0; if (key) { - edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL, NULL); + f = eina_file_open(file, EINA_FALSE); + if (!f) return NULL; + + edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL); if (edf) { str = (char*) edje_string_get(eina_hash_find(edf->data, key)); @@ -262,6 +287,8 @@ edje_file_data_get(const char *file, const char *key) _edje_cache_file_unref(edf); } + + eina_file_close(f); } return str; } @@ -290,7 +317,7 @@ _edje_physics_world_update_cb(void *data, EPhysics_World *world EINA_UNUSED, voi #endif int -_edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested) +_edje_object_file_set_internal(Evas_Object *obj, Eina_File *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested) { Edje *ed; Evas *tev; @@ -310,18 +337,11 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g ed = _edje_fetch(obj); if (!ed) return 0; - if (!file) file = ""; if (!group) group = ""; - if (((ed->path) && (!strcmp(file, ed->path))) && - (ed->group) && (!strcmp(group, ed->group)) && - ed->file) + if ((ed->file) && (ed->file->f == file) && + (ed->group) && (!strcmp(group, ed->group))) { - struct stat st; - - if (stat(file, &st) != 0) - return 1; - if (st.st_mtime == ed->file->mtime) - return 1; + return 1; } tev = evas_object_evas_get(obj); @@ -343,13 +363,13 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g _edje_file_del(ed); - eina_stringshare_replace(&ed->path, file); + eina_stringshare_replace(&ed->path, file ? eina_file_filename_get(file) : NULL); eina_stringshare_replace(&ed->group, group); ed->parent = eina_stringshare_add(parent); ed->load_error = EDJE_LOAD_ERROR_NONE; - _edje_file_add(ed); + _edje_file_add(ed, file); ed->block_break = EINA_FALSE; if (ed->file && ed->file->external_dir) @@ -567,7 +587,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g break; case EDJE_PART_TYPE_GRADIENT: ERR("SPANK ! SPANK ! SPANK ! YOU ARE USING GRADIENT IN PART %s FROM GROUP %s INSIDE FILE %s !! THEY ARE NOW REMOVED !", - ep->name, group, file); + ep->name, group, eina_file_filename_get(file)); break; case EDJE_PART_TYPE_SPACER: rp->object = NULL; @@ -834,7 +854,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g if (data == group_path_entry) { ERR("recursive loop group '%s' already included inside part '%s' of group '%s' from file '%s'", - group_path_entry, rp->part->name, group, file); + group_path_entry, rp->part->name, group, eina_file_filename_get(file)); ed->load_error = EDJE_LOAD_ERROR_RECURSIVE_REFERENCE; eina_stringshare_del(group_path_entry); goto on_error; @@ -862,7 +882,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g if (!_edje_object_file_set_internal(child_obj, file, source, rp->part->name, group_path, nested)) { ERR("impossible to set part '%s' of group '%s' from file '%s' to '%s'", - rp->part->name, group_path_entry, file, source); + rp->part->name, group_path_entry, eina_file_filename_get(file), source); ed->load_error = edje_object_load_error_get(child_obj); evas_object_del(child_obj); eina_stringshare_del(group_path_entry); @@ -1106,13 +1126,20 @@ on_error: } void -_edje_file_add(Edje *ed) +_edje_file_add(Edje *ed, Eina_File *f) { if (!_edje_edd_edje_file) return; - ed->file = _edje_cache_file_coll_open(ed->path, ed->group, - &(ed->load_error), - &(ed->collection), - ed); + if (!f) + { + ed->load_error = EDJE_LOAD_ERROR_DOES_NOT_EXIST; + } + else + { + ed->file = _edje_cache_file_coll_open(f, ed->group, + &(ed->load_error), + &(ed->collection), + ed); + } if (!ed->collection) { diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index b29b469b79..608aa01ccf 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -1967,9 +1967,8 @@ void *_edje_signal_callback_disable(const Edje_Signal_Callback_Group *cgp, EAPI void _edje_edd_init(void); EAPI void _edje_edd_shutdown(void); -int _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested); +int _edje_object_file_set_internal(Evas_Object *obj, Eina_File *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested); -void _edje_file_add(Edje *ed); void _edje_file_del(Edje *ed); void _edje_file_free(Edje_File *edf); void _edje_file_cache_shutdown(void); @@ -2150,7 +2149,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 *ed); +Edje_File *_edje_cache_file_coll_open(Eina_File *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); diff --git a/src/lib/edje/edje_smart.c b/src/lib/edje/edje_smart.c index e4590fb396..b692a5aba5 100644 --- a/src/lib/edje/edje_smart.c +++ b/src/lib/edje/edje_smart.c @@ -333,12 +333,37 @@ _edje_smart_file_set(Eo *obj, void *_pd EINA_UNUSED, va_list *list) const char *file = va_arg(*list, const char *); const char *group = va_arg(*list, const char *); Eina_Bool *ret = va_arg(*list, Eina_Bool *); + Eina_File *f; Eina_Array *nested; + if (ret) *ret = EINA_FALSE; + f = eina_file_open(file, EINA_FALSE); nested = eina_array_new(8); - if (_edje_object_file_set_internal(obj, file, group, NULL, NULL, nested)) + + if (_edje_object_file_set_internal(obj, f, group, NULL, NULL, nested)) if (ret) *ret = EINA_TRUE; + + eina_array_free(nested); + eina_file_close(f); + _edje_object_orientation_inform(obj); +} + +static void +_edje_smart_mmap_set(Eo *obj, void *_pd EINA_UNUSED, va_list *list) +{ + Eina_File *f = va_arg(*list, Eina_File *); + const char *group = va_arg(*list, const char *); + Eina_Bool *ret = va_arg(*list, Eina_Bool *); + Eina_Array *nested; + + if (ret) *ret = EINA_FALSE; + + nested = eina_array_new(8); + + if (_edje_object_file_set_internal(obj, f, group, NULL, NULL, nested)) + if (ret) *ret = EINA_TRUE; + eina_array_free(nested); _edje_object_orientation_inform(obj); } @@ -481,6 +506,7 @@ _edje_smart_class_constructor(Eo_Class *klass) EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_PART_EXTERNAL_CONTENT_GET), _part_external_content_get), EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_PART_EXTERNAL_PARAM_TYPE_GET), _part_external_param_type_get), EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_FILE_SET), _edje_smart_file_set), + EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MMAP_SET), _edje_smart_mmap_set), EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_FILE_GET), _file_get), EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_LOAD_ERROR_GET), _load_error_get), EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MESSAGE_SEND), _message_send), @@ -626,6 +652,7 @@ static const Eo_Op_Description op_desc[] = { EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_PART_EXTERNAL_CONTENT_GET, "Get an object contained in an part of type EXTERNAL"), EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_PART_EXTERNAL_PARAM_TYPE_GET, "Facility to query the type of the given parameter of the given part."), EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_FILE_SET, "Sets the @b EDJ file (and group within it) to load an Edje"), + EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_MMAP_SET, "Sets the @b EDJ file (and group within it) to load an Edje"), EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_FILE_GET, "Get the file and group name that a given Edje object is bound to"), EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_LOAD_ERROR_GET, "Gets the (last) file loading error for a given Edje object"), EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_MESSAGE_SEND, "Send an (Edje) message to a given Edje object"), |