| ... | @@ -581,8 +581,6 @@ pub const VTable = struct { | ... | @@ -581,8 +581,6 @@ pub const VTable = struct { |
| 581 | context_alignment: std.mem.Alignment, | 581 | context_alignment: std.mem.Alignment, |
| 582 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, | 582 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 583 | ) ?*AnyFuture, | 583 | ) ?*AnyFuture, |
| 584 | /// Returning `null` indicates resource allocation failed. | | |
| 585 | /// | | |
| 586 | /// Thread-safe. | 584 | /// Thread-safe. |
| 587 | asyncConcurrent: *const fn ( | 585 | asyncConcurrent: *const fn ( |
| 588 | /// Corresponds to `Io.userdata`. | 586 | /// Corresponds to `Io.userdata`. |
| ... | @@ -594,19 +592,6 @@ pub const VTable = struct { | ... | @@ -594,19 +592,6 @@ pub const VTable = struct { |
| 594 | context_alignment: std.mem.Alignment, | 592 | context_alignment: std.mem.Alignment, |
| 595 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, | 593 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 596 | ) error{OutOfMemory}!*AnyFuture, | 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 | /// Executes `start` asynchronously in a manner such that it cleans itself | 595 | /// Executes `start` asynchronously in a manner such that it cleans itself |
| 611 | /// up. This mode does not support results, await, or cancel. | 596 | /// up. This mode does not support results, await, or cancel. |
| 612 | /// | 597 | /// |
| ... | @@ -1166,8 +1151,8 @@ pub fn Queue(Elem: type) type { | ... | @@ -1166,8 +1151,8 @@ pub fn Queue(Elem: type) type { |
| 1166 | /// not guaranteed to be available until `await` is called. | 1151 | /// not guaranteed to be available until `await` is called. |
| 1167 | /// | 1152 | /// |
| 1168 | /// `function` *may* be called immediately, before `async` returns. This has | 1153 | /// `function` *may* be called immediately, before `async` returns. This has |
| 1169 | /// weaker guarantees than `asyncConcurrent` and `asyncParallel`, making it the | 1154 | /// weaker guarantees than `asyncConcurrent`, making more portable and |
| 1170 | /// most portable and reusable among the async family functions. | 1155 | /// reusable. |
| 1171 | /// | 1156 | /// |
| 1172 | /// See also: | 1157 | /// See also: |
| 1173 | /// * `asyncDetached` | 1158 | /// * `asyncDetached` |
| ... | @@ -1198,13 +1183,12 @@ pub fn async( | ... | @@ -1198,13 +1183,12 @@ pub fn async( |
| 1198 | } | 1183 | } |
| 1199 | | 1184 | |
| 1200 | /// Calls `function` with `args`, such that the return value of the function is | 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 | 1186 | /// not guaranteed to be available until `await` is called, allowing the caller |
| 1202 | /// flow back to the caller while waiting for any `Io` operations. | 1187 | /// to progress while waiting for any `Io` operations. |
| 1203 | /// | 1188 | /// |
| 1204 | /// This has a weaker guarantee than `asyncParallel`, making it more portable | 1189 | /// This has stronger guarantee than `async`, placing restrictions on what kind |
| 1205 | /// and reusable, however it has stronger guarantee than `async`, placing | 1190 | /// of `Io` implementations are supported. By calling `async` instead, one |
| 1206 | /// restrictions on what kind of `Io` implementations are supported. By calling | 1191 | /// allows, for example, stackful single-threaded blocking I/O. |
| 1207 | /// `async` instead, one allows, for example, stackful single-threaded blocking I/O. | | |
| 1208 | pub fn asyncConcurrent( | 1192 | pub fn asyncConcurrent( |
| 1209 | io: Io, | 1193 | io: Io, |
| 1210 | function: anytype, | 1194 | function: anytype, |
| ... | @@ -1231,44 +1215,6 @@ pub fn asyncConcurrent( | ... | @@ -1231,44 +1215,6 @@ pub fn asyncConcurrent( |
| 1231 | return future; | 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 | /// Calls `function` with `args` asynchronously. The resource cleans itself up | 1218 | /// Calls `function` with `args` asynchronously. The resource cleans itself up |
| 1273 | /// when the function returns. Does not support await, cancel, or a return value. | 1219 | /// when the function returns. Does not support await, cancel, or a return value. |
| 1274 | /// | 1220 | /// |