summaryrefslogtreecommitdiff
path: root/legacy
diff options
context:
space:
mode:
authorCarsten Haitzler <raster@rasterman.com>2010-03-07 03:01:55 +0000
committerCarsten Haitzler <raster@rasterman.com>2010-03-07 03:01:55 +0000
commit73a9612f2c320cc6779da7ab3063f89cdf920169 (patch)
tree60d368665b692b82219e176e554c1d56d2c33cbc /legacy
parent329628e8e7bb4bc9496058cb55bd3f0876cf92c1 (diff)
also revert - on3e of these 2 - or both, causes a deadlock in e. see my
previous commit log. SVN revision: 46918
Diffstat (limited to 'legacy')
-rw-r--r--legacy/eet/AUTHORS1
-rw-r--r--legacy/eet/ChangeLog4
-rw-r--r--legacy/eet/src/lib/eet_lib.c63
-rw-r--r--legacy/eet/src/tests/eet_suite.c64
4 files changed, 21 insertions, 111 deletions
diff --git a/legacy/eet/AUTHORS b/legacy/eet/AUTHORS
index d1172a0e26..cd5fc41184 100644
--- a/legacy/eet/AUTHORS
+++ b/legacy/eet/AUTHORS
@@ -9,4 +9,3 @@ Gustavo Sverzut Barbieri <barbieri@gmail.com>
9Raphael Kubo da Costa <kubo@profusion.mobi> 9Raphael Kubo da Costa <kubo@profusion.mobi>
10Mathieu Taillefumier <mathieu.taillefumier@free.fr> 10Mathieu Taillefumier <mathieu.taillefumier@free.fr>
11Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com> 11Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com>
12Adam Simpkins <adam@adamsimpkins.net>
diff --git a/legacy/eet/ChangeLog b/legacy/eet/ChangeLog
index 093d030808..f71ff865c8 100644
--- a/legacy/eet/ChangeLog
+++ b/legacy/eet/ChangeLog
@@ -337,7 +337,3 @@
3372010-03-01 Albin Tonnerre 3372010-03-01 Albin Tonnerre
338 338
339 * Fix override of global symbols. 339 * Fix override of global symbols.
340
3412010-03-05 Adam Simpkins
342
343 * Fix clearcache race condition.
diff --git a/legacy/eet/src/lib/eet_lib.c b/legacy/eet/src/lib/eet_lib.c
index 4ed8432f60..8fed189666 100644
--- a/legacy/eet/src/lib/eet_lib.c
+++ b/legacy/eet/src/lib/eet_lib.c
@@ -280,7 +280,7 @@ eet_test_close(int test, Eet_File *ef)
280 if (test) 280 if (test)
281 { 281 {
282 ef->delete_me_now = 1; 282 ef->delete_me_now = 1;
283 eet_internal_close(ef, 1); 283 eet_internal_close(ef, 0);
284 } 284 }
285 return test; 285 return test;
286} 286}
@@ -307,7 +307,6 @@ eet_cache_find(const char *path, Eet_File **cache, int cache_num)
307} 307}
308 308
309/* add to end of cache */ 309/* add to end of cache */
310/* this should only be called when the cache lock is already held */
311static void 310static void
312eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc) 311eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc)
313{ 312{
@@ -359,7 +358,6 @@ eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc)
359} 358}
360 359
361/* delete from cache */ 360/* delete from cache */
362/* this should only be called when the cache lock is already held */
363static void 361static void
364eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc) 362eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc)
365{ 363{
@@ -851,7 +849,6 @@ eet_clearcache(void)
851 * We need to compute the list of eet file to close separately from the cache, 849 * We need to compute the list of eet file to close separately from the cache,
852 * due to eet_close removing them from the cache after each call. 850 * due to eet_close removing them from the cache after each call.
853 */ 851 */
854 LOCK_CACHE;
855 for (i = 0; i < eet_writers_num; i++) 852 for (i = 0; i < eet_writers_num; i++)
856 { 853 {
857 if (eet_writers[i]->references <= 0) num++; 854 if (eet_writers[i]->references <= 0) num++;
@@ -890,10 +887,9 @@ eet_clearcache(void)
890 887
891 for (i = 0; i < num; i++) 888 for (i = 0; i < num; i++)
892 { 889 {
893 eet_internal_close(closelist[i], 1); 890 eet_close(closelist[i]);
894 } 891 }
895 } 892 }
896 UNLOCK_CACHE;
897} 893}
898 894
899/* FIXME: MMAP race condition in READ_WRITE_MODE */ 895/* FIXME: MMAP race condition in READ_WRITE_MODE */
@@ -1285,12 +1281,6 @@ eet_internal_read1(Eet_File *ef)
1285} 1281}
1286#endif 1282#endif
1287 1283
1288/*
1289 * this should only be called when the cache lock is already held
1290 * (We could drop this restriction if we add a parameter to eet_test_close
1291 * that indicates if the lock is held or not. For now it is easiest
1292 * to just require that it is always held.)
1293 */
1294static Eet_File * 1284static Eet_File *
1295eet_internal_read(Eet_File *ef) 1285eet_internal_read(Eet_File *ef)
1296{ 1286{
@@ -1327,9 +1317,6 @@ eet_internal_close(Eet_File *ef, Eina_Bool locked)
1327 /* check to see its' an eet file pointer */ 1317 /* check to see its' an eet file pointer */
1328 if (eet_check_pointer(ef)) 1318 if (eet_check_pointer(ef))
1329 return EET_ERROR_BAD_OBJECT; 1319 return EET_ERROR_BAD_OBJECT;
1330
1331 if (!locked) LOCK_CACHE;
1332
1333 /* deref */ 1320 /* deref */
1334 ef->references--; 1321 ef->references--;
1335 /* if its still referenced - dont go any further */ 1322 /* if its still referenced - dont go any further */
@@ -1342,18 +1329,17 @@ eet_internal_close(Eet_File *ef, Eina_Bool locked)
1342 1329
1343 /* if not urgent to delete it - dont free it - leave it in cache */ 1330 /* if not urgent to delete it - dont free it - leave it in cache */
1344 if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ)) 1331 if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ))
1345 { 1332 return EET_ERROR_NONE;
1346 if (!locked) UNLOCK_CACHE;
1347 return EET_ERROR_NONE;
1348 }
1349 1333
1350 /* remove from cache */ 1334 /* remove from cache */
1335 if (!locked)
1336 {
1337 LOCK_CACHE;
1338 }
1351 if (ef->mode == EET_FILE_MODE_READ) 1339 if (ef->mode == EET_FILE_MODE_READ)
1352 eet_cache_del(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc); 1340 eet_cache_del(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
1353 else if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE)) 1341 else if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE))
1354 eet_cache_del(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc); 1342 eet_cache_del(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
1355
1356 /* we can unlock the cache now */
1357 if (!locked) 1343 if (!locked)
1358 { 1344 {
1359 UNLOCK_CACHE; 1345 UNLOCK_CACHE;
@@ -1439,11 +1425,7 @@ eet_memopen_read(const void *data, size_t size)
1439 ef->sha1 = NULL; 1425 ef->sha1 = NULL;
1440 ef->sha1_length = 0; 1426 ef->sha1_length = 0;
1441 1427
1442 /* eet_internal_read expects the cache lock to be held when it is called */ 1428 return eet_internal_read(ef);
1443 LOCK_CACHE;
1444 ef = eet_internal_read(ef);
1445 UNLOCK_CACHE;
1446 return ef;
1447} 1429}
1448 1430
1449EAPI Eet_File * 1431EAPI Eet_File *
@@ -1484,6 +1466,7 @@ eet_open(const char *file, Eet_File_Mode mode)
1484 } 1466 }
1485 ef = eet_cache_find((char *)file, eet_writers, eet_writers_num); 1467 ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
1486 } 1468 }
1469 UNLOCK_CACHE;
1487 1470
1488 /* try open the file based on mode */ 1471 /* try open the file based on mode */
1489 if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE)) 1472 if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
@@ -1492,23 +1475,23 @@ eet_open(const char *file, Eet_File_Mode mode)
1492 file_stat.st_mtime = 0; 1475 file_stat.st_mtime = 0;
1493 1476
1494 fp = fopen(file, "rb"); 1477 fp = fopen(file, "rb");
1495 if (!fp) goto open_error; 1478 if (!fp) goto on_error;
1496 if (fstat(fileno(fp), &file_stat)) 1479 if (fstat(fileno(fp), &file_stat))
1497 { 1480 {
1498 fclose(fp); 1481 fclose(fp);
1499 fp = NULL; 1482 fp = NULL;
1500 goto open_error; 1483 goto on_error;
1501 } 1484 }
1502 if ((mode == EET_FILE_MODE_READ) && 1485 if ((mode == EET_FILE_MODE_READ) &&
1503 (file_stat.st_size < ((int) sizeof(int) * 3))) 1486 (file_stat.st_size < ((int) sizeof(int) * 3)))
1504 { 1487 {
1505 fclose(fp); 1488 fclose(fp);
1506 fp = NULL; 1489 fp = NULL;
1507 goto open_error; 1490 goto on_error;
1508 } 1491 }
1509 1492
1510 open_error: 1493 on_error:
1511 if (fp == NULL && mode == EET_FILE_MODE_READ) goto on_error; 1494 if (fp == NULL && mode == EET_FILE_MODE_READ) return NULL;
1512 } 1495 }
1513 else 1496 else
1514 { 1497 {
@@ -1520,7 +1503,7 @@ eet_open(const char *file, Eet_File_Mode mode)
1520 unlink(file); 1503 unlink(file);
1521 fd = open(file, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); 1504 fd = open(file, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
1522 fp = fdopen(fd, "wb"); 1505 fp = fdopen(fd, "wb");
1523 if (!fp) goto on_error; 1506 if (!fp) return NULL;
1524 } 1507 }
1525 1508
1526 /* We found one */ 1509 /* We found one */
@@ -1537,7 +1520,6 @@ eet_open(const char *file, Eet_File_Mode mode)
1537 /* reference it up and return it */ 1520 /* reference it up and return it */
1538 if (fp != NULL) fclose(fp); 1521 if (fp != NULL) fclose(fp);
1539 ef->references++; 1522 ef->references++;
1540 UNLOCK_CACHE;
1541 return ef; 1523 return ef;
1542 } 1524 }
1543 1525
@@ -1546,7 +1528,7 @@ eet_open(const char *file, Eet_File_Mode mode)
1546 /* Allocate struct for eet file and have it zero'd out */ 1528 /* Allocate struct for eet file and have it zero'd out */
1547 ef = malloc(sizeof(Eet_File) + file_len); 1529 ef = malloc(sizeof(Eet_File) + file_len);
1548 if (!ef) 1530 if (!ef)
1549 goto on_error; 1531 return NULL;
1550 1532
1551 /* fill some of the members */ 1533 /* fill some of the members */
1552 INIT_FILE(ef); 1534 INIT_FILE(ef);
@@ -1575,7 +1557,7 @@ eet_open(const char *file, Eet_File_Mode mode)
1575 1557
1576 /* if we can't open - bail out */ 1558 /* if we can't open - bail out */
1577 if (eet_test_close(!ef->fp, ef)) 1559 if (eet_test_close(!ef->fp, ef))
1578 goto on_error; 1560 return NULL;
1579 1561
1580 fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC); 1562 fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC);
1581 /* if we opened for read or read-write */ 1563 /* if we opened for read or read-write */
@@ -1585,10 +1567,10 @@ eet_open(const char *file, Eet_File_Mode mode)
1585 ef->data = mmap(NULL, ef->data_size, PROT_READ, 1567 ef->data = mmap(NULL, ef->data_size, PROT_READ,
1586 MAP_SHARED, fileno(ef->fp), 0); 1568 MAP_SHARED, fileno(ef->fp), 0);
1587 if (eet_test_close((ef->data == MAP_FAILED), ef)) 1569 if (eet_test_close((ef->data == MAP_FAILED), ef))
1588 goto on_error; 1570 return NULL;
1589 ef = eet_internal_read(ef); 1571 ef = eet_internal_read(ef);
1590 if (!ef) 1572 if (!ef)
1591 goto on_error; 1573 return NULL;
1592 } 1574 }
1593 1575
1594 empty_file: 1576 empty_file:
@@ -1602,19 +1584,16 @@ eet_open(const char *file, Eet_File_Mode mode)
1602 /* add to cache */ 1584 /* add to cache */
1603 if (ef->references == 1) 1585 if (ef->references == 1)
1604 { 1586 {
1587 LOCK_CACHE;
1605 if (ef->mode == EET_FILE_MODE_READ) 1588 if (ef->mode == EET_FILE_MODE_READ)
1606 eet_cache_add(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc); 1589 eet_cache_add(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
1607 else 1590 else
1608 if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE)) 1591 if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE))
1609 eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc); 1592 eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
1593 UNLOCK_CACHE;
1610 } 1594 }
1611 1595
1612 UNLOCK_CACHE;
1613 return ef; 1596 return ef;
1614
1615on_error:
1616 UNLOCK_CACHE;
1617 return NULL;
1618} 1597}
1619 1598
1620EAPI Eet_File_Mode 1599EAPI Eet_File_Mode
diff --git a/legacy/eet/src/tests/eet_suite.c b/legacy/eet/src/tests/eet_suite.c
index 0faa01b883..a41e8f7d23 100644
--- a/legacy/eet/src/tests/eet_suite.c
+++ b/legacy/eet/src/tests/eet_suite.c
@@ -6,7 +6,6 @@
6#include <stdio.h> 6#include <stdio.h>
7#include <fcntl.h> 7#include <fcntl.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <pthread.h>
10 9
11#include <check.h> 10#include <check.h>
12 11
@@ -1411,65 +1410,6 @@ START_TEST(eet_cipher_decipher_simple)
1411} 1410}
1412END_TEST 1411END_TEST
1413 1412
1414static Eina_Bool open_worker_stop;
1415static void*
1416open_close_worker(void* path)
1417{
1418 while (!open_worker_stop)
1419 {
1420 Eet_File* ef = eet_open((char const*)path, EET_FILE_MODE_READ);
1421 if (ef == NULL)
1422 {
1423 pthread_exit("eet_open() failed");
1424 }
1425 else
1426 {
1427 Eet_Error err_code = eet_close(ef);
1428 if (err_code != EET_ERROR_NONE)
1429 pthread_exit("eet_close() failed");
1430 }
1431 }
1432
1433 pthread_exit(NULL);
1434}
1435
1436START_TEST(eet_cache_concurrency)
1437{
1438 char *file = strdup("/tmp/eet_suite_testXXXXXX");
1439 const char *buffer = "test data";
1440 Eet_File *ef;
1441 void *thread_ret;
1442 unsigned int n;
1443
1444 eet_init();
1445
1446 /* create a file to test with */
1447 fail_if(!mktemp(file));
1448 ef = eet_open(file, EET_FILE_MODE_WRITE);
1449 fail_if(!ef);
1450 fail_if(!eet_write(ef, "keys/tests", buffer, strlen(buffer) + 1, 0));
1451
1452 /* start a thread that repeatedly opens and closes a file */
1453 open_worker_stop = 0;
1454 pthread_t thread;
1455 pthread_create(&thread, NULL, open_close_worker, file);
1456
1457 /* clear the cache repeatedly in this thread */
1458 for (n = 0; n < 100000; ++n)
1459 {
1460 eet_clearcache();
1461 }
1462
1463 /* join the other thread, and fail if it returned an error message */
1464 open_worker_stop = 1;
1465 fail_if(pthread_join(thread, &thread_ret) != 0);
1466 fail_unless(thread_ret == NULL, (char const*)thread_ret);
1467
1468 fail_if(unlink(file) != 0);
1469 eet_shutdown();
1470}
1471END_TEST
1472
1473 1413
1474Suite * 1414Suite *
1475eet_suite(void) 1415eet_suite(void)
@@ -1515,10 +1455,6 @@ eet_suite(void)
1515 suite_add_tcase(s, tc); 1455 suite_add_tcase(s, tc);
1516#endif 1456#endif
1517 1457
1518 tc = tcase_create("Eet Cache");
1519 tcase_add_test(tc, eet_cache_concurrency);
1520 suite_add_tcase(s, tc);
1521
1522 return s; 1458 return s;
1523} 1459}
1524 1460