Skip to content

Instantly share code, notes, and snippets.

@SpexGuy
Created June 15, 2020 18:42
Show Gist options
  • Save SpexGuy/a3add6ee85877a767163962af7be0369 to your computer and use it in GitHub Desktop.
Save SpexGuy/a3add6ee85877a767163962af7be0369 to your computer and use it in GitHub Desktop.
A weird method for frame selection
const SelectFrames = struct {
frames: []@Frame(runInternal),
next_get_result: usize,
next_put_result: usize,
result_frames: []@Frame(awaitResultInternal);
result_values: []Result;
pub fn init(self: *@This(), in_frames: []anyframe->Result) !void {
const wrapped_frames = try allocator.alloc(@Frame(runInternal), in_frames.len);
errdefer allocator.free(wrapped_frames);
const result_frames = try allocator.alloc(@Frame(awaitResultInternal), in_frames.len);
errdefer allocator.free(result_frames);
const results = try allocator.alloc(Result, in_frames.len);
errdefer allocator.free(results);
self = .{
.frames = wrapped_frames,
.next_get_result = 0,
.next_put_result = 0,
.result_frames = result_frames,
.dispose_frames = results,
};
for (result_frames) |*frame| {
frame.* = async awaitResultInternal(self);
}
for (wrapped_frames) |*frame, i| {
frame.* = async runInternal(self, in_frames[i]);
}
}
/// Blocks until any result is available, and returns it.
pub fn next(self: *PollFrames) Result {
const index = atomic_increment(&self.next_get_result);
await self.result_frames[index];
return self.result_values[index];
}
fn runInternal(self: *PollFrames, frame: anyframe->Result) void {
const result = await frame;
const index = atomic_increment(&self.next_put_result);
result_values[index] = result;
resume result_frames[index];
}
fn awaitResultInternal(self: *PollFrames) Result {
suspend; // resumed by finished function
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment