summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric Bail <cedric.bail@samsung.com>2013-11-21 14:58:32 +0900
committerCedric Bail <cedric.bail@samsung.com>2013-11-21 14:58:32 +0900
commitba420c60474c23bfc0d59b07f9e4d0710ebcfa86 (patch)
tree0c6ec3872cfd94705c099c9b7a4debf48b0571b0
parent40d86ae6440c3c32abce55181147a92df69b1925 (diff)
downloadeina-ba420c60474c23bfc0d59b07f9e4d0710ebcfa86.tar.gz
eina: backport fix for race condition in Eina_File infrastructure.
-rw-r--r--ChangeLog5
-rw-r--r--NEWS9
-rw-r--r--src/lib/eina_file.c14
3 files changed, 23 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 8970c02..bfefe9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -434,3 +434,8 @@
2013-09-10 Eduardo Lima (Etrunko)
* 1.7.9 release
+
+2013-11-21 Cedric Bail
+
+ * Fix race condition when calling eina_file_open/eina_file_close.
+
diff --git a/NEWS b/NEWS
index 9aad8db..fb8dc75 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+Eina 1.7.10
+
+Changes since Eina 1.7.9:
+-------------------------
+
+Fixes:
+ * Fix race condition when calling eina_file_open/eina_file_close.
+
+
Eina 1.7.9
Changes since Eina 1.7.8:
diff --git a/src/lib/eina_file.c b/src/lib/eina_file.c
index 68a6cce..7fe6bb0 100644
--- a/src/lib/eina_file.c
+++ b/src/lib/eina_file.c
@@ -988,7 +988,6 @@ eina_file_open(const char *path, Eina_Bool shared)
{
file->delete_me = EINA_TRUE;
eina_hash_del(_eina_file_cache, file->filename, file);
- _eina_file_real_close(file);
file = NULL;
}
@@ -1050,18 +1049,23 @@ eina_file_open(const char *path, Eina_Bool shared)
EAPI void
eina_file_close(Eina_File *file)
{
+ Eina_Bool leave = EINA_TRUE;
+
EINA_SAFETY_ON_NULL_RETURN(file);
+ eina_lock_take(&_eina_file_lock_cache);
+
eina_lock_take(&file->lock);
file->refcount--;
+ if (file->refcount == 0) leave = EINA_FALSE;
eina_lock_release(&file->lock);
+ if (leave) goto end;
- if (file->refcount != 0) return;
- eina_lock_take(&_eina_file_lock_cache);
-
- eina_hash_del(_eina_file_cache, file->filename, file);
+ if (eina_hash_find(_eina_file_cache, file->filename) == file)
+ eina_hash_del(_eina_file_cache, file->filename, file);
_eina_file_real_close(file);
+ end:
eina_lock_release(&_eina_file_lock_cache);
}