On Wed, 13 Apr 2011, Enlightenment SVN wrote:
> +}
> +
> +static unsigned int
> +_eina_file_map_key_length(__UNUSED__ const void *key)
> +{
> +   return sizeof (unsigned long int) * 2;

just to be sure: are you supposing that long is of size 64bits on 64bits 
arch ? because it's not the case on Windows 64 bits

same for the functions below

Vincent

> +}
> +
> +static int
> +_eina_file_map_key_cmp(const unsigned long int *key1, __UNUSED__ int 
> key1_length,
> +                       const unsigned long int *key2, __UNUSED__ int 
> key2_length)
> +{
> +   if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
> +   return key1[0] - key2[0];
> +}
> +
> +static int
> +_eina_file_map_key_hash(const unsigned long int *key, __UNUSED__ int 
> key_length)
> +{
> +   return eina_hash_int64(&key[0], sizeof (unsigned long int))
> +     ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
> +}
> +
> +static void
> +_eina_file_map_rule_apply(Eina_File_Populate rule, void *addr, unsigned long 
> int size)
> +{
> +   int flag;
> +
> +   switch (rule)
> +     {
> +      case EINA_FILE_RANDOM: flag = MADV_RANDOM; break;
> +      case EINA_FILE_SEQUENTIAL: flag = MADV_SEQUENTIAL; break;
> +      case EINA_FILE_WILLNEED:
> +      case EINA_FILE_POPULATE:
> +          flag = MADV_WILLNEED;
> +          break;
> +     }
> +
> +   madvise(addr, size, flag);
> +}
> +
> +Eina_Bool
> +eina_file_init(void)
> +{
> +   _eina_file_log_dom = eina_log_domain_register("eina_file",
> +                                                 EINA_LOG_COLOR_DEFAULT);
> +   if (_eina_file_log_dom < 0)
> +     {
> +        EINA_LOG_ERR("Could not register log domain: eina_file");
> +        return EINA_FALSE;
> +     }
> +
> +   _eina_file_cache = 
> eina_hash_string_djb2_new(EINA_FREE_CB(_eina_file_real_close));
> +   if (!_eina_file_cache)
> +     {
> +        ERR("Could not create cache.");
> +        eina_log_domain_unregister(_eina_file_log_dom);
> +        _eina_file_log_dom = -1;
> +        return EINA_FALSE;
> +     }
> +
> +   return EINA_TRUE;
> +}
> +
> +Eina_Bool
> +eina_file_shutdown(void)
> +{
> +   Eina_File *f;
> +   Eina_List *l;
> +
> +   EINA_LIST_FREE(_eina_file_cache_delete, f)
> +     _eina_file_real_close(f);
> +
> +   EINA_LIST_FOREACH(_eina_file_cache_lru, l, f)
> +     eina_hash_del(_eina_file_cache, f->filename, f);
> +
> +   if (eina_hash_population(_eina_file_cache) > 0)
> +     {
> +        Eina_Iterator *it;
> +        const char *key;
> +
> +        it = eina_hash_iterator_key_new(_eina_file_cache);
> +        EINA_ITERATOR_FOREACH(it, key)
> +          ERR("File [%s] still open !", key);
> +        eina_iterator_free(it);
> +     }
> +
> +   eina_hash_free(_eina_file_cache);
> +
> +   eina_log_domain_unregister(_eina_file_log_dom);
> +   _eina_file_log_dom = -1;
> +   return EINA_FALSE;
> +}
> +
> /**
>  * @endcond
>  */
> @@ -527,3 +703,228 @@
>
>    return &it->iterator;
> }
> +
> +EAPI Eina_File *
> +eina_file_open(const char *filename, Eina_Bool shared)
> +{
> +   Eina_File *file;
> +   Eina_File *n;
> +   struct stat file_stat;
> +   int fd;
> +   Eina_Bool create = EINA_FALSE;
> +
> +   /* FIXME: always open absolute path (need to fix filename according to 
> current
> +      directory) */
> +
> +   if (shared)
> +     fd = shm_open(filename, O_RDONLY | O_CLOEXEC, ACCESSPERMS);
> +   else
> +     fd = open(filename, O_RDONLY | O_CLOEXEC, ACCESSPERMS);
> +
> +   if (fd < 0) return NULL;
> +
> +   if (fstat(fd, &file_stat))
> +     {
> +        close(fd);
> +        return NULL;
> +     }
> +
> +   file = eina_hash_find(_eina_file_cache, filename);
> +   if (file && (file->mtime != file_stat.st_mtime
> +                || file->length != file_stat.st_size))
> +     {
> +        create = EINA_TRUE;
> +
> +        if (file->refcount == 0)
> +          {
> +             _eina_file_cache_lru = eina_list_prepend(_eina_file_cache_lru, 
> file);
> +             eina_hash_del(_eina_file_cache, file->filename, file);
> +
> +             file = NULL;
> +          }
> +        else if (!file->delete_me)
> +          {
> +             file->delete_me = EINA_TRUE;
> +             _eina_file_cache_delete = 
> eina_list_prepend(_eina_file_cache_delete, file);
> +          }
> +     }
> +
> +   if (!file || create)
> +     {
> +        n = malloc(sizeof (Eina_File));
> +        if (!n) goto on_error;
> +
> +        n->filename = eina_stringshare_add(filename);
> +        n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length),
> +                               EINA_KEY_CMP(_eina_file_map_key_cmp),
> +                               EINA_KEY_HASH(_eina_file_map_key_hash),
> +                               EINA_FREE_CB(_eina_file_map_close),
> +                               3);
> +        n->rmap = eina_hash_pointer_new(NULL);
> +        n->global_map = MAP_FAILED;
> +        n->length = file_stat.st_size;
> +        n->mtime = file_stat.st_mtime;
> +        n->refcount = 0;
> +        n->fd = fd;
> +        n->shared = shared;
> +        n->delete_me = EINA_FALSE;
> +
> +        eina_hash_set(_eina_file_cache, filename, n);
> +     }
> +   else
> +     {
> +        close(fd);
> +
> +        n = file;
> +
> +        if (n->refcount == 0)
> +          _eina_file_cache_lru = eina_list_remove(_eina_file_cache_lru, n);
> +     }
> +
> +   n->refcount++;
> +
> +   return n;
> +
> + on_error:
> +   close(fd);
> +   return NULL;
> +}
> +
> +EAPI void
> +eina_file_close(Eina_File *file)
> +{
> +   file->refcount--;
> +
> +   if (file->refcount != 0) return ;
> +
> +   if (file->delete_me)
> +     {
> +        _eina_file_cache_delete = eina_list_remove(_eina_file_cache_delete, 
> file);
> +        _eina_file_real_close(file);
> +     }
> +   else
> +     {
> +        _eina_file_cache_lru = eina_list_prepend(_eina_file_cache_lru, file);
> +     }
> +}
> +
> +EAPI unsigned long int
> +eina_file_size_get(Eina_File *file)
> +{
> +   return file->length;
> +}
> +
> +EAPI time_t
> +eina_file_mtime_get(Eina_File *file)
> +{
> +   return file->mtime;
> +}
> +
> +EAPI const char *
> +eina_file_filename_get(Eina_File *file)
> +{
> +   return file->filename;
> +}
> +
> +EAPI void *
> +eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
> +{
> +   int flags = MAP_SHARED;
> +
> +   if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
> +
> +   if (file->global_map == MAP_FAILED)
> +     file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 
> 0);
> +
> +   if (file->global_map != MAP_FAILED)
> +     {
> +        _eina_file_map_rule_apply(rule, file->global_map, file->length);
> +        file->global_refcount++;
> +        return file->global_map;
> +     }
> +   return NULL;
> +}
> +
> +EAPI void *
> +eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
> +                  unsigned long int offset, unsigned long int length)
> +{
> +   Eina_File_Map *map;
> +   unsigned long int key[2];
> +
> +   if (offset > file->length)
> +     return NULL;
> +   if (offset + length > file->length)
> +     return NULL;
> +
> +   if (offset == 0 && length == file->length)
> +     return eina_file_map_all(file, rule);
> +
> +   key[0] = offset;
> +   key[1] = length;
> +
> +   map = eina_hash_find(file->map, &key);
> +   if (!map)
> +     {
> +        int flags = MAP_SHARED;
> +
> +        if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
> +
> +        map = malloc(sizeof (Eina_File_Map));
> +        if (!map) return NULL;
> +
> +        map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset);
> +        map->offset = offset;
> +        map->length = length;
> +        map->refcount = 0;
> +
> +        if (map->map == MAP_FAILED)
> +          {
> +             free(map);
> +             return NULL;
> +          }
> +
> +        eina_hash_add(file->map, &key, map);
> +        eina_hash_direct_add(file->rmap, map->map, map);
> +     }
> +
> +   map->refcount++;
> +
> +   _eina_file_map_rule_apply(rule, map->map, length);
> +
> +   return map->map;
> +}
> +
> +EAPI void
> +eina_file_map_free(Eina_File *file, void *map)
> +{
> +   if (file->global_map == map)
> +     {
> +        file->global_refcount--;
> +
> +        if (file->global_refcount > 0) return ;
> +
> +        munmap(file->global_map, file->length);
> +        file->global_map = MAP_FAILED;
> +     }
> +   else
> +     {
> +        Eina_File_Map *em;
> +        unsigned long int key[2];
> +
> +        em = eina_hash_find(file->rmap, &map);
> +        if (!em) return ;
> +
> +        em->refcount--;
> +
> +        if (em->refcount > 0) return ;
> +
> +        key[0] = em->offset;
> +        key[1] = em->length;
> +
> +        eina_hash_del(file->rmap, &map, em);
> +        eina_hash_del(file->map, &key, em);
> +     }
> +}
> +
> +
>
> Modified: trunk/eina/src/lib/eina_main.c
> ===================================================================
> --- trunk/eina/src/lib/eina_main.c    2011-04-13 13:29:54 UTC (rev 58636)
> +++ trunk/eina/src/lib/eina_main.c    2011-04-13 16:15:30 UTC (rev 58637)
> @@ -124,6 +124,7 @@
>    S(ustrbuf);
>    S(quadtree);
>    S(simple_xml);
> +   S(file);
> #undef S
>
> struct eina_desc_setup
> @@ -156,7 +157,8 @@
>    S(strbuf),
>    S(ustrbuf),
>    S(quadtree),
> -   S(simple_xml)
> +   S(simple_xml),
> +   S(file)
> #undef S
> };
> static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
>
>
> ------------------------------------------------------------------------------
> Forrester Wave Report - Recovery time is now measured in hours and minutes
> not days. Key insights are discussed in the 2010 Forrester Wave Report as
> part of an in-depth evaluation of disaster recovery service providers.
> Forrester found the best-in-class provider in terms of services and vision.
> Read this report now!  http://p.sf.net/sfu/ibm-webcastpromo
> _______________________________________________
> enlightenment-svn mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
>
>

------------------------------------------------------------------------------
Forrester Wave Report - Recovery time is now measured in hours and minutes
not days. Key insights are discussed in the 2010 Forrester Wave Report as
part of an in-depth evaluation of disaster recovery service providers.
Forrester found the best-in-class provider in terms of services and vision.
Read this report now!  http://p.sf.net/sfu/ibm-webcastpromo
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to