Produce-consume with defer cleanup
Description
Produce-consume with defer cleanup.
- Push 5 Events into a list (producer).
- Pop each, sum the codes (consumer).
- defer frees any items remaining on error, before or after the loop.
Diagram
Source
pub fn produce_consume_with_defer_cleanup(allocator: std.mem.Allocator, io: std.Io) !void {
_ = io;
var list: std.DoublyLinkedList = .{};
defer freeRemaining(&list, allocator);
var i: i32 = 0;
while (i < 5) : (i += 1) {
var slot: Slot = null;
try items.Event.EventPolyHelper.create(allocator, &slot);
items.Event.EventPolyHelper.mustIdentifySlotAs(&slot).code = i;
list.append(&slot.?.*.node);
slot = null;
}
var sum: i32 = 0;
while (list.popFirst()) |node| {
const poly: *polynode.PolyNode = @fieldParentPtr("node", node);
const ev: *items.Event = items.Event.EventPolyHelper.identifyNodeAs(poly) orelse return error.CastFailed;
sum += ev.*.code;
items.freeItem(poly, allocator);
}
try helpers.expect(error.ProduceConsumeFailed, sum == 0 + 1 + 2 + 3 + 4, "wrong sum");
}
fn freeRemaining(list: *std.DoublyLinkedList, alloc: std.mem.Allocator) void {
while (list.popFirst()) |node| {
const poly: *polynode.PolyNode = @fieldParentPtr("node", node);
items.freeItem(poly, alloc);
}
}
const items = @import("../items/items.zig");
const helpers = @import("../helpers/helpers.zig");
const polynode = @import("matryoshka").polynode;
const std = @import("std");
const Slot = polynode.Slot;