| ... | @@ -1315,10 +1315,23 @@ pub const TypeErasedQueue = struct { | ... | @@ -1315,10 +1315,23 @@ pub const TypeErasedQueue = struct { |
| 1315 | | 1315 | |
| 1316 | pub fn get(q: *@This(), io: Io, buffer: []u8, min: usize) Cancelable!usize { | 1316 | pub fn get(q: *@This(), io: Io, buffer: []u8, min: usize) Cancelable!usize { |
| 1317 | assert(buffer.len >= min); | 1317 | assert(buffer.len >= min); |
| 1318 | | 1318 | if (buffer.len == 0) return 0; |
| 1319 | try q.mutex.lock(io); | 1319 | try q.mutex.lock(io); |
| 1320 | defer q.mutex.unlock(io); | 1320 | defer q.mutex.unlock(io); |
| | 1321 | return getLocked(q, io, buffer, min, false); |
| | 1322 | } |
| | 1323 | |
| | 1324 | pub fn getUncancelable(q: *@This(), io: Io, buffer: []u8, min: usize) usize { |
| | 1325 | assert(buffer.len >= min); |
| | 1326 | if (buffer.len == 0) return 0; |
| | 1327 | q.mutex.lockUncancelable(io); |
| | 1328 | defer q.mutex.unlock(io); |
| | 1329 | return getLocked(q, io, buffer, min, true) catch |err| switch (err) { |
| | 1330 | error.Canceled => unreachable, |
| | 1331 | }; |
| | 1332 | } |
| 1321 | | 1333 | |
| | 1334 | pub fn getLocked(q: *@This(), io: Io, buffer: []u8, min: usize, uncancelable: bool) Cancelable!usize { |
| 1322 | // The ring buffer gets first priority, then data should come from any | 1335 | // The ring buffer gets first priority, then data should come from any |
| 1323 | // queued putters, then finally the ring buffer should be filled with | 1336 | // queued putters, then finally the ring buffer should be filled with |
| 1324 | // data from putters so they can be resumed. | 1337 | // data from putters so they can be resumed. |
| ... | @@ -1371,7 +1384,10 @@ pub const TypeErasedQueue = struct { | ... | @@ -1371,7 +1384,10 @@ pub const TypeErasedQueue = struct { |
| 1371 | | 1384 | |
| 1372 | var pending: Get = .{ .remaining = remaining, .condition = .{}, .node = .{} }; | 1385 | var pending: Get = .{ .remaining = remaining, .condition = .{}, .node = .{} }; |
| 1373 | q.getters.append(&pending.node); | 1386 | q.getters.append(&pending.node); |
| 1374 | try pending.condition.wait(io, &q.mutex); | 1387 | if (uncancelable) |
| | 1388 | pending.condition.waitUncancelable(io, &q.mutex) |
| | 1389 | else |
| | 1390 | try pending.condition.wait(io, &q.mutex); |
| 1375 | remaining = pending.remaining; | 1391 | remaining = pending.remaining; |
| 1376 | } | 1392 | } |
| 1377 | } | 1393 | } |
| ... | @@ -1439,6 +1455,14 @@ pub fn Queue(Elem: type) type { | ... | @@ -1439,6 +1455,14 @@ pub fn Queue(Elem: type) type { |
| 1439 | return @divExact(q.type_erased.putUncancelable(io, @ptrCast(elements), min * @sizeOf(Elem)), @sizeOf(Elem)); | 1455 | return @divExact(q.type_erased.putUncancelable(io, @ptrCast(elements), min * @sizeOf(Elem)), @sizeOf(Elem)); |
| 1440 | } | 1456 | } |
| 1441 | | 1457 | |
| | 1458 | pub fn putOne(q: *@This(), io: Io, item: Elem) Cancelable!void { |
| | 1459 | assert(try q.put(io, &.{item}, 1) == 1); |
| | 1460 | } |
| | 1461 | |
| | 1462 | pub fn putOneUncancelable(q: *@This(), io: Io, item: Elem) void { |
| | 1463 | assert(q.putUncancelable(io, &.{item}, 1) == 1); |
| | 1464 | } |
| | 1465 | |
| 1442 | /// Receives elements from the beginning of the queue. The function | 1466 | /// Receives elements from the beginning of the queue. The function |
| 1443 | /// returns when at least `min` elements have been populated inside | 1467 | /// returns when at least `min` elements have been populated inside |
| 1444 | /// `buffer`. | 1468 | /// `buffer`. |
| ... | @@ -1450,12 +1474,8 @@ pub fn Queue(Elem: type) type { | ... | @@ -1450,12 +1474,8 @@ pub fn Queue(Elem: type) type { |
| 1450 | return @divExact(try q.type_erased.get(io, @ptrCast(buffer), min * @sizeOf(Elem)), @sizeOf(Elem)); | 1474 | return @divExact(try q.type_erased.get(io, @ptrCast(buffer), min * @sizeOf(Elem)), @sizeOf(Elem)); |
| 1451 | } | 1475 | } |
| 1452 | | 1476 | |
| 1453 | pub fn putOne(q: *@This(), io: Io, item: Elem) Cancelable!void { | 1477 | pub fn getUncancelable(q: *@This(), io: Io, buffer: []Elem, min: usize) usize { |
| 1454 | assert(try q.put(io, &.{item}, 1) == 1); | 1478 | return @divExact(q.type_erased.getUncancelable(io, @ptrCast(buffer), min * @sizeOf(Elem)), @sizeOf(Elem)); |
| 1455 | } | | |
| 1456 | | | |
| 1457 | pub fn putOneUncancelable(q: *@This(), io: Io, item: Elem) void { | | |
| 1458 | assert(q.putUncancelable(io, &.{item}, 1) == 1); | | |
| 1459 | } | 1479 | } |
| 1460 | | 1480 | |
| 1461 | pub fn getOne(q: *@This(), io: Io) Cancelable!Elem { | 1481 | pub fn getOne(q: *@This(), io: Io) Cancelable!Elem { |
| ... | @@ -1464,6 +1484,12 @@ pub fn Queue(Elem: type) type { | ... | @@ -1464,6 +1484,12 @@ pub fn Queue(Elem: type) type { |
| 1464 | return buf[0]; | 1484 | return buf[0]; |
| 1465 | } | 1485 | } |
| 1466 | | 1486 | |
| | 1487 | pub fn getOneUncancelable(q: *@This(), io: Io) Elem { |
| | 1488 | var buf: [1]Elem = undefined; |
| | 1489 | assert(q.getUncancelable(io, &buf, 1) == 1); |
| | 1490 | return buf[0]; |
| | 1491 | } |
| | 1492 | |
| 1467 | /// Returns buffer length in `Elem` units. | 1493 | /// Returns buffer length in `Elem` units. |
| 1468 | pub fn capacity(q: *const @This()) usize { | 1494 | pub fn capacity(q: *const @This()) usize { |
| 1469 | return @divExact(q.type_erased.buffer.len, @sizeOf(Elem)); | 1495 | return @divExact(q.type_erased.buffer.len, @sizeOf(Elem)); |