| ... | ... | @@ -581,8 +581,6 @@ pub const VTable = struct { |
| 581 | 581 | context_alignment: std.mem.Alignment, |
| 582 | 582 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 583 | 583 | ) ?*AnyFuture, |
| 584 | | /// Returning `null` indicates resource allocation failed. |
| 585 | | /// |
| 586 | 584 | /// Thread-safe. |
| 587 | 585 | asyncConcurrent: *const fn ( |
| 588 | 586 | /// Corresponds to `Io.userdata`. |
| ... | ... | @@ -594,19 +592,6 @@ pub const VTable = struct { |
| 594 | 592 | context_alignment: std.mem.Alignment, |
| 595 | 593 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 596 | 594 | ) error{OutOfMemory}!*AnyFuture, |
| 597 | | /// Returning `null` indicates resource allocation failed. |
| 598 | | /// |
| 599 | | /// Thread-safe. |
| 600 | | asyncParallel: *const fn ( |
| 601 | | /// Corresponds to `Io.userdata`. |
| 602 | | userdata: ?*anyopaque, |
| 603 | | result_len: usize, |
| 604 | | result_alignment: std.mem.Alignment, |
| 605 | | /// Copied and then passed to `start`. |
| 606 | | context: []const u8, |
| 607 | | context_alignment: std.mem.Alignment, |
| 608 | | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 609 | | ) error{OutOfMemory}!*AnyFuture, |
| 610 | 595 | /// Executes `start` asynchronously in a manner such that it cleans itself |
| 611 | 596 | /// up. This mode does not support results, await, or cancel. |
| 612 | 597 | /// |
| ... | ... | @@ -1166,8 +1151,8 @@ pub fn Queue(Elem: type) type { |
| 1166 | 1151 | /// not guaranteed to be available until `await` is called. |
| 1167 | 1152 | /// |
| 1168 | 1153 | /// `function` *may* be called immediately, before `async` returns. This has |
| 1169 | | /// weaker guarantees than `asyncConcurrent` and `asyncParallel`, making it the |
| 1170 | | /// most portable and reusable among the async family functions. |
| 1154 | /// weaker guarantees than `asyncConcurrent`, making more portable and |
| 1155 | /// reusable. |
| 1171 | 1156 | /// |
| 1172 | 1157 | /// See also: |
| 1173 | 1158 | /// * `asyncDetached` |
| ... | ... | @@ -1198,13 +1183,12 @@ pub fn async( |
| 1198 | 1183 | } |
| 1199 | 1184 | |
| 1200 | 1185 | /// Calls `function` with `args`, such that the return value of the function is |
| 1201 | | /// not guaranteed to be available until `await` is called, passing control |
| 1202 | | /// flow back to the caller while waiting for any `Io` operations. |
| 1186 | /// not guaranteed to be available until `await` is called, allowing the caller |
| 1187 | /// to progress while waiting for any `Io` operations. |
| 1203 | 1188 | /// |
| 1204 | | /// This has a weaker guarantee than `asyncParallel`, making it more portable |
| 1205 | | /// and reusable, however it has stronger guarantee than `async`, placing |
| 1206 | | /// restrictions on what kind of `Io` implementations are supported. By calling |
| 1207 | | /// `async` instead, one allows, for example, stackful single-threaded blocking I/O. |
| 1189 | /// This has stronger guarantee than `async`, placing restrictions on what kind |
| 1190 | /// of `Io` implementations are supported. By calling `async` instead, one |
| 1191 | /// allows, for example, stackful single-threaded blocking I/O. |
| 1208 | 1192 | pub fn asyncConcurrent( |
| 1209 | 1193 | io: Io, |
| 1210 | 1194 | function: anytype, |
| ... | ... | @@ -1231,44 +1215,6 @@ pub fn asyncConcurrent( |
| 1231 | 1215 | return future; |
| 1232 | 1216 | } |
| 1233 | 1217 | |
| 1234 | | /// Simultaneously calls `function` with `args` while passing control flow back |
| 1235 | | /// to the caller. The return value of the function is not guaranteed to be |
| 1236 | | /// available until `await` is called. |
| 1237 | | /// |
| 1238 | | /// This has the strongest guarantees of all async family functions, placing |
| 1239 | | /// the most restrictions on what kind of `Io` implementations are supported. |
| 1240 | | /// By calling `asyncConcurrent` instead, one allows, for example, stackful |
| 1241 | | /// single-threaded non-blocking I/O. |
| 1242 | | /// |
| 1243 | | /// See also: |
| 1244 | | /// * `asyncConcurrent` |
| 1245 | | /// * `async` |
| 1246 | | pub fn asyncParallel( |
| 1247 | | io: Io, |
| 1248 | | function: anytype, |
| 1249 | | args: std.meta.ArgsTuple(@TypeOf(function)), |
| 1250 | | ) error{OutOfMemory}!Future(@typeInfo(@TypeOf(function)).@"fn".return_type.?) { |
| 1251 | | const Result = @typeInfo(@TypeOf(function)).@"fn".return_type.?; |
| 1252 | | const Args = @TypeOf(args); |
| 1253 | | const TypeErased = struct { |
| 1254 | | fn start(context: *const anyopaque, result: *anyopaque) void { |
| 1255 | | const args_casted: *const Args = @alignCast(@ptrCast(context)); |
| 1256 | | const result_casted: *Result = @ptrCast(@alignCast(result)); |
| 1257 | | result_casted.* = @call(.auto, function, args_casted.*); |
| 1258 | | } |
| 1259 | | }; |
| 1260 | | var future: Future(Result) = undefined; |
| 1261 | | future.any_future = try io.vtable.asyncParallel( |
| 1262 | | io.userdata, |
| 1263 | | @sizeOf(Result), |
| 1264 | | .of(Result), |
| 1265 | | @ptrCast((&args)[0..1]), |
| 1266 | | .of(Args), |
| 1267 | | TypeErased.start, |
| 1268 | | ); |
| 1269 | | return future; |
| 1270 | | } |
| 1271 | | |
| 1272 | 1218 | /// Calls `function` with `args` asynchronously. The resource cleans itself up |
| 1273 | 1219 | /// when the function returns. Does not support await, cancel, or a return value. |
| 1274 | 1220 | /// |