mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix deadlock when returning multiple values in lock (#14014)
This commit is contained in:
parent
3e3b2e25db
commit
afb07e0e16
@ -3902,6 +3902,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
tmpvar := g.new_tmp_var()
|
||||
ret_typ := g.typ(g.unwrap_generic(g.fn_decl.return_type))
|
||||
mut use_tmp_var := g.defer_stmts.len > 0 || g.defer_profile_code.len > 0
|
||||
|| g.cur_lock.lockeds.len > 0
|
||||
// handle promoting none/error/function returning 'Option'
|
||||
if fn_return_is_optional {
|
||||
optional_none := node.exprs[0] is ast.None
|
||||
|
@ -1,4 +1,3 @@
|
||||
// vtest retry: 3
|
||||
import time
|
||||
|
||||
struct AA {
|
||||
@ -6,49 +5,42 @@ mut:
|
||||
b string
|
||||
}
|
||||
|
||||
const (
|
||||
run_time = time.millisecond * 200 // must be big enough to ensure threads have started
|
||||
sleep_time = time.millisecond * 250 // some tolerance added
|
||||
)
|
||||
|
||||
fn test_return_lock() {
|
||||
start := time.now()
|
||||
shared s := AA{'3'}
|
||||
go printer(shared s, start)
|
||||
go fn (shared s AA, start time.Time) {
|
||||
for {
|
||||
reader(shared s)
|
||||
if time.now() - start > run_time {
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
}(shared s, start)
|
||||
time.sleep(sleep_time)
|
||||
assert false
|
||||
}
|
||||
|
||||
fn printer(shared s AA, start time.Time) {
|
||||
for {
|
||||
lock s {
|
||||
assert s.b in ['0', '1', '2', '3', '4', '5']
|
||||
}
|
||||
if time.now() - start > run_time {
|
||||
exit(0)
|
||||
assert s.b == '5'
|
||||
s.b = '4'
|
||||
}
|
||||
rlock s {
|
||||
assert s.b == '4'
|
||||
}
|
||||
}
|
||||
|
||||
fn reader(shared s AA) {
|
||||
mut i := 0
|
||||
for {
|
||||
i++
|
||||
x := i.str()
|
||||
lock s {
|
||||
s.b = x
|
||||
if s.b == '5' {
|
||||
assert s.b == '3'
|
||||
s.b = '5'
|
||||
// this test checks if cgen unlocks the mutex here
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fn test_multi_return_lock() {
|
||||
shared s := AA{'3'}
|
||||
reti, retb := printer2(shared s)
|
||||
lock s {
|
||||
assert s.b == '3'
|
||||
assert reti == 4
|
||||
assert retb == true
|
||||
}
|
||||
}
|
||||
|
||||
fn printer2(shared s AA) (int, bool) {
|
||||
rlock s {
|
||||
assert s.b == '3'
|
||||
return 4, true
|
||||
}
|
||||
return 5, false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user