Skip to content

Commit 1b52538

Browse files
authored
sync: fix a helgrind false positive, for a data race, on PoolProcessor (#24023)
1 parent 42538e1 commit 1b52538

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

vlib/sync/pool/pool.c.v

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub struct PoolProcessor {
1313
mut:
1414
njobs int
1515
items []voidptr
16-
results []voidptr
16+
results shared []voidptr
1717
ntask u32 // reading/writing to this should be atomic
1818
waitgroup sync.WaitGroup
1919
shared_context voidptr
@@ -88,7 +88,9 @@ pub fn (mut pool PoolProcessor) work_on_pointers(items []voidptr) {
8888
}
8989
unsafe {
9090
pool.thread_contexts = []voidptr{len: items.len}
91-
pool.results = []voidptr{len: items.len}
91+
lock pool.results {
92+
pool.results = []voidptr{len: items.len}
93+
}
9294
pool.items = []voidptr{cap: items.len}
9395
pool.items << items
9496
pool.waitgroup.add(njobs)
@@ -115,7 +117,9 @@ fn process_in_thread(mut pool PoolProcessor, task_id int) {
115117
if idx >= ilen {
116118
break
117119
}
118-
pool.results[idx] = cb(mut pool, idx, task_id)
120+
lock pool.results {
121+
pool.results[idx] = cb(mut pool, idx, task_id)
122+
}
119123
}
120124
pool.waitgroup.done()
121125
}
@@ -129,14 +133,18 @@ pub fn (pool &PoolProcessor) get_item[T](idx int) T {
129133
// get_result - called by the main thread to get a specific result.
130134
// Retrieves a type safe instance of the produced result.
131135
pub fn (pool &PoolProcessor) get_result[T](idx int) T {
132-
return unsafe { *(&T(pool.results[idx])) }
136+
rlock pool.results {
137+
return unsafe { *(&T(pool.results[idx])) }
138+
}
133139
}
134140

135141
// get_results - get a list of type safe results in the main thread.
136142
pub fn (pool &PoolProcessor) get_results[T]() []T {
137143
mut res := []T{cap: pool.results.len}
138144
for i in 0 .. pool.results.len {
139-
res << unsafe { *(&T(pool.results[i])) }
145+
rlock pool.results {
146+
res << unsafe { *(&T(pool.results[i])) }
147+
}
140148
}
141149
return res
142150
}
@@ -145,7 +153,9 @@ pub fn (pool &PoolProcessor) get_results[T]() []T {
145153
pub fn (pool &PoolProcessor) get_results_ref[T]() []&T {
146154
mut res := []&T{cap: pool.results.len}
147155
for i in 0 .. pool.results.len {
148-
res << unsafe { &T(pool.results[i]) }
156+
rlock pool.results {
157+
res << unsafe { &T(pool.results[i]) }
158+
}
149159
}
150160
return res
151161
}

vlib/v/gen/c/assign.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
234234
// we can't just do `.str` since we need the extra data from the string struct
235235
// doing `&string` is also not an option since the stack memory with the data will be overwritten
236236
g.expr(left0) // node.left[0])
237+
if first_left_type.has_flag(.shared_f) {
238+
g.write('->val')
239+
}
237240
g.writeln('); // free ${type_to_free} on re-assignment2')
238241
defer {
239242
if af {

0 commit comments

Comments
 (0)