Skip to content

Commit

Permalink
uringlator: sever next and prev links in completion
Browse files Browse the repository at this point in the history
Do not do this only for link_timeout. Simplifies logic as there is no
need to check validity of prev or next anymore, and avoids (unlikely) ID reuse bugs.
  • Loading branch information
Cloudef committed Feb 4, 2025
1 parent 66240f9 commit cfbcc87
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/aio/uringlator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,9 @@ pub fn Uringlator(BackendOperation: type) type {
switch (op_type) {
.link_timeout => {
const cid = self.ops.getOne(.prev, res.id);
std.debug.assert(!std.meta.eql(cid, res.id));

const raced = blk: {
if (std.meta.eql(cid, res.id)) break :blk true;
for (finished) |res2| if (std.meta.eql(cid, res2.id)) break :blk true;
break :blk false;
};
Expand All @@ -370,7 +370,6 @@ pub fn Uringlator(BackendOperation: type) type {
self.ops.lookup(cid) catch break :blk .not_found;
std.debug.assert(self.started.isSet(cid.slot));
std.debug.assert(!self.link_lock.isSet(cid.slot));
self.ops.setOne(.next, cid, cid); // sever the link
self.cancel(cid, error.Canceled, backend) catch {};
// ^ even if the operation is not in cancelable state anymore
// the backend will still wait for it to complete
Expand Down Expand Up @@ -435,6 +434,17 @@ pub fn Uringlator(BackendOperation: type) type {
std.debug.assert(self.link_lock.isSet(next.slot));
self.link_lock.unset(next.slot);
}

// sever the link with the next op in chain
self.ops.setOne(.prev, next, next);
}

const prev = self.ops.getOne(.prev, res.id);
if (!std.meta.eql(prev, res.id)) {
if (self.ops.lookup(prev)) {
// sever the link with the previous op in chain
self.ops.setOne(.next, prev, prev);
} else |_| {}
}

backend.uringlator_complete(res.id, op_type, failure);
Expand Down

0 comments on commit cfbcc87

Please sign in to comment.