summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS3
-rw-r--r--src/lib/eina/eina_file.c9
-rw-r--r--src/lib/eina/eina_file_common.c15
-rw-r--r--src/lib/eina/eina_file_common.h3
-rw-r--r--src/lib/eina/eina_file_win32.c7
-rw-r--r--src/tests/eina/eina_test_file.c34
7 files changed, 16 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c3dea3a93..3dc7c28258 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,3 @@
12013-11-20 Cedric Bail
2
3 * Eina: Fix a possible race condition during eina_file_close.
4
52013-11-19 Tom Hacohen 12013-11-19 Tom Hacohen
6 2
7 * Evas textblock: Fixed order of tags inserted with markup_app/prepend. 3 * Evas textblock: Fixed order of tags inserted with markup_app/prepend.
diff --git a/NEWS b/NEWS
index 5ce9bcf17b..6a1f8bdb01 100644
--- a/NEWS
+++ b/NEWS
@@ -268,8 +268,7 @@ Fixes:
268 - Fix memory leak in eina_xattr_value_ls. 268 - Fix memory leak in eina_xattr_value_ls.
269 - Fix magic failure in eina_value_array_count when array has not been allocated. 269 - Fix magic failure in eina_value_array_count when array has not been allocated.
270 - Fix issue when wchar_t is signed and eina_unicode does negative array lookups. 270 - Fix issue when wchar_t is signed and eina_unicode does negative array lookups.
271 - Fix eina_file_map_lines() to not drop of one character in the last line. 271 - Eina: fix eina_file_map_lines() to not drop of one character in the last line.
272 - Fix a possible race condition during eina_file_close().
273 * Eet: 272 * Eet:
274 - Fix PPC (big endian) image codec bug. 273 - Fix PPC (big endian) image codec bug.
275 - Fix leak in eet_pbkdf2_sha1 with OpenSSL. 274 - Fix leak in eet_pbkdf2_sha1 with OpenSSL.
diff --git a/src/lib/eina/eina_file.c b/src/lib/eina/eina_file.c
index 8ae5a0f4ed..6d7ee56f54 100644
--- a/src/lib/eina/eina_file.c
+++ b/src/lib/eina/eina_file.c
@@ -305,6 +305,11 @@ eina_file_real_close(Eina_File *file)
305{ 305{
306 Eina_File_Map *map; 306 Eina_File_Map *map;
307 307
308 if (file->refcount != 0) return;
309
310 eina_hash_free(file->rmap);
311 eina_hash_free(file->map);
312
308 EINA_LIST_FREE(file->dead_map, map) 313 EINA_LIST_FREE(file->dead_map, map)
309 { 314 {
310 munmap(map->map, map->length); 315 munmap(map->map, map->length);
@@ -315,6 +320,8 @@ eina_file_real_close(Eina_File *file)
315 munmap(file->global_map, file->length); 320 munmap(file->global_map, file->length);
316 321
317 if (file->fd != -1) close(file->fd); 322 if (file->fd != -1) close(file->fd);
323
324 free(file);
318} 325}
319 326
320static void 327static void
@@ -905,8 +912,6 @@ eina_file_open(const char *path, Eina_Bool shared)
905 n->shared = shared; 912 n->shared = shared;
906 eina_lock_new(&n->lock); 913 eina_lock_new(&n->lock);
907 eina_hash_direct_add(_eina_file_cache, n->filename, n); 914 eina_hash_direct_add(_eina_file_cache, n->filename, n);
908
909 EINA_MAGIC_SET(n, EINA_FILE_MAGIC);
910 } 915 }
911 else 916 else
912 { 917 {
diff --git a/src/lib/eina/eina_file_common.c b/src/lib/eina/eina_file_common.c
index f5724d70bf..7b05b3b249 100644
--- a/src/lib/eina/eina_file_common.c
+++ b/src/lib/eina/eina_file_common.c
@@ -451,26 +451,17 @@ eina_file_close(Eina_File *file)
451 451
452 EINA_SAFETY_ON_NULL_RETURN(file); 452 EINA_SAFETY_ON_NULL_RETURN(file);
453 453
454 eina_lock_take(&_eina_file_lock_cache);
455
456 eina_lock_take(&file->lock); 454 eina_lock_take(&file->lock);
457 file->refcount--; 455 file->refcount--;
458 if (file->refcount == 0) leave = EINA_FALSE; 456 if (file->refcount == 0) leave = EINA_FALSE;
459 eina_lock_release(&file->lock); 457 eina_lock_release(&file->lock);
460 if (leave) goto end; 458 if (leave) return;
461 459
462 eina_hash_del(_eina_file_cache, file->filename, file); 460 eina_lock_take(&_eina_file_lock_cache);
463 461
464 // Backend specific file resource close 462 eina_hash_del(_eina_file_cache, file->filename, file);
465 eina_file_real_close(file); 463 eina_file_real_close(file);
466 464
467 // Generic destruction of the file
468 eina_hash_free(file->rmap); file->rmap = NULL;
469 eina_hash_free(file->map); file->map = NULL;
470 EINA_MAGIC_SET(file, 0);
471 free(file);
472
473 end:
474 eina_lock_release(&_eina_file_lock_cache); 465 eina_lock_release(&_eina_file_lock_cache);
475} 466}
476 467
diff --git a/src/lib/eina/eina_file_common.h b/src/lib/eina/eina_file_common.h
index e3ee0fc553..0ac704d028 100644
--- a/src/lib/eina/eina_file_common.h
+++ b/src/lib/eina/eina_file_common.h
@@ -24,14 +24,11 @@
24#include "eina_lock.h" 24#include "eina_lock.h"
25#include "eina_list.h" 25#include "eina_list.h"
26 26
27#define EINA_FILE_MAGIC 0xFEEDBEEF
28
29typedef struct _Eina_File_Map Eina_File_Map; 27typedef struct _Eina_File_Map Eina_File_Map;
30typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator; 28typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator;
31 29
32struct _Eina_File 30struct _Eina_File
33{ 31{
34 EINA_MAGIC;
35 const char *filename; 32 const char *filename;
36 33
37 Eina_Hash *map; 34 Eina_Hash *map;
diff --git a/src/lib/eina/eina_file_win32.c b/src/lib/eina/eina_file_win32.c
index 8290501869..cddf2da81a 100644
--- a/src/lib/eina/eina_file_win32.c
+++ b/src/lib/eina/eina_file_win32.c
@@ -366,6 +366,9 @@ eina_file_real_close(Eina_File *file)
366{ 366{
367 Eina_File_Map *map; 367 Eina_File_Map *map;
368 368
369 eina_hash_free(file->rmap);
370 eina_hash_free(file->map);
371
369 EINA_LIST_FREE(file->dead_map, map) 372 EINA_LIST_FREE(file->dead_map, map)
370 { 373 {
371 UnmapViewOfFile(map->map); 374 UnmapViewOfFile(map->map);
@@ -377,6 +380,8 @@ eina_file_real_close(Eina_File *file)
377 380
378 if (file->fm) CloseHandle(file->fm); 381 if (file->fm) CloseHandle(file->fm);
379 if (file->handle) CloseHandle(file->handle); 382 if (file->handle) CloseHandle(file->handle);
383
384 free(file);
380} 385}
381 386
382static void 387static void
@@ -832,8 +837,6 @@ eina_file_open(const char *path, Eina_Bool shared)
832 n->shared = shared; 837 n->shared = shared;
833 eina_lock_new(&n->lock); 838 eina_lock_new(&n->lock);
834 eina_hash_direct_add(_eina_file_cache, n->filename, n); 839 eina_hash_direct_add(_eina_file_cache, n->filename, n);
835
836 EINA_MAGIC_SET(n, EINA_FILE_MAGIC);
837 } 840 }
838 else 841 else
839 { 842 {
diff --git a/src/tests/eina/eina_test_file.c b/src/tests/eina/eina_test_file.c
index e8f735d3f0..f2f322550f 100644
--- a/src/tests/eina/eina_test_file.c
+++ b/src/tests/eina/eina_test_file.c
@@ -441,39 +441,6 @@ START_TEST(eina_test_file_virtualize)
441} 441}
442END_TEST 442END_TEST
443 443
444static void *
445_eina_test_file_thread(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
446{
447 Eina_File *f;
448 unsigned int i;
449
450 for (i = 0; i < 10000; ++i)
451 {
452 f = eina_file_open("/bin/sh", EINA_FALSE);
453 fail_if(!f);
454 eina_file_close(f);
455 }
456
457 return NULL;
458}
459
460START_TEST(eina_test_file_thread)
461{
462 Eina_Thread th[4];
463 unsigned int i;
464
465 fail_if(!eina_init());
466
467 for (i = 0; i < 4; i++)
468 fail_if(!(eina_thread_create(&th[i], EINA_THREAD_NORMAL, 0, _eina_test_file_thread, NULL)));
469
470 for (i = 0; i < 4; i++)
471 fail_if(eina_thread_join(th[i]) != NULL);
472
473 eina_shutdown();
474}
475END_TEST
476
477void 444void
478eina_test_file(TCase *tc) 445eina_test_file(TCase *tc)
479{ 446{
@@ -482,6 +449,5 @@ eina_test_file(TCase *tc)
482 tcase_add_test(tc, eina_file_ls_simple); 449 tcase_add_test(tc, eina_file_ls_simple);
483 tcase_add_test(tc, eina_file_map_new_test); 450 tcase_add_test(tc, eina_file_map_new_test);
484 tcase_add_test(tc, eina_test_file_virtualize); 451 tcase_add_test(tc, eina_test_file_virtualize);
485 tcase_add_test(tc, eina_test_file_thread);
486} 452}
487 453