| ... | ... | @@ -1283,6 +1283,46 @@ pub fn Select(comptime U: type) type { |
| 1283 | 1283 | s.io.vtable.groupAsync(s.io.userdata, &s.group, @ptrCast(&context), .of(Context), Context.start); |
| 1284 | 1284 | } |
| 1285 | 1285 | |
| 1286 | /// Calls `function` with `args` concurrently. The resource spawned is |
| 1287 | /// owned by the select. |
| 1288 | /// |
| 1289 | /// `function` must have return type matching the `field` field of `Union`. |
| 1290 | /// |
| 1291 | /// After this function returns successfully, it is guaranteed that |
| 1292 | /// `function` has been assigned a unit of concurrency, and `await` or |
| 1293 | /// `cancel` must be called before the select is deinitialized. |
| 1294 | /// |
| 1295 | /// |
| 1296 | /// Threadsafe. |
| 1297 | /// |
| 1298 | /// Related: |
| 1299 | /// * `Io.concurrent` |
| 1300 | /// * `Group.concurrent` |
| 1301 | pub fn concurrent( |
| 1302 | s: *S, |
| 1303 | comptime field: Field, |
| 1304 | function: anytype, |
| 1305 | args: std.meta.ArgsTuple(@TypeOf(function)), |
| 1306 | ) ConcurrentError!void { |
| 1307 | const Context = struct { |
| 1308 | select: *S, |
| 1309 | args: @TypeOf(args), |
| 1310 | fn start(type_erased_context: *const anyopaque) Cancelable!void { |
| 1311 | const context: *const @This() = @ptrCast(@alignCast(type_erased_context)); |
| 1312 | const raw_result = @call(.auto, function, context.args); |
| 1313 | const elem = @unionInit(U, @tagName(field), raw_result); |
| 1314 | context.select.queue.putOneUncancelable(context.select.io, elem) catch |err| switch (err) { |
| 1315 | error.Closed => unreachable, |
| 1316 | }; |
| 1317 | if (@typeInfo(@TypeOf(raw_result)) == .error_union) |
| 1318 | raw_result catch |err| if (err == error.Canceled) return error.Canceled; |
| 1319 | } |
| 1320 | }; |
| 1321 | const context: Context = .{ .select = s, .args = args }; |
| 1322 | try s.io.vtable.groupConcurrent(s.io.userdata, &s.group, @ptrCast(&context), .of(Context), Context.start); |
| 1323 | _ = @atomicRmw(usize, &s.outstanding, .Add, 1, .monotonic); |
| 1324 | } |
| 1325 | |
| 1286 | 1326 | /// Blocks until another task of the select finishes. |
| 1287 | 1327 | /// |
| 1288 | 1328 | /// Asserts there is at least one more `outstanding` task. |