evas/cserve2: Remap string entries when size changed
authorJean-Philippe Andre <jp.andre@samsung.com>
Fri, 23 Aug 2013 05:52:11 +0000 (14:52 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:14 +0000 (15:47 +0900)
Lots of files can't be found by the client when the strings table
changed, because it was not remapped properly.

src/lib/evas/cserve2/evas_cs2_client.c

index 9bcf966..7746e1d 100644 (file)
@@ -1661,58 +1661,11 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_F
 
 static Eina_Bool _shared_index_remap_check(Shared_Index *si, int elemsize);
 
-// Returns the number of correctly opened index arrays
-static int
-_server_index_list_set(Msg_Base *data, int size)
+static Eina_Bool
+_string_index_refresh(void)
 {
-   Msg_Index_List *msg = (Msg_Index_List *) data;
-   unsigned sz;
-
-   // TODO #1: Check populate rule.
-   // TODO #2: Protect memory for read-only access.
-   // TODO #3: Optimize file reopen/remap (esp. strings table)
-
-   if (size != sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST)
-     {
-        CRIT("Invalid message! type: %d, size: %d (expected %d)",
-             msg->base.type, size, (int) sizeof(*msg));
-        return -1;
-     }
-
-   if (_index.generation_id == msg->generation_id)
-     {
-        ERR("New index generation_id is the same as before: %d",
-            _index.generation_id);
-     }
-
-   _index.generation_id = msg->generation_id;
-
-   // 1. Strings (indexes and entries)
-
-   if (_index.strings_entries.data
-       && strncmp(_index.strings_entries.path, msg->strings_entries_path,
-                  SHARED_BUFFER_PATH_MAX) != 0)
-     {
-        DBG("Updating string entries shm to: '%s'", msg->strings_entries_path);
-        eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
-        eina_file_close(_index.strings_entries.f);
-        _index.strings_entries.f = NULL;
-        _index.strings_entries.data = NULL;
-     }
-
-   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);
+   size_t sz;
+   Eina_Bool ret = EINA_FALSE;
 
    if (!_index.strings_entries.data
        && _index.strings_entries.path[0]
@@ -1729,8 +1682,13 @@ _server_index_list_set(Msg_Base *data, int size)
              eina_file_close(_index.strings_entries.f);
              _index.strings_entries.f = NULL;
              _index.strings_entries.data = NULL;
+             ret = EINA_FALSE;
+          }
+        else
+          {
+             DBG("Mapped string entries from %s", _index.strings_entries.path);
+             ret = EINA_TRUE;
           }
-        else DBG("Mapped string entries from %s", _index.strings_entries.path);
      }
 
    if (_index.strings_entries.data &&
@@ -1752,6 +1710,7 @@ _server_index_list_set(Msg_Base *data, int size)
                       _index.strings_index.count, _index.strings_index.header->count);
                   _index.strings_index.count = _index.strings_index.header->count;
                }
+             ret = EINA_TRUE;
           }
         else
           {
@@ -1762,20 +1721,79 @@ _server_index_list_set(Msg_Base *data, int size)
              _index.strings_index.f = NULL;
              _index.strings_entries.f = NULL;
              _index.strings_entries.data = NULL;
+             ret = EINA_FALSE;
           }
      }
 
    _shared_index_remap_check(&_index.strings_index, sizeof(Index_Entry));
    if (_index.strings_entries.data)
      {
-        if (eina_file_refresh(_index.strings_entries.f))
+        if (eina_file_refresh(_index.strings_entries.f)
+            || (_index.strings_entries.size != (int) eina_file_size_get(_index.strings_entries.f)))
           {
              eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
              _index.strings_entries.data = eina_file_map_all(_index.strings_entries.f, EINA_FILE_RANDOM);
              _index.strings_entries.size = eina_file_size_get(_index.strings_entries.f);
+             return EINA_TRUE;
           }
      }
 
+   return ret;
+}
+
+// Returns the number of correctly opened index arrays
+static int
+_server_index_list_set(Msg_Base *data, int size)
+{
+   Msg_Index_List *msg = (Msg_Index_List *) data;
+
+   // TODO #1: Check populate rule.
+   // TODO #2: Protect memory for read-only access.
+   // TODO #3: Optimize file reopen/remap (esp. strings table)
+
+   if (size != sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST)
+     {
+        CRIT("Invalid message! type: %d, size: %d (expected %d)",
+             msg->base.type, size, (int) sizeof(*msg));
+        return -1;
+     }
+
+   if (_index.generation_id == msg->generation_id)
+     {
+        ERR("New index generation_id is the same as before: %d",
+            _index.generation_id);
+     }
+
+   _index.generation_id = msg->generation_id;
+
+   // 1. Strings (indexes and entries)
+
+   if (_index.strings_entries.data
+       && strncmp(_index.strings_entries.path, msg->strings_entries_path,
+                  SHARED_BUFFER_PATH_MAX) != 0)
+     {
+        DBG("Updating string entries shm to: '%s'", msg->strings_entries_path);
+        eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
+        eina_file_close(_index.strings_entries.f);
+        _index.strings_entries.f = NULL;
+        _index.strings_entries.data = NULL;
+     }
+
+   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);
+   _string_index_refresh();
+
 
    // 2. File indexes
 
@@ -1803,12 +1821,29 @@ _shared_string_get(int id)
 {
    Index_Entry *ie;
 
+   if (!_index.strings_entries.data)
+     {
+        CRIT("Strings table is not valid: no data");
+        return NULL;
+     }
+
    ie = (Index_Entry *)
          _shared_index_item_get_by_id(&_index.strings_index, sizeof(*ie), id);
    if (!ie) return NULL;
    if (ie->offset < 0) return NULL;
    if (!ie->refcount) return NULL;
-   if (ie->offset + ie->length > _index.strings_entries.size) return NULL;
+   if (ie->offset + ie->length > _index.strings_entries.size)
+     {
+        if (eina_file_refresh(_index.strings_entries.f)
+            || (_index.strings_entries.size != (int) eina_file_size_get(_index.strings_entries.f)))
+          {
+             DBG("String entries size has changed from %d to %d",
+                 _index.strings_entries.size, (int) eina_file_size_get(_index.strings_entries.f));
+             if (_string_index_refresh())
+               return _shared_string_get(id);
+          }
+        return NULL;
+     }
 
    return _index.strings_entries.data + ie->offset;
 }
@@ -1821,7 +1856,7 @@ static const char *
 _shared_file_data_hkey_get(char *hkey, const char *file, const char *key,
                            size_t hkey_size)
 {
-   size_t keylen, filelen;
+   size_t keylen = 0, filelen;
 
    if (key) keylen = strlen(key) + 1;
    filelen = strlen(file);
@@ -2071,6 +2106,7 @@ _shared_index_remap_check(Shared_Index *si, int elemsize)
              si->f = NULL;
              return EINA_FALSE;
           }
+        si->count = (filesize - sizeof(Shared_Array_Header)) / elemsize;
         refresh = EINA_TRUE;
      }