| ... | ... | @@ -6,6 +6,8 @@ const windows = std.os.windows; |
| 6 | 6 | const c = std.c; |
| 7 | 7 | const assert = std.debug.assert; |
| 8 | 8 | |
| 9 | const bad_startfn_ret = "expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"; |
| 10 | |
| 9 | 11 | pub const Thread = struct { |
| 10 | 12 | data: Data, |
| 11 | 13 | |
| ... | ... | @@ -158,15 +160,34 @@ pub const Thread = struct { |
| 158 | 160 | }; |
| 159 | 161 | fn threadMain(raw_arg: windows.LPVOID) callconv(.C) windows.DWORD { |
| 160 | 162 | const arg = if (@sizeOf(Context) == 0) {} else @ptrCast(*Context, @alignCast(@alignOf(Context), raw_arg)).*; |
| 163 | |
| 161 | 164 | switch (@typeInfo(@TypeOf(startFn).ReturnType)) { |
| 162 | | .Int => { |
| 163 | | return startFn(arg); |
| 165 | .NoReturn => { |
| 166 | startFn(arg); |
| 164 | 167 | }, |
| 165 | 168 | .Void => { |
| 166 | 169 | startFn(arg); |
| 167 | 170 | return 0; |
| 168 | 171 | }, |
| 169 | | else => @compileError("expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"), |
| 172 | .Int => |info| { |
| 173 | if (info.bits != 8) { |
| 174 | @compileError(bad_startfn_ret); |
| 175 | } |
| 176 | return startFn(arg); |
| 177 | }, |
| 178 | .ErrorUnion => |info| { |
| 179 | if (info.payload != void) { |
| 180 | @compileError(bad_startfn_ret); |
| 181 | } |
| 182 | startFn(arg) catch |err| { |
| 183 | std.debug.warn("error: {}\n", .{@errorName(err)}); |
| 184 | if (@errorReturnTrace()) |trace| { |
| 185 | std.debug.dumpStackTrace(trace.*); |
| 186 | } |
| 187 | }; |
| 188 | return 0; |
| 189 | }, |
| 190 | else => @compileError(bad_startfn_ret), |
| 170 | 191 | } |
| 171 | 192 | } |
| 172 | 193 | }; |
| ... | ... | @@ -202,14 +223,32 @@ pub const Thread = struct { |
| 202 | 223 | const arg = if (@sizeOf(Context) == 0) {} else @intToPtr(*const Context, ctx_addr).*; |
| 203 | 224 | |
| 204 | 225 | switch (@typeInfo(@TypeOf(startFn).ReturnType)) { |
| 205 | | .Int => { |
| 206 | | return startFn(arg); |
| 226 | .NoReturn => { |
| 227 | startFn(arg); |
| 207 | 228 | }, |
| 208 | 229 | .Void => { |
| 209 | 230 | startFn(arg); |
| 210 | 231 | return 0; |
| 211 | 232 | }, |
| 212 | | else => @compileError("expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"), |
| 233 | .Int => |info| { |
| 234 | if (info.bits != 8) { |
| 235 | @compileError(bad_startfn_ret); |
| 236 | } |
| 237 | return startFn(arg); |
| 238 | }, |
| 239 | .ErrorUnion => |info| { |
| 240 | if (info.payload != void) { |
| 241 | @compileError(bad_startfn_ret); |
| 242 | } |
| 243 | startFn(arg) catch |err| { |
| 244 | std.debug.warn("error: {}\n", .{@errorName(err)}); |
| 245 | if (@errorReturnTrace()) |trace| { |
| 246 | std.debug.dumpStackTrace(trace.*); |
| 247 | } |
| 248 | }; |
| 249 | return 0; |
| 250 | }, |
| 251 | else => @compileError(bad_startfn_ret), |
| 213 | 252 | } |
| 214 | 253 | } |
| 215 | 254 | fn posixThreadMain(ctx: ?*c_void) callconv(.C) ?*c_void { |