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 : }
|