pub fn Channel(comptime T: type) type {
return struct {
const Self = @This();
allocator: mem.Allocator,
messages: ArrayList(T),
mutex: Thread.Mutex,
condition: Thread.Condition,
is_closed: bool,
pub fn open(allocator: mem.Allocator) Self {
return Self{
.allocator = allocator,
.messages = ArrayList(T).init(allocator),
.mutex = Thread.Mutex{},
.condition = Thread.Condition{},
.is_closed = false,
};
}
pub fn close(self: *Self) void {
self.mutex.lock();
defer self.mutex.unlock();
self.is_closed = true;
self.messages.deinit();
}
pub fn send(self: *Self, message: T) !void {
self.mutex.lock();
defer self.mutex.unlock();
if (self.is_closed)
return error.ChannelClosed;
try self.messages.append(message);
}
pub fn receive(self: *Self) !?T {
self.mutex.lock();
defer self.mutex.unlock();
if (self.is_closed)
return error.ChannelClosed;
if (self.messages.items.len > 0)
return self.messages.pop();
while (!self.is_closed and self.messages.items.len == 0)
self.condition.wait(&self.mutex);
if (self.is_closed)
return error.ChannelClosed;
if (self.messages.items.len > 0)
return self.messages.pop();
return null;
}
};
}