forked from enlightenment/efl
parent
f07605db74
commit
5fa5eb95cd
|
@ -64,6 +64,7 @@ void *alloca (size_t);
|
||||||
#include "eina_stringshare.h"
|
#include "eina_stringshare.h"
|
||||||
#include "eina_hash.h"
|
#include "eina_hash.h"
|
||||||
#include "eina_list.h"
|
#include "eina_list.h"
|
||||||
|
#include "eina_lock.h"
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* Local *
|
* Local *
|
||||||
|
@ -116,6 +117,8 @@ struct _Eina_File
|
||||||
Eina_Hash *rmap;
|
Eina_Hash *rmap;
|
||||||
void *global_map;
|
void *global_map;
|
||||||
|
|
||||||
|
Eina_Lock lock;
|
||||||
|
|
||||||
unsigned long long length;
|
unsigned long long length;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
ino_t inode;
|
ino_t inode;
|
||||||
|
@ -142,6 +145,7 @@ struct _Eina_File_Map
|
||||||
static Eina_Hash *_eina_file_cache = NULL;
|
static Eina_Hash *_eina_file_cache = NULL;
|
||||||
static Eina_List *_eina_file_cache_lru = NULL;
|
static Eina_List *_eina_file_cache_lru = NULL;
|
||||||
static Eina_List *_eina_file_cache_delete = NULL;
|
static Eina_List *_eina_file_cache_delete = NULL;
|
||||||
|
static Eina_Lock _eina_file_lock_cache;
|
||||||
|
|
||||||
static int _eina_file_log_dom = -1;
|
static int _eina_file_log_dom = -1;
|
||||||
|
|
||||||
|
@ -487,6 +491,8 @@ eina_file_init(void)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eina_lock_new(&_eina_file_lock_cache);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,6 +521,8 @@ eina_file_shutdown(void)
|
||||||
|
|
||||||
eina_hash_free(_eina_file_cache);
|
eina_hash_free(_eina_file_cache);
|
||||||
|
|
||||||
|
eina_lock_free(&_eina_file_lock_cache);
|
||||||
|
|
||||||
eina_log_domain_unregister(_eina_file_log_dom);
|
eina_log_domain_unregister(_eina_file_log_dom);
|
||||||
_eina_file_log_dom = -1;
|
_eina_file_log_dom = -1;
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -771,6 +779,8 @@ eina_file_open(const char *filename, Eina_Bool shared)
|
||||||
if (fstat(fd, &file_stat))
|
if (fstat(fd, &file_stat))
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
|
eina_lock_take(&_eina_file_lock_cache);
|
||||||
|
|
||||||
file = eina_hash_find(_eina_file_cache, filename);
|
file = eina_hash_find(_eina_file_cache, filename);
|
||||||
if (file && (file->mtime != file_stat.st_mtime
|
if (file && (file->mtime != file_stat.st_mtime
|
||||||
|| file->length != (unsigned long long) file_stat.st_size
|
|| file->length != (unsigned long long) file_stat.st_size
|
||||||
|
@ -814,6 +824,7 @@ eina_file_open(const char *filename, Eina_Bool shared)
|
||||||
n->fd = fd;
|
n->fd = fd;
|
||||||
n->shared = shared;
|
n->shared = shared;
|
||||||
n->delete_me = EINA_FALSE;
|
n->delete_me = EINA_FALSE;
|
||||||
|
eina_lock_new(&n->lock);
|
||||||
|
|
||||||
if (file) eina_hash_del(_eina_file_cache, filename, file);
|
if (file) eina_hash_del(_eina_file_cache, filename, file);
|
||||||
eina_hash_direct_add(_eina_file_cache, n->filename, n);
|
eina_hash_direct_add(_eina_file_cache, n->filename, n);
|
||||||
|
@ -828,7 +839,11 @@ eina_file_open(const char *filename, Eina_Bool shared)
|
||||||
_eina_file_cache_lru = eina_list_remove(_eina_file_cache_lru, n);
|
_eina_file_cache_lru = eina_list_remove(_eina_file_cache_lru, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eina_lock_take(&n->lock);
|
||||||
n->refcount++;
|
n->refcount++;
|
||||||
|
eina_lock_release(&n->lock);
|
||||||
|
|
||||||
|
eina_lock_release(&_eina_file_lock_cache);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
|
@ -840,13 +855,16 @@ eina_file_open(const char *filename, Eina_Bool shared)
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_file_close(Eina_File *file)
|
eina_file_close(Eina_File *file)
|
||||||
{
|
{
|
||||||
|
eina_lock_take(&file->lock);
|
||||||
file->refcount--;
|
file->refcount--;
|
||||||
|
eina_lock_release(&file->lock);
|
||||||
|
|
||||||
if (file->refcount != 0) return ;
|
if (file->refcount != 0) return ;
|
||||||
|
|
||||||
if (file->delete_me)
|
if (file->delete_me)
|
||||||
{
|
{
|
||||||
_eina_file_cache_delete = eina_list_remove(_eina_file_cache_delete, file);
|
_eina_file_cache_delete = eina_list_remove(_eina_file_cache_delete,
|
||||||
|
file);
|
||||||
_eina_file_real_close(file);
|
_eina_file_real_close(file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -877,6 +895,7 @@ EAPI void *
|
||||||
eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
|
eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
|
||||||
{
|
{
|
||||||
int flags = MAP_SHARED;
|
int flags = MAP_SHARED;
|
||||||
|
void *ret = NULL;
|
||||||
|
|
||||||
// bsd people will lack this feature
|
// bsd people will lack this feature
|
||||||
#ifdef MAP_POPULATE
|
#ifdef MAP_POPULATE
|
||||||
|
@ -886,6 +905,7 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
|
||||||
if (file->length > EINA_HUGE_PAGE) flags |= MAP_HUGETLB;
|
if (file->length > EINA_HUGE_PAGE) flags |= MAP_HUGETLB;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
eina_lock_take(&file->lock);
|
||||||
if (file->global_map == MAP_FAILED)
|
if (file->global_map == MAP_FAILED)
|
||||||
file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0);
|
file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0);
|
||||||
|
|
||||||
|
@ -893,9 +913,11 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
|
||||||
{
|
{
|
||||||
_eina_file_map_rule_apply(rule, file->global_map, file->length);
|
_eina_file_map_rule_apply(rule, file->global_map, file->length);
|
||||||
file->global_refcount++;
|
file->global_refcount++;
|
||||||
return file->global_map;
|
ret = file->global_map;
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
eina_lock_release(&file->lock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void *
|
EAPI void *
|
||||||
|
@ -916,6 +938,8 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
||||||
key[0] = offset;
|
key[0] = offset;
|
||||||
key[1] = length;
|
key[1] = length;
|
||||||
|
|
||||||
|
eina_lock_take(&file->lock);
|
||||||
|
|
||||||
map = eina_hash_find(file->map, &key);
|
map = eina_hash_find(file->map, &key);
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
|
@ -930,18 +954,14 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
map = malloc(sizeof (Eina_File_Map));
|
map = malloc(sizeof (Eina_File_Map));
|
||||||
if (!map) return NULL;
|
if (!map) goto on_error;
|
||||||
|
|
||||||
map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset);
|
map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset);
|
||||||
map->offset = offset;
|
map->offset = offset;
|
||||||
map->length = length;
|
map->length = length;
|
||||||
map->refcount = 0;
|
map->refcount = 0;
|
||||||
|
|
||||||
if (map->map == MAP_FAILED)
|
if (map->map == MAP_FAILED) goto on_error;
|
||||||
{
|
|
||||||
free(map);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
eina_hash_add(file->map, &key, map);
|
eina_hash_add(file->map, &key, map);
|
||||||
eina_hash_direct_add(file->rmap, map->map, map);
|
eina_hash_direct_add(file->rmap, map->map, map);
|
||||||
|
@ -951,17 +971,27 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
||||||
|
|
||||||
_eina_file_map_rule_apply(rule, map->map, length);
|
_eina_file_map_rule_apply(rule, map->map, length);
|
||||||
|
|
||||||
|
eina_lock_release(&file->lock);
|
||||||
|
|
||||||
return map->map;
|
return map->map;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
free(map);
|
||||||
|
eina_lock_release(&file->lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_file_map_free(Eina_File *file, void *map)
|
eina_file_map_free(Eina_File *file, void *map)
|
||||||
{
|
{
|
||||||
|
eina_lock_take(&file->lock);
|
||||||
|
|
||||||
if (file->global_map == map)
|
if (file->global_map == map)
|
||||||
{
|
{
|
||||||
file->global_refcount--;
|
file->global_refcount--;
|
||||||
|
|
||||||
if (file->global_refcount > 0) return ;
|
if (file->global_refcount > 0) goto on_exit;
|
||||||
|
|
||||||
munmap(file->global_map, file->length);
|
munmap(file->global_map, file->length);
|
||||||
file->global_map = MAP_FAILED;
|
file->global_map = MAP_FAILED;
|
||||||
|
@ -976,7 +1006,7 @@ eina_file_map_free(Eina_File *file, void *map)
|
||||||
|
|
||||||
em->refcount--;
|
em->refcount--;
|
||||||
|
|
||||||
if (em->refcount > 0) return ;
|
if (em->refcount > 0) goto on_exit;
|
||||||
|
|
||||||
key[0] = em->offset;
|
key[0] = em->offset;
|
||||||
key[1] = em->length;
|
key[1] = em->length;
|
||||||
|
@ -984,6 +1014,9 @@ eina_file_map_free(Eina_File *file, void *map)
|
||||||
eina_hash_del(file->rmap, &map, em);
|
eina_hash_del(file->rmap, &map, em);
|
||||||
eina_hash_del(file->map, &key, em);
|
eina_hash_del(file->map, &key, em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on_exit:
|
||||||
|
eina_lock_release(&file->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue