From acae35b4d1cb2a8aa602cc9c1e6de468997de059 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 22 Jul 2013 16:28:42 +0900 Subject: [PATCH] evas/cserve2: Use Shared_Array storage for File_Data File_Entry and File_Data are now two different types, one being stored in the shared array, the other one is only a reference counting entry. --- src/bin/evas/evas_cserve2_cache.c | 457 ++++++++++++++++++++---------- src/bin/evas/evas_cserve2_index.c | 5 +- 2 files changed, 310 insertions(+), 152 deletions(-) diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c index 607520031b..d3926e2a10 100644 --- a/src/bin/evas/evas_cserve2_cache.c +++ b/src/bin/evas/evas_cserve2_cache.c @@ -14,20 +14,15 @@ #include -// For testing purposes only. -#define EXPERIMENTAL_SHARED_INDEX 0 -#if EXPERIMENTAL_SHARED_INDEX typedef int string_t; -#else -#define cserve2_shared_string_get(str) (str) -#define cserve2_shared_string_del(str) (eina_stringshare_del(str)) -#define cserve2_shared_string_add(str) (eina_stringshare_add(str)) -#define cserve2_shared_string_ref(str) (eina_stringshare_ref(str)) -typedef Eina_Stringshare* string_t; -#endif +#define ENTRY Entry base +#define ASENTRY(a) (&(a->base)) +#define SHMOBJECT unsigned int id; unsigned int refcount typedef struct _Entry Entry; +typedef struct _Shm_Object Shm_Object; typedef struct _Reference Reference; +typedef struct _File_Entry File_Entry; typedef struct _File_Data File_Data; typedef struct _Image_Data Image_Data; typedef struct _File_Watch File_Watch; @@ -55,8 +50,19 @@ struct _Entry { #endif }; +struct _Shm_Object +{ + SHMOBJECT; +}; + +struct _File_Entry { + ENTRY; + File_Watch *watcher; + Eina_List *images; +}; + struct _File_Data { - Entry base; + SHMOBJECT; string_t path; string_t key; string_t loader_data; @@ -64,8 +70,6 @@ struct _File_Data { int frame_count; int loop_count; int loop_hint; - File_Watch *watcher; - Eina_List *images; Eina_Bool alpha : 1; Eina_Bool invalid : 1; }; @@ -74,7 +78,6 @@ struct _File_Data { struct _Image_Data { Entry base; unsigned int file_id; - File_Data *file; Evas_Image_Load_Opts opts; Shm_Handle *shm; Eina_Bool alpha_sparse : 1; @@ -172,6 +175,8 @@ struct _File_Watch { }; static unsigned int _entry_id = 0; +static Shared_Array *_file_data_array = NULL; + static Eina_Hash *file_ids = NULL; // maps path + key --> file_id static Eina_Hash *file_entries = NULL; // maps file_id --> entry @@ -235,6 +240,54 @@ _entry_load_reused(Entry *e) #endif } + +static int +_shm_object_id_find_cb(const void *data1, const void *data2) +{ + const Shm_Object *obj; + unsigned int key; + + if (data1 == data2) return 0; + if (!data1) return 1; + if (!data2) return -1; + + obj = data1; + key = *((unsigned int *) data2); + if (obj->id == key) return 0; + if (obj->id < key) + return -1; + else + return +1; +} + +static inline File_Data * +_file_data_find(unsigned int file_id) +{ + File_Data *fd; + + fd = cserve2_shared_array_item_data_find(_file_data_array, &file_id, + _shm_object_id_find_cb); + if (fd && !fd->refcount) + { + ERR("Can not access object %u with refcount 0", file_id); + return NULL; + } + return fd; +} + +static inline File_Entry * +_file_entry_find(unsigned int entry_id) +{ + Entry *e; + + e = (Entry *) eina_hash_find(file_entries, &entry_id); + if (!e || e->type != CSERVE2_IMAGE_FILE) + return NULL; + + return (File_Entry *) e; +} + + static Msg_Opened * _image_opened_msg_create(File_Data *fd, int *size) { @@ -260,7 +313,7 @@ _image_opened_send(Client *client, File_Data *fd, unsigned int rid) int size; Msg_Opened *msg; - DBG("Sending OPENED reply for entry: %d and RID: %d.", fd->base.id, rid); + DBG("Sending OPENED reply for entry: %d and RID: %d.", fd->id, rid); // clear the struct with possible paddings, since it is not aligned. msg = _image_opened_msg_create(fd, &size); @@ -334,12 +387,20 @@ _font_loaded_send(Client *client, unsigned int rid) } static void * -_open_request_build(File_Data *fd, int *bufsize) +_open_request_build(Entry *entry, int *bufsize) { const char *loader_data; char *buf; int size, pathlen, keylen, loaderlen; Slave_Msg_Image_Open msg; + File_Data *fd; + + fd = _file_data_find(entry->id); + if (!fd) + { + ERR("Could not find file data for entry %u", entry->id); + return NULL; + } pathlen = strlen(cserve2_shared_string_get(fd->path)) + 1; keylen = strlen(cserve2_shared_string_get(fd->key)) + 1; @@ -361,7 +422,7 @@ _open_request_build(File_Data *fd, int *bufsize) *bufsize = size; - _entry_load_start(&fd->base); + _entry_load_start(entry); return buf; } @@ -373,11 +434,19 @@ _request_free(void *msg, void *data EINA_UNUSED) } static Msg_Opened * -_open_request_response(File_Data *fd, Slave_Msg_Image_Opened *resp, int *size) +_open_request_response(Entry *entry, Slave_Msg_Image_Opened *resp, int *size) { - _entry_load_finish(&fd->base); + File_Data *fd; - fd->base.request = NULL; + _entry_load_finish(entry); + entry->request = NULL; + + fd = _file_data_find(entry->id); + if (!fd) + { + ERR("Could not find file data for entry %u", entry->id); + return NULL; + } fd->w = resp->w; fd->h = resp->h; @@ -436,18 +505,26 @@ _load_request_build(Image_Data *i, int *bufsize) int size; int shmlen, filelen, keylen, loaderlen; Slave_Msg_Image_Load msg; + File_Data *fd; + + fd = _file_data_find(i->file_id); + if (!fd) + { + ERR("Could not find file data %u for image %u", i->file_id, i->base.id); + return NULL; + } // opening shm for this file - i->shm = cserve2_shm_request("img", i->file->w * i->file->h * 4); + i->shm = cserve2_shm_request("img", fd->w * fd->h * 4); if (!i->shm) return NULL; shmpath = cserve2_shm_name_get(i->shm); shmlen = strlen(shmpath) + 1; - filelen = strlen(cserve2_shared_string_get(i->file->path)) + 1; - keylen = strlen(cserve2_shared_string_get(i->file->key)) + 1; - loader_data = cserve2_shared_string_get(i->file->loader_data); + filelen = strlen(cserve2_shared_string_get(fd->path)) + 1; + keylen = strlen(cserve2_shared_string_get(fd->key)) + 1; + loader_data = cserve2_shared_string_get(fd->loader_data); if (loader_data) loaderlen = strlen(loader_data) + 1; else @@ -458,9 +535,9 @@ _load_request_build(Image_Data *i, int *bufsize) if (!buf) return NULL; memset(&msg, 0, sizeof(msg)); - msg.w = i->file->w; - msg.h = i->file->h; - msg.alpha = i->file->alpha; + msg.w = fd->w; + msg.h = fd->h; + msg.alpha = fd->alpha; // NOTE: Not passing scale_load options msg.opts.w = i->opts.w; @@ -483,11 +560,11 @@ _load_request_build(Image_Data *i, int *bufsize) memcpy(ptr, shmpath, shmlen); ptr += shmlen; - memcpy(ptr, cserve2_shared_string_get(i->file->path), filelen); + memcpy(ptr, cserve2_shared_string_get(fd->path), filelen); ptr += filelen; - memcpy(ptr, cserve2_shared_string_get(i->file->key), keylen); + memcpy(ptr, cserve2_shared_string_get(fd->key), keylen); ptr += keylen; - if (loaderlen > 0) memcpy(ptr, cserve2_shared_string_get(i->file->loader_data), loaderlen); + if (loaderlen > 0) memcpy(ptr, cserve2_shared_string_get(fd->loader_data), loaderlen); *bufsize = size; @@ -509,6 +586,15 @@ _scaling_do(Shm_Handle *scale_shm, Image_Data *entry, Image_Data *original) { char *scale_map, *orig_map; void *src_data, *dst_data; + File_Data *fd; + + fd = _file_data_find(entry->file_id); + if (!fd) + { + ERR("Could not find file data %u for image %u", + entry->file_id, entry->base.id); + return -1; + } scale_map = cserve2_shm_map(scale_shm); if (scale_map == MAP_FAILED) @@ -540,7 +626,7 @@ _scaling_do(Shm_Handle *scale_shm, Image_Data *entry, Image_Data *original) entry->opts.scale_load.src_w, entry->opts.scale_load.src_h, 0, 0, entry->opts.scale_load.dst_w, entry->opts.scale_load.dst_h, - entry->file->alpha, entry->opts.scale_load.smooth); + fd->alpha, entry->opts.scale_load.smooth); cserve2_shm_unmap(original->shm); cserve2_shm_unmap(scale_shm); @@ -572,9 +658,6 @@ _scaling_prepare_and_do(Image_Data *orig) static Msg_Loaded * _load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size) { - const char *path = cserve2_shared_string_get(e->file->path); - const char *key = cserve2_shared_string_get(e->file->key); - _entry_load_finish(&e->base); e->base.request = NULL; @@ -586,17 +669,15 @@ _load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size) if (_scaling_needed(e, resp)) { - DBG("About to scale down image '%s%s'", path, key); + DBG("About to scale down image %u", ASENTRY(e)->id); if (!_scaling_prepare_and_do(e)) - DBG("Image '%s:%s' has been scaled down.", - path, key); + DBG("Image %u has been scaled down.", ASENTRY(e)->id); else - ERR("Failed to scale down image '%s%s'", - path, key); + ERR("Failed to scale down image %u", ASENTRY(e)->id); } else - DBG("No scaling needed for image '%s%s'", path, key); + DBG("No scaling needed for image %u", ASENTRY(e)->id); return _image_loaded_msg_create(e, size); } @@ -652,9 +733,11 @@ _file_id_free(File_Data *fd) char buf[4096]; DBG("Removing entry file id: %d, file: \"%s:%s\"", - fd->base.id, cserve2_shared_string_get(fd->path), cserve2_shared_string_get(fd->key)); + fd->id, cserve2_shared_string_get(fd->path), + cserve2_shared_string_get(fd->key)); snprintf(buf, sizeof(buf), "%s:%s", - cserve2_shared_string_get(fd->path), cserve2_shared_string_get(fd->key)); + cserve2_shared_string_get(fd->path), + cserve2_shared_string_get(fd->key)); eina_hash_del_by_key(file_ids, buf); } @@ -672,7 +755,8 @@ _image_id_free(Image_Data *entry) static void _image_entry_free(Image_Data *entry) { - File_Data *fd = entry->file; + File_Data *fd; + File_Entry *fentry; if (entry->base.request) cserve2_request_cancel_all(entry->base.request, CSERVE2_REQUEST_CANCEL); @@ -683,12 +767,17 @@ _image_entry_free(Image_Data *entry) unused_mem_usage -= _image_entry_size_get(entry); } + fd = _file_data_find(entry->file_id); if (fd) { - fd->images = eina_list_remove(fd->images, entry); - if (!fd->images && !fd->base.references) - eina_hash_del_by_key(file_entries, &fd->base.id); + fentry = _file_entry_find(fd->id); + fentry->images = eina_list_remove(fentry->images, entry); + if (fentry && !fentry->images && !ASENTRY(fentry)->references) + eina_hash_del_by_key(file_entries, &fd->id); } + else + ERR("Could not find file data %u for image %u", + entry->file_id, ASENTRY(entry)->id); if (entry->shm) cserve2_shm_unref(entry->shm); free(entry); @@ -704,44 +793,60 @@ _hash_image_entry_free(void *data) } static void -_file_entry_free(File_Data *fd) +_file_entry_free(File_Entry *fentry) { File_Watch *fw; + if (!fentry) return; + // Should we call free for each of the images too? // If everything goes fine, it's not necessary. - if (fd->images) + + if (fentry->images) { - ERR("Freeing file %d (\"%s:%s\") image data still referenced.", - fd->base.id, cserve2_shared_string_get(fd->path), cserve2_shared_string_get(fd->key)); - eina_list_free(fd->images); + ERR("Freeing file %u image data still referenced.", ASENTRY(fentry)->id); + eina_list_free(fentry->images); } + if (ASENTRY(fentry)->request) + cserve2_request_cancel_all(ASENTRY(fentry)->request, + CSERVE2_REQUEST_CANCEL); - if (fd->base.request) - cserve2_request_cancel_all(fd->base.request, CSERVE2_REQUEST_CANCEL); - - if ((fw = fd->watcher)) + if ((fw = fentry->watcher)) { - fw->entries = eina_list_remove(fw->entries, fd); + fw->entries = eina_list_remove(fw->entries, fentry); if (!fw->entries) eina_hash_del_by_key(file_watch, fw->path); } - cserve2_shared_string_del(fd->key); - cserve2_shared_string_del(fd->path); - cserve2_shared_string_del(fd->loader_data); - free(fd); + free(fentry); +} + +static void +_file_data_free(File_Data *fd) +{ + if (!fd) return; + if (!fd->refcount) return; + if (--fd->refcount == 0) + { + cserve2_shared_string_del(fd->key); + cserve2_shared_string_del(fd->path); + cserve2_shared_string_del(fd->loader_data); + memset((char *) fd + sizeof(fd->id), 0, sizeof(*fd) - sizeof(fd->id)); + } } static void _hash_file_entry_free(void *data) { - File_Data *fd = data; + File_Entry *fentry = data; + File_Data *fd; // TODO: Add some checks to make sure that we are freeing an // unused entry. + fd = _file_data_find(ASENTRY(fentry)->id); _file_id_free(fd); - _file_entry_free(fd); + _file_entry_free(fentry); + _file_data_free(fd); } static void @@ -904,6 +1009,8 @@ cserve2_cache_init(void) EINA_KEY_HASH(_font_entry_key_hash), EINA_FREE_CB(_font_entry_free), 5); + + _file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0); } void @@ -922,6 +1029,8 @@ cserve2_cache_shutdown(void) eina_hash_free(font_entries); eina_hash_free(font_sources); + + cserve2_shared_array_del(_file_data_array); } static Reference * @@ -983,22 +1092,32 @@ _entry_reference_del(Entry *entry, Reference *ref) if (entry->type == CSERVE2_IMAGE_FILE) { - File_Data *fd = (File_Data *)entry; + File_Entry *fentry = (File_Entry *) entry; + File_Data *fd = _file_data_find(entry->id); - if (fd->invalid) - _file_entry_free(fd); - else if (!fd->images) - eina_hash_del_by_key(file_entries, &entry->id); + if (fd) + { + if (fd->invalid) + { + _file_entry_free(fentry); + _file_data_free(fd); + } + else if (!fentry->images) + eina_hash_del_by_key(file_entries, &entry->id); + } + else + ERR("File data not found for id %u", entry->id); /* don't free file entries that have images attached to it, they will * be freed when the last unused image is freed */ } else if (entry->type == CSERVE2_IMAGE_DATA) { - Image_Data *ientry = (Image_Data *)entry; + Image_Data *ientry = (Image_Data *) entry; + File_Data *fd = _file_data_find(entry->id); - if (!ientry->file) + if (!fd) eina_hash_del_by_key(image_entries, &entry->id); - else if (ientry->file->invalid) + else if (fd->invalid) _image_entry_free(ientry); else _entry_unused_push(ientry); @@ -1090,22 +1209,24 @@ cserve2_cache_client_del(Client *client) static Image_Data * _image_entry_new(Client *client, int rid, - unsigned int file_id, unsigned int image_id, + unsigned int client_file_id, unsigned int image_id, Evas_Image_Load_Opts *opts) { Reference *ref; Image_Data *im_entry; + File_Data *fd; - ref = eina_hash_find(client->files.referencing, &file_id); + ref = eina_hash_find(client->files.referencing, &client_file_id); if (!ref) { ERR("Couldn't find file id: %d, for image id: %d", - file_id, image_id); + client_file_id, image_id); cserve2_client_error_send(client, rid, CSERVE2_INVALID_CACHE); return NULL; } - if (((File_Data *)ref->entry)->invalid) + fd = _file_data_find(ref->entry->id); + if (!fd || fd->invalid) { cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED); @@ -1115,7 +1236,6 @@ _image_entry_new(Client *client, int rid, im_entry = calloc(1, sizeof(*im_entry)); im_entry->base.type = CSERVE2_IMAGE_DATA; im_entry->file_id = ref->entry->id; - im_entry->file = (File_Data *)ref->entry; if (opts) { im_entry->opts.dpi = opts->dpi; @@ -1152,11 +1272,19 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo { Eina_List *ll; Image_Data *ie; + File_Entry *fentry; fd->invalid = EINA_TRUE; - fd->watcher = NULL; + fentry = _file_entry_find(fd->id); + if (!fentry) + { + ERR("Could not find file entry for id %u", fd->id); + continue; + } - EINA_LIST_FOREACH(fd->images, ll, ie) + fentry->watcher = NULL; + + EINA_LIST_FOREACH(fentry->images, ll, ie) { _image_id_free(ie); eina_hash_set(image_entries, &ie->base.id, NULL); @@ -1169,12 +1297,19 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo } _file_id_free(fd); - eina_hash_set(file_entries, &fd->base.id, NULL); - if (fd->base.request /*&& !fd->base.request->processing*/) - cserve2_request_cancel_all(fd->base.request, CSERVE2_FILE_CHANGED); - fd->base.request = NULL; - if (!fd->images && !fd->base.references) - _file_entry_free(fd); + eina_hash_set(file_entries, &fd->id, NULL); + if (ASENTRY(fentry)->request + /*&& !ASENTRY(fentry)->request->processing*/) + { + cserve2_request_cancel_all(ASENTRY(fentry)->request, + CSERVE2_FILE_CHANGED); + ASENTRY(fentry)->request = NULL; + } + if (!fentry->images && !ASENTRY(fentry)->references) + { + _file_entry_free(fentry); + _file_data_free(fd); + } } eina_hash_del_by_key(file_watch, fw->path); @@ -1220,8 +1355,6 @@ _font_load_request_build(void *data, int *size) msg->rend_flags = fe->rend_flags; msg->size = fe->size; msg->dpi = fe->dpi; - -#warning TODO Use shared index on client side msg->name = cserve2_shared_string_get(fe->src->name); msg->file = cserve2_shared_string_get(fe->src->file); @@ -1751,21 +1884,21 @@ static Eina_Bool _image_file_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) { Msg_Stats *msg = fdata; - File_Data *fd = data; + File_Entry *fentry = data; // accounting numbers msg->images.files_loaded++; // accounting size msg->images.files_size += sizeof(File_Data) + - eina_list_count(fd->images) * sizeof(Eina_List *) + - eina_list_count(fd->base.references) * + eina_list_count(fentry->images) * sizeof(Eina_List *) + + eina_list_count(ASENTRY(fentry)->references) * (sizeof(Slave_Request *) + sizeof(Eina_List *)); #ifdef DEBUG_LOAD_TIME // accounting file entries load time - msg->images.files_load_time += fd->base.load_time; - msg->images.files_saved_time += fd->base.saved_time; + msg->images.files_load_time += ASENTRY(fentry)->load_time; + msg->images.files_saved_time += ASENTRY(fentry)->saved_time; #endif return EINA_TRUE; @@ -1776,7 +1909,7 @@ _image_data_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EI { Msg_Stats *msg = fdata; Image_Data *id = data; - unsigned int image_size; + File_Data *fd; // accounting numbers msg->images.images_loaded++; @@ -1786,9 +1919,13 @@ _image_data_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EI msg->images.images_size += _image_entry_size_get(id) * 1024; if (id->unused) msg->images.unused_size += _image_entry_size_get(id) * 1024; - image_size = id->file->w * id->file->h * 4; - msg->images.requested_size += - (image_size * eina_list_count(id->base.references)); + fd = _file_data_find(id->file_id); + if (fd) + { + unsigned int image_size = fd->w * fd->h * 4; + msg->images.requested_size += + (image_size * eina_list_count(id->base.references)); + } #ifdef DEBUG_LOAD_TIME // accounting image entries load time @@ -2047,15 +2184,17 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, Reference *ref; File_Watch *fw; char buf[4906]; + File_Entry *fentry; + int idx; // look for this file on client references ref = eina_hash_find(client->files.referencing, &client_file_id); if (ref) { - fd = (File_Data *)ref->entry; _entry_load_reused(ref->entry); - if (fd->invalid) + fd = _file_data_find(ref->entry->id); + if (!fd || fd->invalid) { cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED); return -1; @@ -2065,8 +2204,8 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, ref->count++; // File already being loaded, just add the request to be replied - if (fd->base.request) - cserve2_request_waiter_add(fd->base.request, rid, client); + if (ref->entry->request) + cserve2_request_waiter_add(ref->entry->request, rid, client); else _image_opened_send(client, fd, rid); return 0; @@ -2079,8 +2218,8 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, { DBG("found file_id %u for client file id %d", file_id, client_file_id); - fd = eina_hash_find(file_entries, &file_id); - if (!fd) + fentry = _file_entry_find(file_id); + if (!fentry) { ERR("file \"%s\" is in file_ids hash but not in entries hash.", buf); @@ -2088,30 +2227,43 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, // FIXME: Maybe we should remove the entry from file_ids then? return -1; } - ref = _entry_reference_add((Entry *)fd, client, client_file_id); + ref = _entry_reference_add(ASENTRY(fentry), client, client_file_id); _entry_load_reused(ref->entry); eina_hash_add(client->files.referencing, &client_file_id, ref); - if (fd->base.request) - cserve2_request_waiter_add(fd->base.request, rid, client); + if (ref->entry->request) + cserve2_request_waiter_add(ref->entry->request, rid, client); else // File already loaded, otherwise there would be a request - _image_opened_send(client, fd, rid); + { + fd = _file_data_find(file_id); + _image_opened_send(client, fd, rid); + } return 0; } file_id = ++_entry_id; - while ((file_id == 0) || (eina_hash_find(file_entries, &file_id))) + while (eina_hash_find(file_entries, &file_id)) file_id = ++_entry_id; - DBG("Creating new entry with file_id: %u for file \"%s:%s\"", - file_id, path, key); - fd = calloc(1, sizeof(*fd)); - fd->base.type = CSERVE2_IMAGE_FILE; + idx = cserve2_shared_array_item_new(_file_data_array); + fd = cserve2_shared_array_item_data_get(_file_data_array, idx); + DBG("Creating new entry with file_id: %u for file \"%s:%s\". Index %d at %p", + file_id, path, key, idx, fd); + if (!fd) + { + ERR("Could not create new file entry!"); + return -1; + } + fd->id = file_id; // FIXME: write last (?) + fd->refcount = 1; fd->path = cserve2_shared_string_add(path); fd->key = cserve2_shared_string_add(key); - fd->base.id = file_id; - eina_hash_add(file_entries, &file_id, fd); + + fentry = calloc(1, sizeof(File_Entry)); + ASENTRY(fentry)->type = CSERVE2_IMAGE_FILE; + ASENTRY(fentry)->id = file_id; + eina_hash_add(file_entries, &file_id, fentry); eina_hash_add(file_ids, buf, (void*)(intptr_t)file_id); - ref = _entry_reference_add((Entry *)fd, client, client_file_id); + ref = _entry_reference_add(ASENTRY(fentry), client, client_file_id); eina_hash_add(client->files.referencing, &client_file_id, ref); fw = eina_hash_find(file_watch, cserve2_shared_string_get(fd->path)); @@ -2122,14 +2274,12 @@ cserve2_cache_file_open(Client *client, unsigned int client_file_id, cserve2_file_change_watch_add(fw->path, _file_changed_cb, fw); eina_hash_direct_add(file_watch, fw->path, fw); } - fw->entries = eina_list_append(fw->entries, fd); - fd->watcher = fw; + fw->entries = eina_list_append(fw->entries, fentry); + fentry->watcher = fw; - fd->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_OPEN, - rid, client, NULL, &_open_funcs, - fd); - - // _open_image_default_set(fd); + ASENTRY(fentry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_OPEN, + rid, client, NULL, + &_open_funcs, fentry); return 0; } @@ -2163,9 +2313,9 @@ _cserve2_cache_fast_scaling_check(Client *client, Image_Data *entry) int scaled_count = 0; int dst_w, dst_h; Eina_Bool first_attempt = EINA_TRUE; + File_Entry *fentry; if (!entry) return -1; - if (!entry->file) return -1; dst_w = entry->opts.scale_load.dst_w; dst_h = entry->opts.scale_load.dst_h; @@ -2206,7 +2356,9 @@ try_again: goto try_again; } - iter = eina_list_iterator_new(entry->file->images); + fentry = _file_entry_find(entry->file_id); + iter = eina_list_iterator_new(fentry->images); + //iter = eina_list_iterator_new(entry->file->images); EINA_ITERATOR_FOREACH(iter, i) { if (i == entry) continue; @@ -2228,16 +2380,13 @@ try_again: if (!original) { - DBG("Found %d scaled images for %s:%s but none matches", - scaled_count, cserve2_shared_string_get(entry->file->path), - cserve2_shared_string_get(entry->file->key)); + DBG("Found %d scaled images for image %u but none matches", + scaled_count, entry->base.id); if (scaled_count >= 4) { DBG("Forcing load of original image now!"); - File_Data *fd; - original = _image_entry_new(client, 0, entry->file_id, 0, &unscaled); if (!original) return -1; @@ -2252,8 +2401,8 @@ try_again: eina_hash_add(image_ids, buf, (void *)(intptr_t)image_id); _entry_unused_push(original); - fd = original->file; - fd->images = eina_list_append(fd->images, original); + fentry = _file_entry_find(original->file_id); + fentry->images = eina_list_append(fentry->images, original); } else return -1; @@ -2299,8 +2448,8 @@ cserve2_cache_image_entry_create(Client *client, int rid, Evas_Image_Load_Opts *opts) { Image_Data *entry; - File_Data *fd = NULL; Reference *ref, *oldref; + File_Entry *fentry; unsigned int image_id; char buf[4096]; @@ -2360,8 +2509,8 @@ cserve2_cache_image_entry_create(Client *client, int rid, eina_hash_del_by_key(client->images.referencing, &client_image_id); eina_hash_add(client->images.referencing, &client_image_id, ref); - fd = entry->file; - fd->images = eina_list_append(fd->images, entry); + fentry = _file_entry_find(entry->file_id); + fentry->images = eina_list_append(fentry->images, entry); if (opts && opts->scale_load.dst_w && opts->scale_load.dst_h) { @@ -2369,9 +2518,9 @@ cserve2_cache_image_entry_create(Client *client, int rid, return 0; } - entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD, - 0, NULL, fd->base.request, - &_load_funcs, entry); + ASENTRY(entry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD, + 0, NULL, ASENTRY(fentry)->request, + &_load_funcs, entry); return 0; } @@ -2380,6 +2529,7 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned { Image_Data *entry; Reference *ref; + File_Data *fd; ref = eina_hash_find(client->images.referencing, &client_image_id); if (!ref) @@ -2389,9 +2539,9 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned return; } - entry = (Image_Data *)ref->entry; - - if (entry->file->invalid) + entry = (Image_Data *) ref->entry; + fd = _file_data_find(entry->file_id); + if (!fd || fd->invalid) { cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED); return; @@ -2409,11 +2559,14 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned else if (entry->shm) _image_loaded_send(client, entry, rid); else - entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD, - rid, client, - entry->file->base.request, - &_load_funcs, - entry); + { + File_Entry *fentry = _file_entry_find(entry->file_id); + ASENTRY(entry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD, + rid, client, + ASENTRY(fentry)->request, + &_load_funcs, + entry); + } entry->doload = EINA_TRUE; } @@ -2423,6 +2576,7 @@ cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsign { Image_Data *entry; Reference *ref; + File_Data *fd; ref = eina_hash_find(client->images.referencing, &client_image_id); if (!ref) @@ -2432,9 +2586,9 @@ cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsign return; } - entry = (Image_Data *)ref->entry; - - if (entry->file->invalid) + entry = (Image_Data *) ref->entry; + fd = _file_data_find(entry->file_id); + if (!fd || fd->invalid) { cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED); return; @@ -2452,11 +2606,14 @@ cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsign else if (entry->shm) _image_loaded_send(client, entry, rid); else - entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD, - rid, client, - entry->file->base.request, - &_load_funcs, - entry); + { + File_Entry *fentry = _file_entry_find(entry->file_id); + ASENTRY(entry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD, + rid, client, + ASENTRY(fentry)->request, + &_load_funcs, + entry); + } entry->doload = EINA_TRUE; } diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c index 2579104a7f..b79c2f8e73 100644 --- a/src/bin/evas/evas_cserve2_index.c +++ b/src/bin/evas/evas_cserve2_index.c @@ -462,7 +462,7 @@ cserve2_shared_array_item_find(Shared_Array *sa, void *data, // TODO: Fast search in the sorted zone - ptr = sa->ds->data; + ptr = sa->ds->data + sizeof(Shared_Array_Header); // Linear search O(n) for (k = 0; k < sa->header->emptyidx; k++) @@ -482,7 +482,8 @@ cserve2_shared_array_item_data_find(Shared_Array *sa, void *data, int elemid; elemid = cserve2_shared_array_item_find(sa, data, cmp); - if (elemid < 0) return NULL; + if (elemid < 0) + return NULL; return cserve2_shared_array_item_data_get(sa, elemid); }