jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=acae35b4d1cb2a8aa602cc9c1e6de468997de059

commit acae35b4d1cb2a8aa602cc9c1e6de468997de059
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Jul 22 16:28:42 2013 +0900

    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 6075200..d3926e2 100644
--- a/src/bin/evas/evas_cserve2_cache.c
+++ b/src/bin/evas/evas_cserve2_cache.c
@@ -14,20 +14,15 @@
 
 #include <Evas_Loader.h>
 
-// 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;
-
-   fd->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_OPEN,
-                                          rid, client, NULL, &_open_funcs,
-                                          fd);
+   fw->entries = eina_list_append(fw->entries, fentry);
+   fentry->watcher = fw;
 
-   // _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 2579104..b79c2f8 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);
 }

-- 


Reply via email to