edje: make it possible for all upper layer function to query the exact same file.

With Eina_File we now can pass an efficient handler accross library boundary. Edje
and all underlayer already use it to avoid race condition when setting an Edje object.
Elementary and Enlightenment are still exposed to some potential race condition when
an Edje file is modified underneath there feet. With the following set of function it
should now be possible to avoid those race condition to:
edje_mmap_data_get
edje_mmap_collection_list
edje_mmap_collection_list_free
edje_mmap_group_exists
This commit is contained in:
Cedric Bail 2013-11-01 10:58:33 +09:00
parent 8447e652c7
commit cf452cc419
2 changed files with 125 additions and 32 deletions

View File

@ -118,6 +118,25 @@ EAPI int edje_shutdown (void);
*/
EAPI void edje_fontset_append_set (const char *fonts);
/**
* Get data from the file level data block of an edje mapped file
* @param file The mapped edje file
* @param key The data key
* @return The string value of the data or NULL if no key is found.
* Must be freed by the user when no longer needed.
*
* If an edje file test.edj is built from the following edc:
*
* data {
* item: "key1" "value1";
* item: "key2" "value2";
* }
* collections { ... }
*
* Then, edje_file_data_get("test.edj", "key1") will return "value1"
*/
EAPI char *edje_mmap_data_get(Eina_File *f, const char *key);
/**
* Get data from the file level data block of an edje file
* @param file The path to the .edj file
@ -134,6 +153,8 @@ EAPI void edje_fontset_append_set (const char *fonts);
* collections { ... }
*
* Then, edje_file_data_get("test.edj", "key1") will return "value1"
*
* @see edje_mmap_data_get()
*/
EAPI char *edje_file_data_get (const char *file, const char *key);
@ -1553,14 +1574,46 @@ typedef enum _Edje_Load_Error
EDJE_LOAD_ERROR_RECURSIVE_REFERENCE = 9 /**< The group/collection set to load from had <b>recursive references</b> on its components */
} Edje_Load_Error; /**< Edje file loading error codes one can get - see edje_load_error_str() too. */
/**
* Get a list of groups in an edje mapped file
* @param file The mapped file
*
* @return The Eina_List of group names (char *)
*
* Note: the list must be freed using edje_mmap_collection_list_free()
* when you are done with it.
*/
EAPI Eina_List *edje_mmap_collection_list(Eina_File *f);
/**
* Free file collection list
* @param lst The Eina_List of groups
*
* Frees the list returned by edje_mmap_collection_list().
*/
EAPI void edje_mmap_collection_list_free(Eina_List *lst);
/**
* Determine whether a group matching glob exists in an edje mapped file.
* @param file The mapped file
* @param glob A glob to match on
*
* @return 1 if a match is found, 0 otherwise
*/
EAPI Eina_Bool edje_mmap_group_exists(Eina_File *f, const char *glob);
/**
* Get a list of groups in an edje file
* @param file The path to the edje file
*
* @return The Eina_List of group names (char *)
* @see edje_mmap_collection_list()
*
* Note: the list must be freed using edje_file_collection_list_free()
* when you are done with it.
*
* @see edje_mmap_group_exists()
*/
EAPI Eina_List *edje_file_collection_list (const char *file);

View File

@ -156,17 +156,13 @@ edje_load_error_str(Edje_Load_Error error)
}
}
EAPI Eina_List *
edje_file_collection_list(const char *file)
edje_mmap_collection_list(Eina_File *f)
{
Eina_List *lst = NULL;
Eina_File *f;
Edje_File *edf;
int error_ret = 0;
if ((!file) || (!*file)) return 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)
@ -183,6 +179,21 @@ edje_file_collection_list(const char *file)
_edje_cache_file_unref(edf);
}
return lst;
}
EAPI Eina_List *
edje_file_collection_list(const char *file)
{
Eina_File *f;
Eina_List *lst;
if ((!file) || (!*file)) return NULL;
f = eina_file_open(file, EINA_FALSE);
lst = edje_mmap_collection_list(f);
eina_file_close(f);
return lst;
}
@ -197,24 +208,26 @@ edje_file_collection_list_free(Eina_List *lst)
}
}
EAPI void
edje_mmap_collection_list_free(Eina_List *lst)
{
edje_file_collection_list_free(lst);
}
EAPI Eina_Bool
edje_file_group_exists(const char *file, const char *glob)
edje_mmap_group_exists(Eina_File *f, const char *glob)
{
Edje_File *edf;
Eina_File *f;
int error_ret = 0;
Eina_Bool succeed = EINA_FALSE;
Eina_Bool is_glob = EINA_FALSE;
const char *p;
if ((!file) || (!*file) || (!glob))
if ((!f) || (!glob))
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;
if (!edf) return EINA_FALSE;
for (p = glob; *p; p++)
{
@ -257,39 +270,66 @@ edje_file_group_exists(const char *file, const char *glob)
}
_edje_cache_file_unref(edf);
DBG("edje_file_group_exists: '%s', '%s': %i.", file, glob, succeed);
DBG("edje_file_group_exists: '%s', '%s': %i.", eina_file_filename_get(f), glob, succeed);
on_error:
eina_file_close(f);
return succeed;
}
EAPI Eina_Bool
edje_file_group_exists(const char *file, const char *glob)
{
Eina_File *f;
Eina_Bool result;
if ((!file) || (!*file) || (!glob))
return EINA_FALSE;
f = eina_file_open(file, EINA_FALSE);
if (!f) return EINA_FALSE;
result = edje_mmap_group_exists(f, glob);
eina_file_close(f);
return result;
}
EAPI char *
edje_mmap_data_get(Eina_File *f, const char *key)
{
Edje_File *edf;
char *str = NULL;
int error_ret = 0;
if (!key) 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));
if (str) str = strdup(str);
_edje_cache_file_unref(edf);
}
return str;
}
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;
char *str;
if (key)
{
f = eina_file_open(file, EINA_FALSE);
if (!f) return NULL;
if (!key) 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));
f = eina_file_open(file, EINA_FALSE);
if (!f) return NULL;
if (str) str = strdup(str);
str = edje_mmap_data_get(f, key);
_edje_cache_file_unref(edf);
}
eina_file_close(f);
eina_file_close(f);
}
return str;
}