Skip to content

Commit 7da4c42

Browse files
committed
refdb: adjust the threading tests to what we promise
We say it's going to work if you use a different repository in each thread. Let's do precisely that in our code instead of hoping re-using the refdb is going to work. This test does fail currently, surfacing existing bugs.
1 parent e1c1433 commit 7da4c42

File tree

1 file changed

+44
-78
lines changed

1 file changed

+44
-78
lines changed

tests/threads/refdb.c

Lines changed: 44 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,21 @@ void test_threads_refdb__cleanup(void)
1919
#define REPEAT 20
2020
#define THREADS 20
2121

22+
struct th_data {
23+
int id;
24+
const char *path;
25+
};
26+
2227
static void *iterate_refs(void *arg)
2328
{
29+
struct th_data *data = (struct th_data *) arg;
2430
git_reference_iterator *i;
2531
git_reference *ref;
2632
int count = 0;
33+
git_repository *repo;
2734

28-
cl_git_pass(git_reference_iterator_new(&i, g_repo));
35+
cl_git_pass(git_repository_open(&repo, data->path));
36+
cl_git_pass(git_reference_iterator_new(&i, repo));
2937

3038
for (count = 0; !git_reference_next(&ref, i); ++count) {
3139
cl_assert(ref != NULL);
@@ -37,77 +45,31 @@ static void *iterate_refs(void *arg)
3745

3846
git_reference_iterator_free(i);
3947

48+
git_repository_free(repo);
4049
giterr_clear();
4150
return arg;
4251
}
4352

44-
void test_threads_refdb__iterator(void)
45-
{
46-
int r, t;
47-
git_thread th[THREADS];
48-
int id[THREADS];
49-
git_oid head;
50-
git_reference *ref;
51-
char name[128];
52-
git_refdb *refdb;
53-
54-
g_repo = cl_git_sandbox_init("testrepo2");
55-
56-
cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
57-
58-
/* make a bunch of references */
59-
60-
for (r = 0; r < 200; ++r) {
61-
p_snprintf(name, sizeof(name), "refs/heads/direct-%03d", r);
62-
cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
63-
git_reference_free(ref);
64-
}
65-
66-
cl_git_pass(git_repository_refdb(&refdb, g_repo));
67-
cl_git_pass(git_refdb_compress(refdb));
68-
git_refdb_free(refdb);
69-
70-
g_expected = 206;
71-
72-
for (r = 0; r < REPEAT; ++r) {
73-
g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */
74-
75-
for (t = 0; t < THREADS; ++t) {
76-
id[t] = t;
77-
#ifdef GIT_THREADS
78-
cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t]));
79-
#else
80-
th[t] = t;
81-
iterate_refs(&id[t]);
82-
#endif
83-
}
84-
85-
#ifdef GIT_THREADS
86-
for (t = 0; t < THREADS; ++t) {
87-
cl_git_pass(git_thread_join(&th[t], NULL));
88-
}
89-
#endif
90-
91-
memset(th, 0, sizeof(th));
92-
}
93-
}
94-
9553
static void *create_refs(void *arg)
9654
{
97-
int *id = arg, i;
55+
int i;
56+
struct th_data *data = (struct th_data *) arg;
9857
git_oid head;
9958
char name[128];
10059
git_reference *ref[10];
60+
git_repository *repo;
10161

102-
cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
62+
cl_git_pass(git_repository_open(&repo, data->path));
63+
64+
cl_git_pass(git_reference_name_to_id(&head, repo, "HEAD"));
10365

10466
for (i = 0; i < 10; ++i) {
105-
p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", *id, i);
106-
cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0, NULL));
67+
p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", data->id, i);
68+
cl_git_pass(git_reference_create(&ref[i], repo, name, &head, 0, NULL));
10769

10870
if (i == 5) {
10971
git_refdb *refdb;
110-
cl_git_pass(git_repository_refdb(&refdb, g_repo));
72+
cl_git_pass(git_repository_refdb(&refdb, repo));
11173
cl_git_pass(git_refdb_compress(refdb));
11274
git_refdb_free(refdb);
11375
}
@@ -116,41 +78,48 @@ static void *create_refs(void *arg)
11678
for (i = 0; i < 10; ++i)
11779
git_reference_free(ref[i]);
11880

81+
git_repository_free(repo);
82+
11983
giterr_clear();
12084
return arg;
12185
}
12286

12387
static void *delete_refs(void *arg)
12488
{
125-
int *id = arg, i;
89+
int i;
90+
struct th_data *data = (struct th_data *) arg;
12691
git_reference *ref;
12792
char name[128];
93+
git_repository *repo;
94+
95+
cl_git_pass(git_repository_open(&repo, data->path));
12896

12997
for (i = 0; i < 10; ++i) {
13098
p_snprintf(
131-
name, sizeof(name), "refs/heads/thread-%03d-%02d", (*id) & ~0x3, i);
99+
name, sizeof(name), "refs/heads/thread-%03d-%02d", (data->id) & ~0x3, i);
132100

133-
if (!git_reference_lookup(&ref, g_repo, name)) {
101+
if (!git_reference_lookup(&ref, repo, name)) {
134102
cl_git_pass(git_reference_delete(ref));
135103
git_reference_free(ref);
136104
}
137105

138106
if (i == 5) {
139107
git_refdb *refdb;
140-
cl_git_pass(git_repository_refdb(&refdb, g_repo));
108+
cl_git_pass(git_repository_refdb(&refdb, repo));
141109
cl_git_pass(git_refdb_compress(refdb));
142110
git_refdb_free(refdb);
143111
}
144112
}
145113

114+
git_repository_free(repo);
146115
giterr_clear();
147116
return arg;
148117
}
149118

150119
void test_threads_refdb__edit_while_iterate(void)
151120
{
152121
int r, t;
153-
int id[THREADS];
122+
struct th_data th_data[THREADS];
154123
git_oid head;
155124
git_reference *ref;
156125
char name[128];
@@ -189,29 +158,26 @@ void test_threads_refdb__edit_while_iterate(void)
189158
default: fn = iterate_refs; break;
190159
}
191160

192-
id[t] = t;
193-
194-
/* It appears with all reflog writing changes, etc., that this
195-
* test has started to fail quite frequently, so let's disable it
196-
* for now by just running on a single thread...
197-
*/
198-
/* #ifdef GIT_THREADS */
199-
/* cl_git_pass(git_thread_create(&th[t], fn, &id[t])); */
200-
/* #else */
201-
fn(&id[t]);
202-
/* #endif */
161+
th_data[t].id = t;
162+
th_data[t].path = git_repository_path(g_repo);
163+
164+
#ifdef GIT_THREADS
165+
cl_git_pass(git_thread_create(&th[t], fn, &th_data[t]));
166+
#else
167+
fn(&th_data[t]);
168+
#endif
203169
}
204170

205171
#ifdef GIT_THREADS
206-
/* for (t = 0; t < THREADS; ++t) { */
207-
/* cl_git_pass(git_thread_join(th[t], NULL)); */
208-
/* } */
172+
for (t = 0; t < THREADS; ++t) {
173+
cl_git_pass(git_thread_join(&th[t], NULL));
174+
}
209175

210176
memset(th, 0, sizeof(th));
211177

212178
for (t = 0; t < THREADS; ++t) {
213-
id[t] = t;
214-
cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t]));
179+
th_data[t].id = t;
180+
cl_git_pass(git_thread_create(&th[t], iterate_refs, &th_data[t]));
215181
}
216182

217183
for (t = 0; t < THREADS; ++t) {

0 commit comments

Comments
 (0)