summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS1
-rw-r--r--src/lib/eina/eina_file.c43
-rw-r--r--src/lib/eina/eina_file.h26
-rw-r--r--src/lib/eina/eina_file_common.c173
-rw-r--r--src/lib/eina/eina_file_common.h13
-rw-r--r--src/lib/eina/eina_file_win32.c37
7 files changed, 245 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c4c2b40f5..2e2d23460f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
12013-07-31 Cedric Bail
2
3 * Eina: add eina_file_virtualize() and eina_file_virtual().
4
12013-07-25 ChunEon Park (Hermet) 52013-07-25 ChunEon Park (Hermet)
2 6
3 * Evas: Skip the map rendering if all points are transparent. 7 * Evas: Skip the map rendering if all points are transparent.
diff --git a/NEWS b/NEWS
index 8df3505ecf..0bacd4e705 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,7 @@ Additions:
34 - Add eina_tiler_area_size_set(), eina_tiler_strict_set(), eina_tiler_area_size_get() 34 - Add eina_tiler_area_size_set(), eina_tiler_strict_set(), eina_tiler_area_size_get()
35 - Add eina_file_map_populate() 35 - Add eina_file_map_populate()
36 - Add eina_tiler_empty() 36 - Add eina_tiler_empty()
37 - Add eina_file_virtualize() and eina_file_virtual()
37 * Eet: 38 * Eet:
38 - Add eet_mmap() 39 - Add eet_mmap()
39 - Add eet_data_descriptor_name_get() 40 - Add eet_data_descriptor_name_get()
diff --git a/src/lib/eina/eina_file.c b/src/lib/eina/eina_file.c
index 6cc1e3835d..32ae4ea2fa 100644
--- a/src/lib/eina/eina_file.c
+++ b/src/lib/eina/eina_file.c
@@ -324,27 +324,6 @@ _eina_file_map_close(Eina_File_Map *map)
324 free(map); 324 free(map);
325} 325}
326 326
327static unsigned int
328_eina_file_map_key_length(const void *key EINA_UNUSED)
329{
330 return sizeof (unsigned long int) * 2;
331}
332
333static int
334_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length EINA_UNUSED,
335 const unsigned long int *key2, int key2_length EINA_UNUSED)
336{
337 if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
338 return key1[0] - key2[0];
339}
340
341static int
342_eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED)
343{
344 return eina_hash_int64(&key[0], sizeof (unsigned long int))
345 ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
346}
347
348#ifndef MAP_POPULATE 327#ifndef MAP_POPULATE
349static unsigned int 328static unsigned int
350_eina_file_map_populate(char *map, unsigned int size, Eina_Bool hugetlb) 329_eina_file_map_populate(char *map, unsigned int size, Eina_Bool hugetlb)
@@ -880,9 +859,9 @@ eina_file_open(const char *path, Eina_Bool shared)
880 memset(n, 0, sizeof(Eina_File)); 859 memset(n, 0, sizeof(Eina_File));
881 n->filename = (char*) (n + 1); 860 n->filename = (char*) (n + 1);
882 strcpy((char*) n->filename, filename); 861 strcpy((char*) n->filename, filename);
883 n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length), 862 n->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
884 EINA_KEY_CMP(_eina_file_map_key_cmp), 863 EINA_KEY_CMP(eina_file_map_key_cmp),
885 EINA_KEY_HASH(_eina_file_map_key_hash), 864 EINA_KEY_HASH(eina_file_map_key_hash),
886 EINA_FREE_CB(_eina_file_map_close), 865 EINA_FREE_CB(_eina_file_map_close),
887 3); 866 3);
888 n->rmap = eina_hash_pointer_new(NULL); 867 n->rmap = eina_hash_pointer_new(NULL);
@@ -931,7 +910,9 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
931 910
932 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 911 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
933 912
934// bsd people will lack this feature 913 if (file->virtual) return eina_file_virtual_map_all(file);
914
915 // bsd people will lack this feature
935#ifdef MAP_POPULATE 916#ifdef MAP_POPULATE
936 if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE; 917 if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
937#endif 918#endif
@@ -984,6 +965,9 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
984 if (offset == 0 && length == file->length) 965 if (offset == 0 && length == file->length)
985 return eina_file_map_all(file, rule); 966 return eina_file_map_all(file, rule);
986 967
968 if (file->virtual)
969 return eina_file_virtual_map_new(file, offset, length);
970
987 key[0] = offset; 971 key[0] = offset;
988 key[1] = length; 972 key[1] = length;
989 973
@@ -1048,6 +1032,9 @@ eina_file_map_free(Eina_File *file, void *map)
1048{ 1032{
1049 EINA_SAFETY_ON_NULL_RETURN(file); 1033 EINA_SAFETY_ON_NULL_RETURN(file);
1050 1034
1035 if (file->virtual)
1036 return eina_file_virtual_map_free(file, map);
1037
1051 eina_lock_take(&file->lock); 1038 eina_lock_take(&file->lock);
1052 1039
1053 if (file->global_map == map) 1040 if (file->global_map == map)
@@ -1104,6 +1091,8 @@ eina_file_map_faulted(Eina_File *file, void *map)
1104 1091
1105 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); 1092 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
1106 1093
1094 if (file->virtual) return EINA_FALSE;
1095
1107 eina_lock_take(&file->lock); 1096 eina_lock_take(&file->lock);
1108 1097
1109 if (file->global_map == map) 1098 if (file->global_map == map)
@@ -1126,6 +1115,8 @@ eina_file_xattr_get(Eina_File *file)
1126{ 1115{
1127 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 1116 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1128 1117
1118 if (file->virtual) return NULL;
1119
1129 return eina_xattr_fd_ls(file->fd); 1120 return eina_xattr_fd_ls(file->fd);
1130} 1121}
1131 1122
@@ -1134,6 +1125,8 @@ eina_file_xattr_value_get(Eina_File *file)
1134{ 1125{
1135 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 1126 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1136 1127
1128 if (file->virtual) return NULL;
1129
1137 return eina_xattr_value_fd_ls(file->fd); 1130 return eina_xattr_value_fd_ls(file->fd);
1138} 1131}
1139 1132
diff --git a/src/lib/eina/eina_file.h b/src/lib/eina/eina_file.h
index 265f4bd648..36aac586e4 100644
--- a/src/lib/eina/eina_file.h
+++ b/src/lib/eina/eina_file.h
@@ -444,8 +444,6 @@ typedef enum {
444 */ 444 */
445EAPI Eina_Bool eina_file_copy(const char *src, const char *dst, Eina_File_Copy_Flags flags, Eina_File_Copy_Progress cb, const void *cb_data) EINA_ARG_NONNULL(1, 2); 445EAPI Eina_Bool eina_file_copy(const char *src, const char *dst, Eina_File_Copy_Flags flags, Eina_File_Copy_Progress cb, const void *cb_data) EINA_ARG_NONNULL(1, 2);
446 446
447
448
449/** 447/**
450 * @brief Get a read-only handler to a file. 448 * @brief Get a read-only handler to a file.
451 * 449 *
@@ -462,6 +460,30 @@ EAPI Eina_Bool eina_file_copy(const char *src, const char *dst, Eina_File_Copy_F
462EAPI Eina_File *eina_file_open(const char *name, Eina_Bool shared) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; 460EAPI Eina_File *eina_file_open(const char *name, Eina_Bool shared) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
463 461
464/** 462/**
463 * @brief Create a virtual file from a memory pointer.
464 *
465 * @param data The memory pointer to take data from
466 * @param length The length of the data in memory
467 * @param copy #EINA_TRUE if the data must be copied
468 * @return Eina_File handle to the file
469 *
470 * @since 1.8
471 */
472EAPI Eina_File *
473eina_file_virtualize(const void *data, unsigned long long length, Eina_Bool copy) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
474
475/**
476 * @brief Tell if a file is a real file or only exist in memory
477 *
478 * @param file The file to test
479 * @return #EINA_TRUE if the file is a virtual file
480 *
481 * @since 1.8
482 */
483EAPI Eina_Bool
484eina_file_virtual(Eina_File *file) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
485
486/**
465 * @brief Dup a read-only handler of a previously open file. 487 * @brief Dup a read-only handler of a previously open file.
466 * 488 *
467 * @param file To duplicate a reference to 489 * @param file To duplicate a reference to
diff --git a/src/lib/eina/eina_file_common.c b/src/lib/eina/eina_file_common.c
index f52b39fc3d..75c92564dd 100644
--- a/src/lib/eina/eina_file_common.c
+++ b/src/lib/eina/eina_file_common.c
@@ -129,6 +129,116 @@ _eina_file_escape(char *path, size_t len)
129 return result; 129 return result;
130} 130}
131 131
132
133unsigned int
134eina_file_map_key_length(const void *key EINA_UNUSED)
135{
136 return sizeof (unsigned long int) * 2;
137}
138
139int
140eina_file_map_key_cmp(const unsigned long int *key1, int key1_length EINA_UNUSED,
141 const unsigned long int *key2, int key2_length EINA_UNUSED)
142{
143 if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
144 return key1[0] - key2[0];
145}
146
147int
148eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED)
149{
150 return eina_hash_int64(&key[0], sizeof (unsigned long int))
151 ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
152}
153
154void *
155eina_file_virtual_map_all(Eina_File *file)
156{
157 eina_lock_take(&file->lock);
158 file->global_refcount++;
159 eina_lock_release(&file->lock);
160
161 return file->global_map;
162}
163
164void *
165eina_file_virtual_map_new(Eina_File *file,
166 unsigned long int offset, unsigned long int length)
167{
168 Eina_File_Map *map;
169 unsigned long int key[2];
170
171 // offset and length has already been checked by the caller function
172
173 key[0] = offset;
174 key[1] = length;
175
176 eina_lock_take(&file->lock);
177
178 map = eina_hash_find(file->map, &key);
179 if (!map)
180 {
181 map = malloc(sizeof (Eina_File_Map));
182 goto on_error;
183
184 map->map = ((char*) file->global_map) + offset;
185 map->offset = offset;
186 map->length = length;
187 map->refcount = 0;
188
189 eina_hash_add(file->map, &key, map);
190 eina_hash_direct_add(file->rmap, map->map, map);
191 }
192
193 map->refcount++;
194
195 on_error:
196 eina_lock_release(&file->lock);
197 return map ? map->map : NULL;
198}
199
200void
201eina_file_virtual_map_free(Eina_File *file, void *map)
202{
203 Eina_File_Map *em;
204
205 eina_lock_take(&file->lock);
206
207 // map could equal global_map even if length != file->length
208 em = eina_hash_find(file->rmap, &map);
209 if (em)
210 {
211 unsigned long int key[2];
212
213 em->refcount--;
214
215 if (em->refcount > 0) goto on_exit;
216
217 key[0] = em->offset;
218 key[1] = em->length;
219
220 eina_hash_del(file->rmap, &map, em);
221 eina_hash_del(file->map, &key, em);
222 }
223 else
224 {
225 if (file->global_map == map)
226 {
227 file->global_refcount--;
228 }
229 }
230
231 on_exit:
232 eina_lock_release(&file->lock);
233}
234
235// Private to this file API
236static void
237_eina_file_map_close(Eina_File_Map *map)
238{
239 free(map);
240}
241
132// Global API 242// Global API
133 243
134EAPI char * 244EAPI char *
@@ -153,9 +263,70 @@ eina_file_path_sanitize(const char *path)
153} 263}
154 264
155EAPI Eina_File * 265EAPI Eina_File *
266eina_file_virtualize(const void *data, unsigned long long length, Eina_Bool copy)
267{
268 Eina_File *file;
269 Eina_Nano_Time tp;
270 long int ti;
271 const char *tmpname = "/dev/mem/virtual\\/%16x";
272
273 // Generate an almost uniq filename based on current nsec time.
274 if (_eina_time_get(&tp)) return NULL;
275 ti = _eina_time_convert(&tp);
276
277 file = malloc(sizeof (Eina_File) +
278 strlen(tmpname) + 17 +
279 (copy ? length : 0));
280 if (!file) return NULL;
281
282 memset(file, 0, sizeof(Eina_File));
283 file->filename = (char*) (file + 1);
284 sprintf((char*) file->filename, tmpname, ti);
285
286 eina_lock_new(&file->lock);
287 file->mtime = ti / 1000;
288 file->length = length;
289 file->mtime_nsec = ti;
290 file->refcount = 1;
291 file->fd = -1;
292 file->virtual = EINA_TRUE;
293 file->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
294 EINA_KEY_CMP(eina_file_map_key_cmp),
295 EINA_KEY_HASH(eina_file_map_key_hash),
296 EINA_FREE_CB(_eina_file_map_close),
297 3);
298 file->rmap = eina_hash_pointer_new(NULL);
299
300 if (copy)
301 {
302 file->global_map = (void*)(file->filename +
303 strlen(file->filename) + 1);
304 memcpy((char*) file->global_map, data, length);
305 }
306 else
307 {
308 file->global_map = (void*) data;
309 }
310
311 return file;
312}
313
314EAPI Eina_Bool
315eina_file_virtual(Eina_File *file)
316{
317 if (file) return file->virtual;
318 return EINA_FALSE;
319}
320
321EAPI Eina_File *
156eina_file_dup(Eina_File *file) 322eina_file_dup(Eina_File *file)
157{ 323{
158 if (file) file->refcount++; 324 if (file)
325 {
326 eina_lock_take(&file->lock);
327 file->refcount++;
328 eina_lock_release(&file->lock);
329 }
159 return file; 330 return file;
160} 331}
161 332
diff --git a/src/lib/eina/eina_file_common.h b/src/lib/eina/eina_file_common.h
index 3d56f7bbee..31f6b6d306 100644
--- a/src/lib/eina/eina_file_common.h
+++ b/src/lib/eina/eina_file_common.h
@@ -61,6 +61,7 @@ struct _Eina_File
61 Eina_Bool shared : 1; 61 Eina_Bool shared : 1;
62 Eina_Bool delete_me : 1; 62 Eina_Bool delete_me : 1;
63 Eina_Bool global_faulty : 1; 63 Eina_Bool global_faulty : 1;
64 Eina_Bool virtual : 1;
64}; 65};
65 66
66struct _Eina_File_Map 67struct _Eina_File_Map
@@ -123,4 +124,16 @@ extern Eina_Hash *_eina_file_cache;
123extern Eina_Lock _eina_file_lock_cache; 124extern Eina_Lock _eina_file_lock_cache;
124extern int _eina_file_log_dom; 125extern int _eina_file_log_dom;
125 126
127// Common function to handle virtual file
128void *eina_file_virtual_map_all(Eina_File *file);
129void *eina_file_virtual_map_new(Eina_File *file,
130 unsigned long int offset, unsigned long int length);
131void eina_file_virtual_map_free(Eina_File *file, void *map);
132
133// Common hash function
134unsigned int eina_file_map_key_length(const void *key);
135int eina_file_map_key_cmp(const unsigned long int *key1, int key1_length,
136 const unsigned long int *key2, int key2_length);
137int eina_file_map_key_hash(const unsigned long int *key, int key_length);
138
126#endif /* EINA_FILE_COMMON_H_ */ 139#endif /* EINA_FILE_COMMON_H_ */
diff --git a/src/lib/eina/eina_file_win32.c b/src/lib/eina/eina_file_win32.c
index e795f60c1d..d96720bbd2 100644
--- a/src/lib/eina/eina_file_win32.c
+++ b/src/lib/eina/eina_file_win32.c
@@ -384,27 +384,6 @@ _eina_file_map_close(Eina_File_Map *map)
384 free(map); 384 free(map);
385} 385}
386 386
387static unsigned int
388_eina_file_map_key_length(const void *key EINA_UNUSED)
389{
390 return sizeof (unsigned long int) * 2;
391}
392
393static int
394_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length EINA_UNUSED,
395 const unsigned long int *key2, int key2_length EINA_UNUSED)
396{
397 if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
398 return key1[0] - key2[0];
399}
400
401static int
402_eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED)
403{
404 return eina_hash_int64(&key[0], sizeof (unsigned long int))
405 ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
406}
407
408/** 387/**
409 * @endcond 388 * @endcond
410 */ 389 */
@@ -804,9 +783,9 @@ eina_file_open(const char *path, Eina_Bool shared)
804 memset(n, 0, sizeof(Eina_File)); 783 memset(n, 0, sizeof(Eina_File));
805 n->filename = (char*) (n + 1); 784 n->filename = (char*) (n + 1);
806 strcpy((char*) n->filename, filename); 785 strcpy((char*) n->filename, filename);
807 n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length), 786 n->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
808 EINA_KEY_CMP(_eina_file_map_key_cmp), 787 EINA_KEY_CMP(eina_file_map_key_cmp),
809 EINA_KEY_HASH(_eina_file_map_key_hash), 788 EINA_KEY_HASH(eina_file_map_key_hash),
810 EINA_FREE_CB(_eina_file_map_close), 789 EINA_FREE_CB(_eina_file_map_close),
811 3); 790 3);
812 n->rmap = eina_hash_pointer_new(NULL); 791 n->rmap = eina_hash_pointer_new(NULL);
@@ -859,6 +838,8 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule EINA_UNUSED)
859{ 838{
860 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 839 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
861 840
841 if (file->virtual) return eina_file_virtual_map_all(file);
842
862 eina_lock_take(&file->lock); 843 eina_lock_take(&file->lock);
863 if (file->global_map == MAP_FAILED) 844 if (file->global_map == MAP_FAILED)
864 { 845 {
@@ -875,6 +856,7 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule EINA_UNUSED)
875 if (file->global_map != MAP_FAILED) 856 if (file->global_map != MAP_FAILED)
876 { 857 {
877 file->global_refcount++; 858 file->global_refcount++;
859 eina_lock_release(&file->lock);
878 return file->global_map; 860 return file->global_map;
879 } 861 }
880 862
@@ -899,6 +881,9 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
899 if (offset == 0 && length == file->length) 881 if (offset == 0 && length == file->length)
900 return eina_file_map_all(file, rule); 882 return eina_file_map_all(file, rule);
901 883
884 if (file->virtual)
885 return eina_file_virtual_map_new(file, offset, length);
886
902 key[0] = offset; 887 key[0] = offset;
903 key[1] = length; 888 key[1] = length;
904 889
@@ -952,6 +937,9 @@ eina_file_map_free(Eina_File *file, void *map)
952{ 937{
953 EINA_SAFETY_ON_NULL_RETURN(file); 938 EINA_SAFETY_ON_NULL_RETURN(file);
954 939
940 if (file->virtual)
941 return eina_file_virtual_map_free(file, map);
942
955 eina_lock_take(&file->lock); 943 eina_lock_take(&file->lock);
956 944
957 if (file->global_map == map) 945 if (file->global_map == map)
@@ -989,6 +977,7 @@ eina_file_map_free(Eina_File *file, void *map)
989EAPI Eina_Bool 977EAPI Eina_Bool
990eina_file_map_faulted(Eina_File *file, void *map) 978eina_file_map_faulted(Eina_File *file, void *map)
991{ 979{
980 if (file->virtual) return EINA_FALSE;
992 /* 981 /*
993 * FIXME: 982 * FIXME:
994 * vc++ : http://msdn.microsoft.com/en-us/library/windows/desktop/aa366801%28v=vs.85%29.aspx 983 * vc++ : http://msdn.microsoft.com/en-us/library/windows/desktop/aa366801%28v=vs.85%29.aspx