diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 7f44932550cd2a..71c7896b5626be 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1441,121 +1441,6 @@ fn (mut g Gen) write_shareds() { } } -fn (mut g Gen) register_thread_void_wait_call() { - lock g.waiter_fns { - if '__v_thread_wait' in g.waiter_fns { - return - } - g.waiter_fns << '__v_thread_wait' - g.waiter_fn_definitions.writeln('void __v_thread_wait(__v_thread thread);') - } - 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('}') -} - -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}' } - ret_typ := if is_void { 'void' } else { 'Array_${eltyp}' } - thread_arr_typ := 'Array_${thread_typ}' - fn_name := '${thread_arr_typ}_wait' - mut should_register := false - lock g.waiter_fns { - if fn_name !in g.waiter_fns { - g.waiter_fns << fn_name - should_register = true - } - } - if should_register { - if is_void { - g.register_thread_void_wait_call() - g.waiter_fn_definitions.writeln('void ${fn_name}(${thread_arr_typ} a);') - g.gowrappers.writeln(' -void ${fn_name}(${thread_arr_typ} a) { - for (int i = 0; i < a.len; ++i) { - ${thread_typ} t = ((${thread_typ}*)a.data)[i]; - if (t == 0) continue; - __v_thread_wait(t); - } -}') - } else { - g.waiter_fn_definitions.writeln('${ret_typ} ${fn_name}(${thread_arr_typ} a);') - g.gowrappers.writeln(' -${ret_typ} ${fn_name}(${thread_arr_typ} a) { - ${ret_typ} res = __new_array_with_default(a.len, a.len, sizeof(${eltyp}), 0); - for (int i = 0; i < a.len; ++i) { - ${thread_typ} t = ((${thread_typ}*)a.data)[i];') - if g.pref.os == .windows { - g.gowrappers.writeln('\t\tif (t.handle == 0) continue;') - } else { - g.gowrappers.writeln('\t\tif (t == 0) continue;') - } - g.gowrappers.writeln('\t\t((${eltyp}*)res.data)[i] = __v_thread_${eltyp}_wait(t); - } - return res; -}') - } - } - return fn_name -} - -fn (mut g Gen) register_thread_fixed_array_wait_call(node ast.CallExpr, eltyp string) string { - is_void := eltyp == 'void' - thread_typ := if is_void { '__v_thread' } else { '__v_thread_${eltyp}' } - ret_typ := if is_void { 'void' } else { 'Array_${eltyp}' } - rec_sym := g.table.sym(node.receiver_type) - len := (rec_sym.info as ast.ArrayFixed).size - thread_arr_typ := rec_sym.cname - fn_name := '${thread_arr_typ}_wait' - mut should_register := false - lock g.waiter_fns { - if fn_name !in g.waiter_fns { - g.waiter_fns << fn_name - should_register = true - } - } - if should_register { - if is_void { - g.register_thread_void_wait_call() - g.waiter_fn_definitions.writeln('void ${fn_name}(${thread_arr_typ} a);') - g.gowrappers.writeln(' -void ${fn_name}(${thread_arr_typ} a) { - for (int i = 0; i < ${len}; ++i) { - ${thread_typ} t = ((${thread_typ}*)a)[i]; - if (t == 0) continue; - __v_thread_wait(t); - } -}') - } else { - g.waiter_fn_definitions.writeln('${ret_typ} ${fn_name}(${thread_arr_typ} a);') - g.gowrappers.writeln(' -${ret_typ} ${fn_name}(${thread_arr_typ} a) { - ${ret_typ} res = __new_array_with_default(${len}, ${len}, sizeof(${eltyp}), 0); - for (int i = 0; i < ${len}; ++i) { - ${thread_typ} t = ((${thread_typ}*)a)[i];') - if g.pref.os == .windows { - g.gowrappers.writeln('\t\tif (t.handle == 0) continue;') - } else { - g.gowrappers.writeln('\t\tif (t == 0) continue;') - } - g.gowrappers.writeln('\t\t((${eltyp}*)res.data)[i] = __v_thread_${eltyp}_wait(t); - } - return res; -}') - } - } - return fn_name -} - fn (mut g Gen) register_chan_pop_option_call(opt_el_type string, styp string) { g.chan_pop_options[opt_el_type] = styp } diff --git a/vlib/v/gen/c/spawn_and_go.v b/vlib/v/gen/c/spawn_and_go.v index 55340f97f7c65a..a98f326ce46555 100644 --- a/vlib/v/gen/c/spawn_and_go.v +++ b/vlib/v/gen/c/spawn_and_go.v @@ -227,6 +227,7 @@ fn (mut g Gen) create_waiter_handler(call_expr ast.CallExpr, s_ret_typ string, g } g.waiter_fn_definitions.writeln('${s_ret_typ} ${waiter_fn_name}(${gohandle_name} thread);') g.gowrappers.writeln('\n${s_ret_typ} ${waiter_fn_name}(${gohandle_name} thread) {') + g.gowrappers.writeln('\tif ((unsigned long int)thread == 0) { _v_panic(_SLIT("unable to join thread")); }') mut c_ret_ptr_ptr := 'NULL' call_ret_type := call_expr.return_type if call_ret_type != ast.void_type { @@ -444,3 +445,119 @@ fn (mut g Gen) create_thread_type(call_expr ast.CallExpr, s_ret_typ string, name } g.gowrappers.writeln('}') } + +fn (mut g Gen) register_thread_void_wait_call() { + lock g.waiter_fns { + if '__v_thread_wait' in g.waiter_fns { + return + } + g.waiter_fns << '__v_thread_wait' + g.waiter_fn_definitions.writeln('void __v_thread_wait(__v_thread thread);') + } + g.gowrappers.writeln('void __v_thread_wait(__v_thread thread) {') + g.gowrappers.writeln('\tif ((unsigned long int)thread == 0) { _v_panic(_SLIT("unable to join 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('}') +} + +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}' } + ret_typ := if is_void { 'void' } else { 'Array_${eltyp}' } + thread_arr_typ := 'Array_${thread_typ}' + fn_name := '${thread_arr_typ}_wait' + mut should_register := false + lock g.waiter_fns { + if fn_name !in g.waiter_fns { + g.waiter_fns << fn_name + should_register = true + } + } + if should_register { + if is_void { + g.register_thread_void_wait_call() + g.waiter_fn_definitions.writeln('void ${fn_name}(${thread_arr_typ} a);') + g.gowrappers.writeln(' +void ${fn_name}(${thread_arr_typ} a) { + for (int i = 0; i < a.len; ++i) { + ${thread_typ} t = ((${thread_typ}*)a.data)[i]; + if (t == 0) continue; + __v_thread_wait(t); + } +}') + } else { + g.waiter_fn_definitions.writeln('${ret_typ} ${fn_name}(${thread_arr_typ} a);') + g.gowrappers.writeln(' +${ret_typ} ${fn_name}(${thread_arr_typ} a) { + ${ret_typ} res = __new_array_with_default(a.len, a.len, sizeof(${eltyp}), 0); + for (int i = 0; i < a.len; ++i) { + ${thread_typ} t = ((${thread_typ}*)a.data)[i];') + if g.pref.os == .windows { + g.gowrappers.writeln('\t\tif (t.handle == 0) continue;') + } else { + g.gowrappers.writeln('\t\tif (t == 0) continue;') + } + g.gowrappers.writeln('\t\t((${eltyp}*)res.data)[i] = __v_thread_${eltyp}_wait(t); + } + return res; +}') + } + } + return fn_name +} + +fn (mut g Gen) register_thread_fixed_array_wait_call(node ast.CallExpr, eltyp string) string { + is_void := eltyp == 'void' + thread_typ := if is_void { '__v_thread' } else { '__v_thread_${eltyp}' } + ret_typ := if is_void { 'void' } else { 'Array_${eltyp}' } + rec_sym := g.table.sym(node.receiver_type) + len := (rec_sym.info as ast.ArrayFixed).size + thread_arr_typ := rec_sym.cname + fn_name := '${thread_arr_typ}_wait' + mut should_register := false + lock g.waiter_fns { + if fn_name !in g.waiter_fns { + g.waiter_fns << fn_name + should_register = true + } + } + if should_register { + if is_void { + g.register_thread_void_wait_call() + g.waiter_fn_definitions.writeln('void ${fn_name}(${thread_arr_typ} a);') + g.gowrappers.writeln(' +void ${fn_name}(${thread_arr_typ} a) { + for (int i = 0; i < ${len}; ++i) { + ${thread_typ} t = ((${thread_typ}*)a)[i]; + if (t == 0) continue; + __v_thread_wait(t); + } +}') + } else { + g.waiter_fn_definitions.writeln('${ret_typ} ${fn_name}(${thread_arr_typ} a);') + g.gowrappers.writeln(' +${ret_typ} ${fn_name}(${thread_arr_typ} a) { + ${ret_typ} res = __new_array_with_default(${len}, ${len}, sizeof(${eltyp}), 0); + for (int i = 0; i < ${len}; ++i) { + ${thread_typ} t = ((${thread_typ}*)a)[i];') + if g.pref.os == .windows { + g.gowrappers.writeln('\t\tif (t.handle == 0) continue;') + } else { + g.gowrappers.writeln('\t\tif (t == 0) continue;') + } + g.gowrappers.writeln('\t\t((${eltyp}*)res.data)[i] = __v_thread_${eltyp}_wait(t); + } + return res; +}') + } + } + return fn_name +}