evas/cserve2: Reuse file entries when possible
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 3 Sep 2013 06:24:27 +0000 (15:24 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:15 +0000 (15:47 +0900)
For some reason, a new File_Entry was created whenever
a new image is loaded, even if that file was already
opened by the client.

src/lib/evas/cserve2/evas_cs2_client.c

index 59ca5406c653eb34739e5d6f3153a39921db28a4..852ae0864028a4ed6b3d8981cd644d79e4e5163d 100644 (file)
@@ -26,6 +26,8 @@ typedef void (*Op_Callback)(void *data, const void *msg, int size);
 struct _File_Entry {
    unsigned int file_id;
    unsigned int server_file_id;
+   unsigned int refcount;
+   Eina_Stringshare *hkey;
 };
 
 struct _Client_Request {
@@ -46,6 +48,7 @@ static unsigned int _file_id = 0;
 static unsigned int _data_id = 0;
 
 static Eina_List *_requests = NULL;
+static Eina_Hash *_file_entries = NULL;
 
 // Shared index table
 static Index_Table _index;
@@ -81,6 +84,15 @@ _memory_zero_cmp(void *data, size_t len)
    return EINA_TRUE;
 }
 
+static void
+_file_entry_free(void *data)
+{
+   File_Entry *fentry = data;
+   if (!fentry) return;
+   eina_stringshare_del(fentry->hkey);
+   free(fentry);
+}
+
 static void
 _socket_path_set(char *path)
 {
@@ -304,6 +316,7 @@ evas_cserve2_init(void)
         return 0;
      }
 
+   _file_entries = eina_hash_string_superfast_new(EINA_FREE_CB(_file_entry_free));
    return cserve2_init;
 }
 
@@ -313,6 +326,12 @@ evas_cserve2_shutdown(void)
    const char zeros[sizeof(Msg_Index_List)] = {0};
    Msg_Index_List *empty = (Msg_Index_List *) zeros;
 
+   if (cserve2_init <= 0)
+     {
+        CRIT("cserve2 is already shutdown");
+        return -1;
+     }
+
    if ((--cserve2_init) > 0)
      return cserve2_init;
 
@@ -321,6 +340,9 @@ evas_cserve2_shutdown(void)
    _server_index_list_set((Msg_Base *) empty, sizeof(Msg_Index_List));
    _server_disconnect();
 
+   eina_hash_free(_file_entries);
+   _file_entries = NULL;
+
    return cserve2_init;
 }
 
@@ -674,6 +696,7 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
    int size;
    char *buf;
    char filebuf[PATH_MAX];
+   char *file_hkey;
    Msg_Open msg_open;
    File_Entry *fentry;
    Data_Entry *dentry;
@@ -696,23 +719,35 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
    flen++;
 
    if (!key) key = "";
+   klen = strlen(key) + 1;
 
-   fentry = calloc(1, sizeof(*fentry));
+   file_hkey = alloca(flen + klen);
+   memcpy(file_hkey, file, flen);
+   file_hkey[flen - 1] = ':';
+   memcpy(file_hkey + flen, key, klen);
+   fentry = eina_hash_find(_file_entries, file_hkey);
    if (!fentry)
-     return 0;
+     {
+        fentry = calloc(1, sizeof(*fentry));
+        if (!fentry)
+          return 0;
+
+        fentry->file_id = ++_file_id;
+        fentry->hkey = eina_stringshare_add(file_hkey);
+        eina_hash_direct_add(_file_entries, fentry->hkey, fentry);
+     }
+   fentry->refcount++;
 
    dentry = calloc(1, sizeof(*dentry));
    if (!dentry)
      {
-        free(fentry);
+        if (!(--fentry->refcount))
+          eina_hash_del(_file_entries, fentry->hkey, fentry);
         return 0;
      }
 
    memset(&msg_open, 0, sizeof(msg_open));
 
-   fentry->file_id = ++_file_id;
-   klen = strlen(key) + 1;
-
    msg_open.base.rid = _next_rid();
    msg_open.base.type = CSERVE2_OPEN;
    msg_open.file_id = fentry->file_id;
@@ -727,7 +762,8 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
    buf = malloc(size);
    if (!buf)
      {
-        free(fentry);
+        if (!(--fentry->refcount))
+          eina_hash_del(_file_entries, fentry->hkey, fentry);
         free(dentry);
         return 0;
      }
@@ -741,8 +777,9 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
      {
         ERR("Couldn't send message to server.");
         free(buf);
-        free(fentry);
         free(dentry);
+        if (!(--fentry->refcount))
+          eina_hash_del(_file_entries, fentry->hkey, fentry);
         return 0;
      }
 
@@ -848,7 +885,8 @@ _image_close_server_send(Image_Entry *ie)
    msg.base.type = CSERVE2_CLOSE;
    msg.file_id = fentry->file_id;
 
-   free(fentry);
+   if (!(--fentry->refcount))
+     eina_hash_del(_file_entries, fentry->hkey, fentry);
    ie->data1 = NULL;
 
    if (!_server_send(&msg, sizeof(msg), NULL, NULL))