| ... | @@ -934,8 +934,6 @@ pub const VTable = struct { | ... | @@ -934,8 +934,6 @@ pub const VTable = struct { |
| 934 | context_alignment: std.mem.Alignment, | 934 | context_alignment: std.mem.Alignment, |
| 935 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, | 935 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 936 | ) ?*AnyFuture, | 936 | ) ?*AnyFuture, |
| 937 | /// Returning `null` indicates resource allocation failed. | | |
| 938 | /// | | |
| 939 | /// Thread-safe. | 937 | /// Thread-safe. |
| 940 | asyncConcurrent: *const fn ( | 938 | asyncConcurrent: *const fn ( |
| 941 | /// Corresponds to `Io.userdata`. | 939 | /// Corresponds to `Io.userdata`. |
| ... | @@ -947,19 +945,6 @@ pub const VTable = struct { | ... | @@ -947,19 +945,6 @@ pub const VTable = struct { |
| 947 | context_alignment: std.mem.Alignment, | 945 | context_alignment: std.mem.Alignment, |
| 948 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, | 946 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 949 | ) error{OutOfMemory}!*AnyFuture, | 947 | ) error{OutOfMemory}!*AnyFuture, |
| 950 | /// Returning `null` indicates resource allocation failed. | | |
| 951 | /// | | |
| 952 | /// Thread-safe. | | |
| 953 | asyncParallel: *const fn ( | | |
| 954 | /// Corresponds to `Io.userdata`. | | |
| 955 | userdata: ?*anyopaque, | | |
| 956 | result_len: usize, | | |
| 957 | result_alignment: std.mem.Alignment, | | |
| 958 | /// Copied and then passed to `start`. | | |
| 959 | context: []const u8, | | |
| 960 | context_alignment: std.mem.Alignment, | | |
| 961 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, | | |
| 962 | ) error{OutOfMemory}!*AnyFuture, | | |
| 963 | /// Executes `start` asynchronously in a manner such that it cleans itself | 948 | /// Executes `start` asynchronously in a manner such that it cleans itself |
| 964 | /// up. This mode does not support results, await, or cancel. | 949 | /// up. This mode does not support results, await, or cancel. |
| 965 | /// | 950 | /// |
| ... | @@ -1519,8 +1504,8 @@ pub fn Queue(Elem: type) type { | ... | @@ -1519,8 +1504,8 @@ pub fn Queue(Elem: type) type { |
| 1519 | /// not guaranteed to be available until `await` is called. | 1504 | /// not guaranteed to be available until `await` is called. |
| 1520 | /// | 1505 | /// |
| 1521 | /// `function` *may* be called immediately, before `async` returns. This has | 1506 | /// `function` *may* be called immediately, before `async` returns. This has |
| 1522 | /// weaker guarantees than `asyncConcurrent` and `asyncParallel`, making it the | 1507 | /// weaker guarantees than `asyncConcurrent`, making more portable and |
| 1523 | /// most portable and reusable among the async family functions. | 1508 | /// reusable. |
| 1524 | /// | 1509 | /// |
| 1525 | /// See also: | 1510 | /// See also: |
| 1526 | /// * `asyncDetached` | 1511 | /// * `asyncDetached` |
| ... | @@ -1551,13 +1536,12 @@ pub fn async( | ... | @@ -1551,13 +1536,12 @@ pub fn async( |
| 1551 | } | 1536 | } |
| 1552 | | 1537 | |
| 1553 | /// Calls `function` with `args`, such that the return value of the function is | 1538 | /// Calls `function` with `args`, such that the return value of the function is |
| 1554 | /// not guaranteed to be available until `await` is called, passing control | 1539 | /// not guaranteed to be available until `await` is called, allowing the caller |
| 1555 | /// flow back to the caller while waiting for any `Io` operations. | 1540 | /// to progress while waiting for any `Io` operations. |
| 1556 | /// | 1541 | /// |
| 1557 | /// This has a weaker guarantee than `asyncParallel`, making it more portable | 1542 | /// This has stronger guarantee than `async`, placing restrictions on what kind |
| 1558 | /// and reusable, however it has stronger guarantee than `async`, placing | 1543 | /// of `Io` implementations are supported. By calling `async` instead, one |
| 1559 | /// restrictions on what kind of `Io` implementations are supported. By calling | 1544 | /// allows, for example, stackful single-threaded blocking I/O. |
| 1560 | /// `async` instead, one allows, for example, stackful single-threaded blocking I/O. | | |
| 1561 | pub fn asyncConcurrent( | 1545 | pub fn asyncConcurrent( |
| 1562 | io: Io, | 1546 | io: Io, |
| 1563 | function: anytype, | 1547 | function: anytype, |
| ... | @@ -1584,44 +1568,6 @@ pub fn asyncConcurrent( | ... | @@ -1584,44 +1568,6 @@ pub fn asyncConcurrent( |
| 1584 | return future; | 1568 | return future; |
| 1585 | } | 1569 | } |
| 1586 | | 1570 | |
| 1587 | /// Simultaneously calls `function` with `args` while passing control flow back | | |
| 1588 | /// to the caller. The return value of the function is not guaranteed to be | | |
| 1589 | /// available until `await` is called. | | |
| 1590 | /// | | |
| 1591 | /// This has the strongest guarantees of all async family functions, placing | | |
| 1592 | /// the most restrictions on what kind of `Io` implementations are supported. | | |
| 1593 | /// By calling `asyncConcurrent` instead, one allows, for example, stackful | | |
| 1594 | /// single-threaded non-blocking I/O. | | |
| 1595 | /// | | |
| 1596 | /// See also: | | |
| 1597 | /// * `asyncConcurrent` | | |
| 1598 | /// * `async` | | |
| 1599 | pub fn asyncParallel( | | |
| 1600 | io: Io, | | |
| 1601 | function: anytype, | | |
| 1602 | args: std.meta.ArgsTuple(@TypeOf(function)), | | |
| 1603 | ) error{OutOfMemory}!Future(@typeInfo(@TypeOf(function)).@"fn".return_type.?) { | | |
| 1604 | const Result = @typeInfo(@TypeOf(function)).@"fn".return_type.?; | | |
| 1605 | const Args = @TypeOf(args); | | |
| 1606 | const TypeErased = struct { | | |
| 1607 | fn start(context: *const anyopaque, result: *anyopaque) void { | | |
| 1608 | const args_casted: *const Args = @alignCast(@ptrCast(context)); | | |
| 1609 | const result_casted: *Result = @ptrCast(@alignCast(result)); | | |
| 1610 | result_casted.* = @call(.auto, function, args_casted.*); | | |
| 1611 | } | | |
| 1612 | }; | | |
| 1613 | var future: Future(Result) = undefined; | | |
| 1614 | future.any_future = try io.vtable.asyncParallel( | | |
| 1615 | io.userdata, | | |
| 1616 | @sizeOf(Result), | | |
| 1617 | .of(Result), | | |
| 1618 | @ptrCast((&args)[0..1]), | | |
| 1619 | .of(Args), | | |
| 1620 | TypeErased.start, | | |
| 1621 | ); | | |
| 1622 | return future; | | |
| 1623 | } | | |
| 1624 | | | |
| 1625 | /// Calls `function` with `args` asynchronously. The resource cleans itself up | 1571 | /// Calls `function` with `args` asynchronously. The resource cleans itself up |
| 1626 | /// when the function returns. Does not support await, cancel, or a return value. | 1572 | /// when the function returns. Does not support await, cancel, or a return value. |
| 1627 | /// | 1573 | /// |