Line data Source code
1 : #include "../common/tdb_private.h" 2 : #include "lock-tracking.h" 3 : 4 : #define fcntl fcntl_with_lockcheck 5 : 6 : #include "../common/io.c" 7 : #include "../common/tdb.c" 8 : #include "../common/lock.c" 9 : #include "../common/freelist.c" 10 : #include "../common/traverse.c" 11 : #include "../common/transaction.c" 12 : #include "../common/error.c" 13 : #include "../common/open.c" 14 : #include "../common/check.c" 15 : #include "../common/hash.c" 16 : #include "../common/mutex.c" 17 : #include "tap-interface.h" 18 : #include <stdlib.h> 19 : #include "logging.h" 20 : 21 : #undef fcntl 22 : 23 : #define NUM_ENTRIES 10 24 : 25 3 : static bool prepare_entries(struct tdb_context *tdb) 26 : { 27 : unsigned int i; 28 : TDB_DATA key, data; 29 : 30 33 : for (i = 0; i < NUM_ENTRIES; i++) { 31 30 : key.dsize = sizeof(i); 32 30 : key.dptr = (void *)&i; 33 30 : data.dsize = strlen("world"); 34 30 : data.dptr = discard_const_p(uint8_t, "world"); 35 : 36 30 : if (tdb_store(tdb, key, data, 0) != 0) 37 0 : return false; 38 : } 39 3 : return true; 40 : } 41 : 42 1 : static void delete_entries(struct tdb_context *tdb) 43 : { 44 : unsigned int i; 45 : TDB_DATA key; 46 : 47 11 : for (i = 0; i < NUM_ENTRIES; i++) { 48 10 : key.dsize = sizeof(i); 49 10 : key.dptr = (void *)&i; 50 : 51 10 : ok1(tdb_delete(tdb, key) == 0); 52 : } 53 1 : } 54 : 55 : /* We don't know how many times this will run. */ 56 6 : static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, 57 : void *private_data) 58 : { 59 : unsigned int i; 60 6 : memcpy(&i, key.dptr, 4); 61 6 : i = (i + 1) % NUM_ENTRIES; 62 6 : key.dptr = (void *)&i; 63 6 : if (tdb_delete(tdb, key) != 0) 64 0 : (*(int *)private_data)++; 65 6 : return 0; 66 : } 67 : 68 10 : static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, 69 : void *private_data) 70 : { 71 10 : ok1(tdb_delete(tdb, key) == 0); 72 10 : return 0; 73 : } 74 : 75 1 : int main(int argc, char *argv[]) 76 : { 77 : struct tdb_context *tdb; 78 1 : int errors = 0; 79 : 80 : plan_tests(41); 81 1 : tdb = tdb_open_ex("run-no-lock-during-traverse.tdb", 82 : 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 83 : 0600, &taplogctx, NULL); 84 : 85 1 : ok1(tdb); 86 1 : ok1(prepare_entries(tdb)); 87 1 : ok1(locking_errors == 0); 88 1 : ok1(tdb_lockall(tdb) == 0); 89 1 : ok1(locking_errors == 0); 90 1 : tdb_traverse(tdb, delete_other, &errors); 91 1 : ok1(errors == 0); 92 1 : ok1(locking_errors == 0); 93 1 : ok1(tdb_unlockall(tdb) == 0); 94 : 95 1 : ok1(prepare_entries(tdb)); 96 1 : ok1(locking_errors == 0); 97 1 : ok1(tdb_lockall(tdb) == 0); 98 1 : ok1(locking_errors == 0); 99 1 : tdb_traverse(tdb, delete_self, NULL); 100 1 : ok1(locking_errors == 0); 101 1 : ok1(tdb_unlockall(tdb) == 0); 102 : 103 1 : ok1(prepare_entries(tdb)); 104 1 : ok1(locking_errors == 0); 105 1 : ok1(tdb_lockall(tdb) == 0); 106 1 : ok1(locking_errors == 0); 107 1 : delete_entries(tdb); 108 1 : ok1(locking_errors == 0); 109 1 : ok1(tdb_unlockall(tdb) == 0); 110 : 111 1 : ok1(tdb_close(tdb) == 0); 112 : 113 1 : return exit_status(); 114 : }