From 82e6d6e51d81602c80a220f7b04192c69511c010 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 3 Oct 2021 23:24:44 +0800 Subject: [PATCH] cgen: fix threads array wait without go calls (fix #12009) (#12050) --- vlib/v/gen/c/cgen.v | 18 +++++++++++++ vlib/v/parser/parse_type.v | 3 +++ vlib/v/tests/go_array_wait_without_go_test.v | 27 ++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 vlib/v/tests/go_array_wait_without_go_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 4ab6f30ba0..a3f7345d26 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -887,6 +887,23 @@ fn (mut g Gen) write_shareds() { } } +fn (mut g Gen) register_thread_void_wait_call() { + if '__v_thread_wait' !in g.waiter_fns { + g.gowrappers.writeln('void __v_thread_wait(__v_thread thread) {') + if g.pref.os == .windows { + g.gowrappers.writeln('\tu32 stat = WaitForSingleObject(thread, INFINITE);') + } else { + g.gowrappers.writeln('\tint stat = pthread_join(thread, (void **)NULL);') + } + g.gowrappers.writeln('\tif (stat != 0) { _v_panic(_SLIT("unable to join thread")); }') + if g.pref.os == .windows { + g.gowrappers.writeln('\tCloseHandle(thread);') + } + g.gowrappers.writeln('}') + g.waiter_fns << '__v_thread_wait' + } +} + fn (mut g Gen) register_thread_array_wait_call(eltyp string) string { is_void := eltyp == 'void' thread_typ := if is_void { '__v_thread' } else { '__v_thread_$eltyp' } @@ -896,6 +913,7 @@ fn (mut g Gen) register_thread_array_wait_call(eltyp string) string { if fn_name !in g.waiter_fns { g.waiter_fns << fn_name if is_void { + g.register_thread_void_wait_call() g.gowrappers.writeln(' void ${fn_name}($thread_arr_typ a) { for (int i = 0; i < a.len; ++i) { diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 6278e033ea..c1a30f001d 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -70,6 +70,9 @@ pub fn (mut p Parser) parse_array_type() ast.Type { // error is set in parse_type return 0 } + if elem_type.idx() == ast.thread_type_idx { + p.register_auto_import('sync.threads') + } mut nr_dims := 1 // detect attr not_attr := p.peek_tok.kind != .name && p.peek_token(2).kind !in [.semicolon, .rsbr] diff --git a/vlib/v/tests/go_array_wait_without_go_test.v b/vlib/v/tests/go_array_wait_without_go_test.v new file mode 100644 index 0000000000..96d3730dcb --- /dev/null +++ b/vlib/v/tests/go_array_wait_without_go_test.v @@ -0,0 +1,27 @@ +fn test_go_array_wait_without_go() { + sa := SA{} + sb := SA{} + + sa.wait() + sb.wait() + + assert true +} + +struct SA { +mut: + threads []thread +} + +pub fn (self SA) wait() { + self.threads.wait() +} + +struct SB { +mut: + threads []thread +} + +pub fn (self SB) wait() { + self.threads.wait() +}