forked from enlightenment/efl
evas/cserve2: Scan shared indexes in client side
Read Image descriptors from the shared arrays But, accessing the shared index can be a bit expensive, so try to read from the socket before scanning the index, without blocking.
This commit is contained in:
parent
08648ab2a5
commit
f5d0f0aec3
|
@ -549,8 +549,10 @@ evas_cache2_shutdown(Evas_Cache2 *cache)
|
||||||
free(cache);
|
free(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
EAPI void
|
||||||
_create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key, size_t keylen, Evas_Image_Load_Opts *lo)
|
evas_cache2_image_cache_key_create(char *hkey, const char *path, size_t pathlen,
|
||||||
|
const char *key, size_t keylen,
|
||||||
|
const Evas_Image_Load_Opts *lo)
|
||||||
{
|
{
|
||||||
const char *ckey = "(null)";
|
const char *ckey = "(null)";
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -561,6 +563,7 @@ _create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key,
|
||||||
memcpy(hkey + size, "//://", 5);
|
memcpy(hkey + size, "//://", 5);
|
||||||
size += 5;
|
size += 5;
|
||||||
if (key) ckey = key;
|
if (key) ckey = key;
|
||||||
|
else keylen = 6;
|
||||||
memcpy(hkey + size, ckey, keylen);
|
memcpy(hkey + size, ckey, keylen);
|
||||||
size += keylen;
|
size += keylen;
|
||||||
if (lo)
|
if (lo)
|
||||||
|
@ -634,7 +637,8 @@ _create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key,
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Image_Entry *
|
EAPI Image_Entry *
|
||||||
evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Evas_Image_Load_Opts *lo, int *error)
|
evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key,
|
||||||
|
Evas_Image_Load_Opts *lo, int *error)
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t pathlen;
|
size_t pathlen;
|
||||||
|
@ -659,7 +663,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Ev
|
||||||
size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
|
size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
|
||||||
hkey = alloca(sizeof(char) * size);
|
hkey = alloca(sizeof(char) * size);
|
||||||
|
|
||||||
_create_hash_key(hkey, path, pathlen, key, keylen, lo);
|
evas_cache2_image_cache_key_create(hkey, path, pathlen, key, keylen, lo);
|
||||||
DBG("Looking at the hash for key '%s'", hkey);
|
DBG("Looking at the hash for key '%s'", hkey);
|
||||||
|
|
||||||
/* use local var to copy default load options to the image entry */
|
/* use local var to copy default load options to the image entry */
|
||||||
|
@ -816,7 +820,8 @@ _scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h,
|
||||||
if (!smooth)
|
if (!smooth)
|
||||||
{
|
{
|
||||||
lo.scale_load.smooth = 1;
|
lo.scale_load.smooth = 1;
|
||||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
evas_cache2_image_cache_key_create(hkey, im->file, pathlen,
|
||||||
|
im->key, keylen, &lo);
|
||||||
|
|
||||||
ret = eina_hash_find(im->cache2->activ, hkey);
|
ret = eina_hash_find(im->cache2->activ, hkey);
|
||||||
if (ret) goto found;
|
if (ret) goto found;
|
||||||
|
@ -827,7 +832,8 @@ _scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h,
|
||||||
lo.scale_load.smooth = smooth;
|
lo.scale_load.smooth = smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
evas_cache2_image_cache_key_create(hkey, im->file, pathlen,
|
||||||
|
im->key, keylen, &lo);
|
||||||
|
|
||||||
ret = eina_hash_find(im->cache2->activ, hkey);
|
ret = eina_hash_find(im->cache2->activ, hkey);
|
||||||
if (ret) goto found;
|
if (ret) goto found;
|
||||||
|
@ -896,7 +902,8 @@ evas_cache2_image_scale_load(Image_Entry *im,
|
||||||
lo.scale_load.smooth = smooth;
|
lo.scale_load.smooth = smooth;
|
||||||
lo.scale_load.scale_hint = im->scale_hint;
|
lo.scale_load.scale_hint = im->scale_hint;
|
||||||
|
|
||||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
evas_cache2_image_cache_key_create(hkey, im->file, pathlen,
|
||||||
|
im->key, keylen, &lo);
|
||||||
|
|
||||||
ret = _evas_cache_image_entry_new(im->cache2, hkey, NULL, im->file, im->key,
|
ret = _evas_cache_image_entry_new(im->cache2, hkey, NULL, im->file, im->key,
|
||||||
&lo, &error);
|
&lo, &error);
|
||||||
|
|
|
@ -66,6 +66,7 @@ EAPI void evas_cache2_image_close(Image_Entry *im);
|
||||||
EAPI int evas_cache2_image_load_data(Image_Entry *ie);
|
EAPI int evas_cache2_image_load_data(Image_Entry *ie);
|
||||||
EAPI void evas_cache2_image_unload_data(Image_Entry *im);
|
EAPI void evas_cache2_image_unload_data(Image_Entry *im);
|
||||||
EAPI void evas_cache2_image_preload_data(Image_Entry *im, const void *target);
|
EAPI void evas_cache2_image_preload_data(Image_Entry *im, const void *target);
|
||||||
|
EAPI void evas_cache2_image_cache_key_create(char *hkey, const char *path, size_t pathlen, const char *key, size_t keylen, const Evas_Image_Load_Opts *lo);
|
||||||
|
|
||||||
EAPI DATA32 * evas_cache2_image_pixels(Image_Entry *im);
|
EAPI DATA32 * evas_cache2_image_pixels(Image_Entry *im);
|
||||||
EAPI Image_Entry * evas_cache2_image_writable(Image_Entry *im);
|
EAPI Image_Entry * evas_cache2_image_writable(Image_Entry *im);
|
||||||
|
|
|
@ -275,6 +275,7 @@ struct _Msg_Font_Debug {
|
||||||
*/
|
*/
|
||||||
struct _Msg_Index_List {
|
struct _Msg_Index_List {
|
||||||
Msg_Base base;
|
Msg_Base base;
|
||||||
|
int generation_id;
|
||||||
char strings_index_path[64];
|
char strings_index_path[64];
|
||||||
char strings_entries_path[64];
|
char strings_entries_path[64];
|
||||||
char files_index_path[64];
|
char files_index_path[64];
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
#ifdef EVAS_CSERVE2
|
#ifdef EVAS_CSERVE2
|
||||||
|
|
||||||
|
#define USE_SHARED_INDEX 1
|
||||||
|
#define SHARED_INDEX_ADD_TO_HASH 1
|
||||||
|
#define HKEY_LOAD_OPTS_STR_LEN 215
|
||||||
typedef void (*Op_Callback)(void *data, const void *msg, int size);
|
typedef void (*Op_Callback)(void *data, const void *msg, int size);
|
||||||
|
|
||||||
struct _File_Entry {
|
struct _File_Entry {
|
||||||
|
@ -47,6 +50,8 @@ static Eina_List *_requests = NULL;
|
||||||
static Index_Table _index;
|
static Index_Table _index;
|
||||||
static const char *_shared_string_get(int id);
|
static const char *_shared_string_get(int id);
|
||||||
static int _server_index_list_set(Msg_Base *data, int size);
|
static int _server_index_list_set(Msg_Base *data, int size);
|
||||||
|
static const File_Data *_shared_file_data_get_by_id(unsigned int id);
|
||||||
|
static const Shm_Object *_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id);
|
||||||
static const File_Data *_shared_image_entry_file_data_find(Image_Entry *ie);
|
static const File_Data *_shared_image_entry_file_data_find(Image_Entry *ie);
|
||||||
static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie);
|
static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie);
|
||||||
|
|
||||||
|
@ -902,10 +907,21 @@ int
|
||||||
evas_cserve2_image_load_wait(Image_Entry *ie)
|
evas_cserve2_image_load_wait(Image_Entry *ie)
|
||||||
{
|
{
|
||||||
const File_Data *fd;
|
const File_Data *fd;
|
||||||
|
Eina_Bool failed;
|
||||||
|
unsigned int rrid, rid;
|
||||||
|
|
||||||
if (!ie)
|
if (!ie)
|
||||||
return CSERVE2_GENERIC;
|
return CSERVE2_GENERIC;
|
||||||
|
|
||||||
|
if (!ie->open_rid)
|
||||||
|
return CSERVE2_NONE;
|
||||||
|
|
||||||
|
rid = ie->open_rid;
|
||||||
|
rrid = _server_dispatch(&failed);
|
||||||
|
if (rid == rrid)
|
||||||
|
return CSERVE2_NONE;
|
||||||
|
|
||||||
|
#if USE_SHARED_INDEX
|
||||||
fd = _shared_image_entry_file_data_find(ie);
|
fd = _shared_image_entry_file_data_find(ie);
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
|
@ -919,6 +935,7 @@ evas_cserve2_image_load_wait(Image_Entry *ie)
|
||||||
ie->open_rid = 0;
|
ie->open_rid = 0;
|
||||||
return CSERVE2_NONE;
|
return CSERVE2_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ie->open_rid)
|
if (ie->open_rid)
|
||||||
{
|
{
|
||||||
|
@ -959,6 +976,7 @@ evas_cserve2_image_load_data_wait(Image_Entry *ie)
|
||||||
if (!ie)
|
if (!ie)
|
||||||
return CSERVE2_GENERIC;
|
return CSERVE2_GENERIC;
|
||||||
|
|
||||||
|
#if USE_SHARED_INDEX
|
||||||
idata = _shared_image_entry_image_data_find(ie);
|
idata = _shared_image_entry_image_data_find(ie);
|
||||||
if (idata)
|
if (idata)
|
||||||
{
|
{
|
||||||
|
@ -997,6 +1015,7 @@ evas_cserve2_image_load_data_wait(Image_Entry *ie)
|
||||||
ie->load_rid = 0;
|
ie->load_rid = 0;
|
||||||
return CSERVE2_NONE;
|
return CSERVE2_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
load_wait:
|
load_wait:
|
||||||
if (ie->load_rid)
|
if (ie->load_rid)
|
||||||
|
@ -1607,6 +1626,7 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_F
|
||||||
|
|
||||||
// Fast access to shared index tables
|
// Fast access to shared index tables
|
||||||
|
|
||||||
|
static Eina_Bool _shared_index_remap_check(Shared_Index *si, int elemsize);
|
||||||
|
|
||||||
// Returns the number of correctly opened index arrays
|
// Returns the number of correctly opened index arrays
|
||||||
static int
|
static int
|
||||||
|
@ -1614,7 +1634,6 @@ _server_index_list_set(Msg_Base *data, int size)
|
||||||
{
|
{
|
||||||
Msg_Index_List *msg = (Msg_Index_List *) data;
|
Msg_Index_List *msg = (Msg_Index_List *) data;
|
||||||
unsigned sz;
|
unsigned sz;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
// TODO #1: Check populate rule.
|
// TODO #1: Check populate rule.
|
||||||
// TODO #2: Protect memory for read-only access.
|
// TODO #2: Protect memory for read-only access.
|
||||||
|
@ -1627,276 +1646,162 @@ _server_index_list_set(Msg_Base *data, int size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset index table
|
if (_index.generation_id == msg->generation_id)
|
||||||
if (_index.strings.index_file)
|
|
||||||
{
|
{
|
||||||
if (_index.strings.index_header)
|
ERR("New index generation_id is the same as before: %d",
|
||||||
eina_file_map_free(_index.strings.index_file,
|
_index.generation_id);
|
||||||
(void *) _index.strings.index_header);
|
|
||||||
eina_file_close(_index.strings.index_file);
|
|
||||||
}
|
|
||||||
if (_index.strings.entries_file)
|
|
||||||
{
|
|
||||||
if (_index.strings.index_header)
|
|
||||||
eina_file_map_free(_index.strings.entries_file,
|
|
||||||
(void *) _index.strings.index_header);
|
|
||||||
eina_file_close(_index.strings.entries_file);
|
|
||||||
}
|
|
||||||
if (_index.files.f)
|
|
||||||
{
|
|
||||||
if (_index.files.header)
|
|
||||||
eina_file_map_free(_index.files.f, (void *) _index.files.header);
|
|
||||||
eina_file_close(_index.files.f);
|
|
||||||
}
|
|
||||||
if (_index.images.f)
|
|
||||||
{
|
|
||||||
if (_index.images.header)
|
|
||||||
eina_file_map_free(_index.images.f, (void *) _index.images.header);
|
|
||||||
eina_file_close(_index.images.f);
|
|
||||||
}
|
|
||||||
if (_index.fonts.f)
|
|
||||||
{
|
|
||||||
if (_index.fonts.header)
|
|
||||||
eina_file_map_free(_index.fonts.f, (void *) _index.fonts.header);
|
|
||||||
eina_file_close(_index.fonts.f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open new indexes
|
_index.generation_id = msg->generation_id;
|
||||||
eina_strlcpy(_index.strings.index_path, msg->strings_index_path, 64);
|
|
||||||
eina_strlcpy(_index.strings.entries_path, msg->strings_entries_path, 64);
|
|
||||||
eina_strlcpy(_index.files.path, msg->files_index_path, 64);
|
|
||||||
eina_strlcpy(_index.images.path, msg->images_index_path, 64);
|
|
||||||
eina_strlcpy(_index.fonts.path, msg->fonts_index_path, 64);
|
|
||||||
|
|
||||||
if (_index.strings.index_path[0] && _index.strings.entries_path[0])
|
// 1. Strings (indexes and entries)
|
||||||
|
|
||||||
|
if (_index.strings_entries.data
|
||||||
|
&& strncmp(_index.strings_entries.path, msg->strings_entries_path,
|
||||||
|
SHARED_BUFFER_PATH_MAX) != 0)
|
||||||
{
|
{
|
||||||
_index.strings.index_file = eina_file_open(_index.strings.index_path,
|
DBG("Updating string entries shm to: '%s'", msg->strings_entries_path);
|
||||||
EINA_TRUE);
|
eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
|
||||||
sz = eina_file_size_get(_index.strings.index_file);
|
eina_file_close(_index.strings_entries.f);
|
||||||
_index.strings.index_header = eina_file_map_all(
|
_index.strings_entries.f = NULL;
|
||||||
_index.strings.index_file, EINA_FILE_POPULATE);
|
_index.strings_entries.data = NULL;
|
||||||
if (_index.strings.index_header && sz > sizeof(Shared_Array_Header)
|
}
|
||||||
&& sz >= (_index.strings.index_header->count * sizeof(Index_Entry)
|
|
||||||
+ sizeof(Shared_Array_Header)))
|
if (_index.strings_index.data
|
||||||
|
&& strncmp(_index.strings_index.path, msg->strings_index_path,
|
||||||
|
SHARED_BUFFER_PATH_MAX) != 0)
|
||||||
|
{
|
||||||
|
DBG("Updating string indexes shm to: '%s'", msg->strings_index_path);
|
||||||
|
eina_file_map_free(_index.strings_index.f, _index.strings_index.data);
|
||||||
|
eina_file_close(_index.strings_index.f);
|
||||||
|
_index.strings_index.f = NULL;
|
||||||
|
_index.strings_index.data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
eina_strlcpy(_index.strings_entries.path, msg->strings_entries_path, SHARED_BUFFER_PATH_MAX);
|
||||||
|
eina_strlcpy(_index.strings_index.path, msg->strings_index_path, SHARED_BUFFER_PATH_MAX);
|
||||||
|
|
||||||
|
if (!_index.strings_entries.data
|
||||||
|
&& _index.strings_entries.path[0]
|
||||||
|
&& _index.strings_index.path[0])
|
||||||
|
{
|
||||||
|
_index.strings_entries.f = eina_file_open(_index.strings_entries.path, EINA_TRUE);
|
||||||
|
_index.strings_entries.size = eina_file_size_get(_index.strings_entries.f);
|
||||||
|
if (_index.strings_entries.size > 0)
|
||||||
|
_index.strings_entries.data = eina_file_map_all(_index.strings_entries.f, EINA_FILE_RANDOM);
|
||||||
|
|
||||||
|
if (!_index.strings_entries.data)
|
||||||
{
|
{
|
||||||
_index.strings.indexes = (Index_Entry *)
|
ERR("Could not map strings entries from: '%s'", _index.strings_entries.path);
|
||||||
&(_index.strings.index_header[1]);
|
eina_file_close(_index.strings_entries.f);
|
||||||
_index.strings.entries_file = eina_file_open(
|
_index.strings_entries.f = NULL;
|
||||||
_index.strings.entries_path, EINA_TRUE);
|
_index.strings_entries.data = NULL;
|
||||||
_index.strings.entries_size = eina_file_size_get(
|
}
|
||||||
_index.strings.entries_file);
|
else DBG("Mapped string entries from %s", _index.strings_entries.path);
|
||||||
_index.strings.data = eina_file_map_all(
|
}
|
||||||
_index.strings.entries_file, EINA_FILE_RANDOM);
|
|
||||||
if (!_index.strings.entries_size || !_index.strings.data)
|
if (_index.strings_entries.data &&
|
||||||
goto strings_map_failed;
|
(!_index.strings_index.data && _index.strings_index.path[0]))
|
||||||
DBG("Mapped shared string table with indexes in %s and data in %s",
|
{
|
||||||
_index.strings.index_path, _index.strings.entries_path);
|
_index.strings_index.f = eina_file_open(_index.strings_index.path, EINA_TRUE);
|
||||||
|
sz = eina_file_size_get(_index.strings_index.f);
|
||||||
|
if (sz >= sizeof(Shared_Array_Header))
|
||||||
|
_index.strings_index.data = eina_file_map_all(_index.strings_index.f, EINA_FILE_RANDOM);
|
||||||
|
|
||||||
|
if (_index.strings_index.data)
|
||||||
|
{
|
||||||
|
DBG("Mapped string indexes from %s", _index.strings_index.path);
|
||||||
|
sz = eina_file_size_get(_index.strings_index.f);
|
||||||
|
_index.strings_index.count = (sz - sizeof(Shared_Array_Header)) / sizeof(Index_Entry);
|
||||||
|
if (_index.strings_index.count > _index.strings_index.header->count)
|
||||||
|
{
|
||||||
|
WRN("Detected larger index than advertised: %d > %d",
|
||||||
|
_index.strings_index.count, _index.strings_index.header->count);
|
||||||
|
_index.strings_index.count = _index.strings_index.header->count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strings_map_failed:
|
ERR("Could not map string indexes from %s", _index.strings_index.path);
|
||||||
eina_file_map_free(_index.strings.entries_file,
|
eina_file_close(_index.strings_index.f);
|
||||||
(void *) _index.strings.data);
|
eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
|
||||||
eina_file_close(_index.strings.entries_file);
|
eina_file_close(_index.strings_entries.f);
|
||||||
eina_file_map_free(_index.strings.index_file,
|
_index.strings_index.f = NULL;
|
||||||
(void *) _index.strings.index_header);
|
_index.strings_entries.f = NULL;
|
||||||
eina_file_close(_index.strings.index_file);
|
_index.strings_entries.data = NULL;
|
||||||
memset(&_index.strings, 0, sizeof(_index.strings));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_index.files.path[0])
|
_shared_index_remap_check(&_index.strings_index, sizeof(Index_Entry));
|
||||||
|
if (_index.strings_entries.data)
|
||||||
{
|
{
|
||||||
_index.files.f = eina_file_open(_index.files.path, EINA_TRUE);
|
if (eina_file_refresh(_index.strings_entries.f))
|
||||||
sz = eina_file_size_get(_index.files.f);
|
|
||||||
if (sz < sizeof(Shared_Array_Header))
|
|
||||||
{
|
{
|
||||||
ERR("Shared index for files is too small: %u", sz);
|
eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
|
||||||
eina_file_close(_index.files.f);
|
_index.strings_entries.data = eina_file_map_all(_index.strings_entries.f, EINA_FILE_RANDOM);
|
||||||
_index.files.f = NULL;
|
_index.strings_entries.size = eina_file_size_get(_index.strings_entries.f);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_index.files.header = eina_file_map_all(_index.files.f,
|
|
||||||
EINA_FILE_POPULATE);
|
|
||||||
if (sz < (_index.files.header->count * sizeof(File_Data)
|
|
||||||
+ sizeof(Shared_Array_Header)))
|
|
||||||
{
|
|
||||||
ERR("Shared index size does not match array size: %u / %u",
|
|
||||||
sz, _index.files.header->count);
|
|
||||||
eina_file_map_free(_index.files.f,
|
|
||||||
(void *) _index.files.header);
|
|
||||||
eina_file_close(_index.files.f);
|
|
||||||
_index.files.f = NULL;
|
|
||||||
_index.files.header = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_index.files.entries.fdata =
|
|
||||||
(File_Data *) &(_index.files.header[1]);
|
|
||||||
DBG("Mapped files shared index '%s' at %p: %u entries max",
|
|
||||||
_index.files.path, _index.files.header,
|
|
||||||
_index.files.header->count);
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_index.images.path[0])
|
|
||||||
{
|
|
||||||
_index.images.f = eina_file_open(_index.images.path, EINA_TRUE);
|
|
||||||
sz = eina_file_size_get(_index.images.f);
|
|
||||||
if (sz < sizeof(Shared_Array_Header))
|
|
||||||
{
|
|
||||||
ERR("Shared index for images is too small: %u", sz);
|
|
||||||
eina_file_close(_index.images.f);
|
|
||||||
_index.images.f = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int size = eina_file_size_get(_index.images.f);
|
|
||||||
_index.images.header = eina_file_map_all(_index.images.f,
|
|
||||||
EINA_FILE_POPULATE);
|
|
||||||
if (sz < (_index.images.header->count * sizeof(Image_Data)
|
|
||||||
+ sizeof(Shared_Array_Header)))
|
|
||||||
{
|
|
||||||
ERR("Shared index size does not match array size: %u / %u",
|
|
||||||
sz, _index.images.header->count);
|
|
||||||
eina_file_map_free(_index.images.f,
|
|
||||||
(void *) _index.images.header);
|
|
||||||
eina_file_close(_index.images.f);
|
|
||||||
_index.images.f = NULL;
|
|
||||||
_index.images.header = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_index.images.count = (size - sizeof(Shared_Array_Header))
|
|
||||||
/ sizeof(Image_Data);
|
|
||||||
_index.images.entries.idata =
|
|
||||||
(Image_Data *) &(_index.images.header[1]);
|
|
||||||
DBG("Mapped images shared index '%s' at %p: %u entries max",
|
|
||||||
_index.images.path, _index.images.header,
|
|
||||||
_index.images.header->count);
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_index.fonts.path[0])
|
// 2. File indexes
|
||||||
ERR("Not implemented yet: fonts shared index");
|
|
||||||
|
|
||||||
return ret;
|
eina_strlcpy(_index.files.path, msg->files_index_path, SHARED_BUFFER_PATH_MAX);
|
||||||
}
|
_shared_index_remap_check(&_index.files, sizeof(File_Data));
|
||||||
|
|
||||||
// FIXME: Copy & paste from evas_cserve2_cache.c
|
|
||||||
static int
|
|
||||||
_shm_object_id_cmp_cb(const void *data1, const void *data2)
|
|
||||||
{
|
|
||||||
const Shm_Object *obj;
|
|
||||||
unsigned int key;
|
|
||||||
|
|
||||||
if (data1 == data2) return 0;
|
// 3. Image indexes
|
||||||
if (!data1) return 1;
|
|
||||||
if (!data2) return -1;
|
|
||||||
|
|
||||||
obj = data1;
|
eina_strlcpy(_index.images.path, msg->images_index_path, SHARED_BUFFER_PATH_MAX);
|
||||||
key = *((unsigned int *) data2);
|
_shared_index_remap_check(&_index.images, sizeof(Image_Data));
|
||||||
if (obj->id == key) return 0;
|
|
||||||
if (obj->id < key)
|
|
||||||
return -1;
|
// 4. Font indexes
|
||||||
else
|
// TODO
|
||||||
return +1;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: (almost) copy & paste from evas_cserve2_cache.c
|
// FIXME: (almost) copy & paste from evas_cserve2_cache.c
|
||||||
static const char *
|
static const char *
|
||||||
_shared_string_get(int id)
|
_shared_string_get(int id)
|
||||||
{
|
{
|
||||||
const char *ret;
|
Index_Entry *ie;
|
||||||
const Index_Entry *ie = NULL;
|
|
||||||
int k;
|
|
||||||
|
|
||||||
if (id <= 0) return NULL;
|
ie = (Index_Entry *)
|
||||||
if (!_index.strings.data) return NULL;
|
_shared_index_item_get_by_id(&_index.strings_index, sizeof(*ie), id);
|
||||||
|
|
||||||
// Binary search
|
|
||||||
if (_index.strings.index_header->sortedidx > 0)
|
|
||||||
{
|
|
||||||
int low = 0;
|
|
||||||
int high = _index.strings.index_header->sortedidx;
|
|
||||||
int prev = -1;
|
|
||||||
int r;
|
|
||||||
k = high / 2;
|
|
||||||
while (prev != k)
|
|
||||||
{
|
|
||||||
ie = &(_index.strings.indexes[k]);
|
|
||||||
r = _shm_object_id_cmp_cb(ie, &id);
|
|
||||||
if (!r)
|
|
||||||
goto found;
|
|
||||||
else if (r > 0)
|
|
||||||
high = k;
|
|
||||||
else
|
|
||||||
low = k;
|
|
||||||
prev = k;
|
|
||||||
k = low + (high - low) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linear search O(n)
|
|
||||||
k = _index.strings.index_header->sortedidx;
|
|
||||||
for (; k < _index.strings.index_header->emptyidx; k++)
|
|
||||||
{
|
|
||||||
ie = &(_index.strings.indexes[k]);
|
|
||||||
if (!_shm_object_id_cmp_cb(ie, &id))
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
found:
|
|
||||||
if (!ie) return NULL;
|
if (!ie) return NULL;
|
||||||
|
if (ie->offset < 0) return NULL;
|
||||||
if (!ie->refcount) return NULL;
|
if (!ie->refcount) return NULL;
|
||||||
if (ie->length + ie->offset > (int) _index.strings.entries_size)
|
if (ie->offset + ie->length > _index.strings_entries.size) return NULL;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = _index.strings.data + ie->offset;
|
return _index.strings_entries.data + ie->offset;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Eina_Bool
|
#define SHARED_INDEX_CHECK(si, typ) \
|
||||||
_shared_image_entry_file_data_match(Image_Entry *ie, const File_Data *fd)
|
do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \
|
||||||
|
CRIT("Failed to remap index"); return NULL; } } while (0)
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_shared_file_data_hkey_get(char *hkey, const char *file, const char *key,
|
||||||
|
size_t hkey_size)
|
||||||
{
|
{
|
||||||
const char *path, *key, *loader;
|
size_t keylen, filelen;
|
||||||
|
|
||||||
if (!fd || !ie) return EINA_FALSE;
|
if (key) keylen = strlen(key) + 1;
|
||||||
if (!ie->file && !ie->key)
|
filelen = strlen(file);
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
path = _shared_string_get(fd->path);
|
if (filelen + keylen + 1 > hkey_size)
|
||||||
key = _shared_string_get(fd->key);
|
return NULL;
|
||||||
loader = _shared_string_get(fd->loader_data);
|
|
||||||
|
|
||||||
if (!path && ie->file)
|
memcpy(hkey, file, filelen);
|
||||||
return EINA_FALSE;
|
hkey[filelen] = ':';
|
||||||
if (ie->file && strcmp(path, ie->file))
|
if (key)
|
||||||
return EINA_FALSE;
|
memcpy(hkey + filelen + 1, key, keylen);
|
||||||
|
else
|
||||||
|
memcpy(hkey + filelen + 1, "(null)", 7);
|
||||||
|
|
||||||
if (!key && ie->key)
|
return hkey;
|
||||||
return EINA_FALSE;
|
|
||||||
if (ie->key && strcmp(key, ie->key))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (!loader && ie->loader_data)
|
|
||||||
return EINA_FALSE;
|
|
||||||
if (strcmp(loader, ie->loader_data))
|
|
||||||
return EINA_FALSE;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Check w,h ?
|
|
||||||
// Not sure which load opts should be checked here
|
|
||||||
DBG("Found a match for %s:%s", ie->file, ie->key);
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const File_Data *
|
static const File_Data *
|
||||||
|
@ -1904,32 +1809,122 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
|
||||||
{
|
{
|
||||||
const File_Data *fdata = NULL;
|
const File_Data *fdata = NULL;
|
||||||
File_Entry *fe;
|
File_Entry *fe;
|
||||||
|
Eina_Bool add_to_hash = SHARED_INDEX_ADD_TO_HASH;
|
||||||
|
char hkey[PATH_MAX];
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
DBG("Trying to find if image '%s:%s' is already opened by cserve2",
|
DBG("Trying to find if image '%s:%s' is already opened by cserve2",
|
||||||
ie->file, ie->key);
|
ie->file, ie->key);
|
||||||
|
|
||||||
if (!_index.files.entries.fdata)
|
SHARED_INDEX_CHECK(_index.files, File_Data);
|
||||||
|
|
||||||
|
if (!_index.strings_index.header || !_index.strings_entries.data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#warning FIXME Use safe count
|
if (!_index.files.header || !_index.files.entries.fdata)
|
||||||
for (k = 0; k < _index.files.header->count; k++)
|
return NULL;
|
||||||
{
|
|
||||||
const File_Data *fd = &(_index.files.entries.fdata[k]);
|
|
||||||
if (!fd->id) return NULL;
|
|
||||||
if (!fd->refcount) continue;
|
|
||||||
|
|
||||||
if (_shared_image_entry_file_data_match(ie, fd))
|
// Direct access
|
||||||
{
|
fe = ie->data1;
|
||||||
fdata = fd;
|
if (fe->server_file_id)
|
||||||
break;
|
{
|
||||||
}
|
if ((fdata = _shared_file_data_get_by_id(fe->server_file_id)) != NULL)
|
||||||
|
return fdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("Found file data for %s:%s: %d", ie->file, ie->key, fdata->id);
|
// Check hash
|
||||||
fe = ie->data1;
|
_shared_file_data_hkey_get(hkey, ie->file, ie->key, PATH_MAX);
|
||||||
fe->server_file_id = fdata->id;
|
fdata = eina_hash_find(_index.files.entries_by_hkey, hkey);
|
||||||
return fdata;
|
if (fdata)
|
||||||
|
return fdata;
|
||||||
|
|
||||||
|
// Scan shared index
|
||||||
|
for (k = _index.files.last_entry_in_hash;
|
||||||
|
k < _index.files.count && k < _index.files.header->emptyidx; k++)
|
||||||
|
{
|
||||||
|
const char *file, *key;
|
||||||
|
const File_Data *fd;
|
||||||
|
char fd_hkey[PATH_MAX];
|
||||||
|
|
||||||
|
fd = &(_index.files.entries.fdata[k]);
|
||||||
|
if (!fd->id) break;
|
||||||
|
if (!fd->refcount) continue;
|
||||||
|
|
||||||
|
file = _shared_string_get(fd->path);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
ERR("Could not find filename for file %d", fd->id);
|
||||||
|
add_to_hash = EINA_FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
key = _shared_string_get(fd->key);
|
||||||
|
|
||||||
|
_shared_file_data_hkey_get(fd_hkey, file, key, PATH_MAX);
|
||||||
|
|
||||||
|
if (add_to_hash)
|
||||||
|
{
|
||||||
|
eina_hash_add(_index.files.entries_by_hkey, fd_hkey, fd);
|
||||||
|
_index.files.last_entry_in_hash = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(hkey, fd_hkey))
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Shm_Object *
|
||||||
|
_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id)
|
||||||
|
{
|
||||||
|
const Shm_Object *obj;
|
||||||
|
const char *base;
|
||||||
|
int low = 0, high, start_high;
|
||||||
|
int cur;
|
||||||
|
|
||||||
|
if (!si || elemsize <= 0 || !id)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// FIXME: HACK (consider all arrays always sorted by id)
|
||||||
|
high = si->header->emptyidx; // Should be si->header->sortedidx
|
||||||
|
|
||||||
|
if (high > si->count)
|
||||||
|
high = si->count;
|
||||||
|
|
||||||
|
base = si->data + sizeof(Shared_Array_Header);
|
||||||
|
|
||||||
|
// Binary search
|
||||||
|
start_high = high;
|
||||||
|
while(high != low)
|
||||||
|
{
|
||||||
|
cur = low + ((high - low) / 2);
|
||||||
|
obj = (Shm_Object *) (base + (elemsize * cur));
|
||||||
|
if (obj->id == id)
|
||||||
|
return obj;
|
||||||
|
if (obj->id < id)
|
||||||
|
low = cur + 1;
|
||||||
|
else
|
||||||
|
high = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Linear search
|
||||||
|
for (cur = start_high; cur < si->count; cur++)
|
||||||
|
{
|
||||||
|
obj = (Shm_Object *) (base + (elemsize * cur));
|
||||||
|
if (!obj->id)
|
||||||
|
return NULL;
|
||||||
|
if (obj->id == id)
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const File_Data *
|
||||||
|
_shared_file_data_get_by_id(unsigned int id)
|
||||||
|
{
|
||||||
|
return (const File_Data *)
|
||||||
|
_shared_index_item_get_by_id(&_index.files, sizeof(File_Data), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Eina_Bool
|
static inline Eina_Bool
|
||||||
|
@ -1945,9 +1940,6 @@ _shared_image_entry_image_data_match(Image_Entry *ie, const Image_Data *id)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHARED_INDEX_CHECK(si, typ) \
|
|
||||||
if (!_shared_index_remap_check(&(si), sizeof(typ))) return NULL
|
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_shared_index_remap_check(Shared_Index *si, int elemsize)
|
_shared_index_remap_check(Shared_Index *si, int elemsize)
|
||||||
{
|
{
|
||||||
|
@ -1957,22 +1949,39 @@ _shared_index_remap_check(Shared_Index *si, int elemsize)
|
||||||
// Note: all checks are unlikely to be true.
|
// Note: all checks are unlikely to be true.
|
||||||
|
|
||||||
if (!si || elemsize <= 0) return EINA_FALSE;
|
if (!si || elemsize <= 0) return EINA_FALSE;
|
||||||
|
|
||||||
if (si->generation_id != _index.generation_id)
|
if (si->generation_id != _index.generation_id)
|
||||||
{
|
{
|
||||||
DBG("Generation ID changed.");
|
DBG("Generation ID changed from %d to %d.",
|
||||||
if (si->f && si->data)
|
si->generation_id, _index.generation_id);
|
||||||
|
if (si->f)
|
||||||
{
|
{
|
||||||
if (eina_file_refresh(si->f))
|
if (strncmp(si->path, eina_file_filename_get(si->f),
|
||||||
|
SHARED_BUFFER_PATH_MAX) != 0)
|
||||||
{
|
{
|
||||||
DBG("Remapping index.");
|
DBG("Index file changed. Closing and reopening.");
|
||||||
eina_file_map_free(si->f, si->data);
|
eina_file_map_free(si->f, si->data);
|
||||||
|
eina_file_close(si->f);
|
||||||
|
si->f = NULL;
|
||||||
si->data = NULL;
|
si->data = NULL;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if (si->f)
|
{
|
||||||
{
|
if (si->data)
|
||||||
eina_file_close(si->f);
|
{
|
||||||
si->f = NULL;
|
if (eina_file_refresh(si->f))
|
||||||
|
{
|
||||||
|
DBG("Remapping index.");
|
||||||
|
eina_file_map_free(si->f, si->data);
|
||||||
|
si->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eina_file_close(si->f);
|
||||||
|
si->f = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
si->generation_id = _index.generation_id;
|
si->generation_id = _index.generation_id;
|
||||||
}
|
}
|
||||||
|
@ -2039,6 +2048,7 @@ _shared_index_remap_check(Shared_Index *si, int elemsize)
|
||||||
if (si->entries_by_hkey) eina_hash_free_buckets(si->entries_by_hkey);
|
if (si->entries_by_hkey) eina_hash_free_buckets(si->entries_by_hkey);
|
||||||
else si->entries_by_hkey = eina_hash_string_small_new(NULL);
|
else si->entries_by_hkey = eina_hash_string_small_new(NULL);
|
||||||
si->last_entry_in_hash = 0;
|
si->last_entry_in_hash = 0;
|
||||||
|
si->entries.p = si->data + sizeof(Shared_Array_Header);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -2048,16 +2058,28 @@ static const Image_Data *
|
||||||
_shared_image_entry_image_data_find(Image_Entry *ie)
|
_shared_image_entry_image_data_find(Image_Entry *ie)
|
||||||
{
|
{
|
||||||
const Image_Data *idata = NULL;
|
const Image_Data *idata = NULL;
|
||||||
|
const char *shmpath;
|
||||||
File_Entry *fe;
|
File_Entry *fe;
|
||||||
unsigned int file_id = 0;
|
unsigned int file_id = 0;
|
||||||
|
Eina_Bool add_to_hash = SHARED_INDEX_ADD_TO_HASH;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
|
||||||
DBG("Trying to find if image '%s:%s' is already loaded by cserve2",
|
DBG("Trying to find if image '%s:%s' is already loaded by cserve2",
|
||||||
ie->file, ie->key);
|
ie->file, ie->key);
|
||||||
|
|
||||||
|
if (!_index.strings_entries.data || !_index.strings_index.data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!_index.images.entries.idata || !_index.images.count)
|
if (!_index.images.entries.idata || !_index.images.count)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!ie->cache_key)
|
||||||
|
{
|
||||||
|
CRIT("Looking for an image in remote cache without hash key?");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
fe = ie->data1;
|
fe = ie->data1;
|
||||||
if (fe && fe->server_file_id)
|
if (fe && fe->server_file_id)
|
||||||
file_id = fe->server_file_id;
|
file_id = fe->server_file_id;
|
||||||
|
@ -2074,32 +2096,79 @@ _shared_image_entry_image_data_find(Image_Entry *ie)
|
||||||
|
|
||||||
SHARED_INDEX_CHECK(_index.images, Image_Data);
|
SHARED_INDEX_CHECK(_index.images, Image_Data);
|
||||||
|
|
||||||
DBG("Looking for loaded image with file id %d", file_id);
|
// Find in known entries hash. O(log n)
|
||||||
for (k = 0; k < _index.images.count; k++)
|
DBG("Looking for %s in hash", ie->cache_key);
|
||||||
|
idata = (const Image_Data *)
|
||||||
|
eina_hash_find(_index.images.entries_by_hkey, ie->cache_key);
|
||||||
|
if (idata)
|
||||||
{
|
{
|
||||||
|
ERR("Image found in shared index (by cache_key).");
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Linear search in non-hashed entries. O(n)
|
||||||
|
DBG("Looking for loaded image with file id %d", file_id);
|
||||||
|
for (k = _index.images.last_entry_in_hash; k < _index.images.count; k++)
|
||||||
|
{
|
||||||
|
const char *file, *key;
|
||||||
|
size_t keylen, filelen;
|
||||||
|
const File_Data *fd;
|
||||||
|
char *hkey;
|
||||||
const Image_Data *id = &(_index.images.entries.idata[k]);
|
const Image_Data *id = &(_index.images.entries.idata[k]);
|
||||||
|
|
||||||
if (!id->id) return NULL;
|
if (!id->id) return NULL;
|
||||||
if (!id->refcount) continue;
|
if (!id->refcount) continue;
|
||||||
|
|
||||||
|
if (add_to_hash)
|
||||||
|
{
|
||||||
|
fd = _shared_file_data_get_by_id(id->file_id);
|
||||||
|
if (!fd)
|
||||||
|
{
|
||||||
|
ERR("Did not find file data for %d", id->file_id);
|
||||||
|
add_to_hash = EINA_FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = _shared_string_get(fd->key);
|
||||||
|
file = _shared_string_get(fd->path);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
ERR("No filename for file %d", fd->id);
|
||||||
|
add_to_hash = EINA_FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
keylen = key ? strlen(key) : 0;
|
||||||
|
filelen = strlen(file);
|
||||||
|
|
||||||
|
hkey = alloca(filelen + keylen + HKEY_LOAD_OPTS_STR_LEN);
|
||||||
|
evas_cache2_image_cache_key_create(hkey, file, filelen,
|
||||||
|
key, keylen, &id->opts);
|
||||||
|
eina_hash_add(_index.images.entries_by_hkey, hkey, id);
|
||||||
|
_index.images.last_entry_in_hash = k;
|
||||||
|
}
|
||||||
|
|
||||||
if (id->file_id != file_id) continue;
|
if (id->file_id != file_id) continue;
|
||||||
|
|
||||||
if (_shared_image_entry_image_data_match(ie, id))
|
if (_shared_image_entry_image_data_match(ie, id))
|
||||||
{
|
{
|
||||||
idata = id;
|
idata = id;
|
||||||
break;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!idata)
|
if (!idata)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!_shared_string_get(idata->shm_id))
|
found:
|
||||||
|
shmpath = _shared_string_get(idata->shm_id);
|
||||||
|
if (!shmpath)
|
||||||
{
|
{
|
||||||
ERR("Found image but it is not loaded yet: %d (doload %d shm %s)",
|
ERR("Found image but it is not loaded yet: %d (doload %d)",
|
||||||
idata->id, idata->doload, _shared_string_get(idata->shm_id));
|
idata->id, idata->doload);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("Found image, loaded, in shm %s", _shared_string_get(idata->shm_id));
|
DBG("Found image, loaded, in shm %s", shmpath);
|
||||||
return idata;
|
return idata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,15 @@
|
||||||
#include "evas_common_private.h"
|
#include "evas_common_private.h"
|
||||||
#include "evas_cs2.h"
|
#include "evas_cs2.h"
|
||||||
|
|
||||||
|
#define SHARED_BUFFER_PATH_MAX 64
|
||||||
typedef struct _Data_Entry Data_Entry;
|
typedef struct _Data_Entry Data_Entry;
|
||||||
typedef struct _Font_Entry Font_Entry;
|
typedef struct _Font_Entry Font_Entry;
|
||||||
typedef struct _Index_Table Index_Table;
|
typedef struct _Index_Table Index_Table;
|
||||||
typedef struct _Shared_Index Shared_Index;
|
typedef struct _Shared_Index Shared_Index;
|
||||||
|
typedef struct _Shared_Buffer Shared_Buffer;
|
||||||
|
|
||||||
struct _Data_Entry {
|
struct _Data_Entry
|
||||||
|
{
|
||||||
unsigned int image_id;
|
unsigned int image_id;
|
||||||
void (*preloaded_cb)(void *, Eina_Bool);
|
void (*preloaded_cb)(void *, Eina_Bool);
|
||||||
struct {
|
struct {
|
||||||
|
@ -23,14 +26,15 @@ struct _Data_Entry {
|
||||||
} shm;
|
} shm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Shared_Index {
|
struct _Shared_Index
|
||||||
char path[64];
|
{
|
||||||
|
char path[SHARED_BUFFER_PATH_MAX];
|
||||||
int generation_id;
|
int generation_id;
|
||||||
Eina_File *f;
|
Eina_File *f;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
const Shared_Array_Header *header;
|
const Shared_Array_Header *header;
|
||||||
void *data;
|
char *data;
|
||||||
};
|
};
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -45,19 +49,19 @@ struct _Shared_Index {
|
||||||
int last_entry_in_hash;
|
int last_entry_in_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Index_Table {
|
struct _Shared_Buffer
|
||||||
|
{
|
||||||
|
char path[SHARED_BUFFER_PATH_MAX];
|
||||||
|
Eina_File *f;
|
||||||
|
char *data;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Index_Table
|
||||||
|
{
|
||||||
int generation_id;
|
int generation_id;
|
||||||
// TODO: use Shared_Index
|
Shared_Buffer strings_entries;
|
||||||
struct {
|
Shared_Index strings_index;
|
||||||
char index_path[64];
|
|
||||||
char entries_path[64];
|
|
||||||
Eina_File *index_file;
|
|
||||||
Eina_File *entries_file;
|
|
||||||
const Shared_Array_Header *index_header;
|
|
||||||
const Index_Entry *indexes;
|
|
||||||
const char *data;
|
|
||||||
size_t entries_size;
|
|
||||||
} strings;
|
|
||||||
Shared_Index files;
|
Shared_Index files;
|
||||||
Shared_Index images;
|
Shared_Index images;
|
||||||
Shared_Index fonts; // TODO
|
Shared_Index fonts; // TODO
|
||||||
|
|
Loading…
Reference in New Issue