Fixed-length, allocation and lock-free, async I/O oriented single-producer single-consumer (SPSC) queues.
This library provides several fixed-length queues for different use-cases, based around the same
core:
- asyncio
is a generic async, thread-safe, lock-free queue using [futures]. Read
operations can pause until data is available, and write operations can pause until space is
returned. The queue can act as an efficient I/O buffer with [futures::AsyncRead
] and
[futures::AsyncWrite
] implementations.
- blocking
is a generic thread-safe queue. Read operations can block until data is
available, and write operations can block until space is returned. The queue can act as an
efficient I/O buffer with [io::Read
] and [io::Write
] implementations.
- nonblocking
is a generic thread-safe, lock-free queue that is guaranteed to not block.
It can act as an efficient I/O buffer when read and write speed is matched or no locks
are available.
All queues have separate Reader
and Writer
ends which can be sent across threads. Queues are
designed with bulk operations in mind, so can safely be used with large read and write
operations, such as in a byte array I/O context.
The library also provides Ring
, a low-level atomic ring buffer building block used to
implement the various queues available.
The library supports no_std
with a reduced feature set, and is highly configurable. With the
default feature set, it does not require any dependencies.
```rust use futures::executor::blockon; use futures::join; use miniio_queue::asyncio::queue;
let (mut reader, mut writer) = queue(8);
let writeloop = async { for i in 0..16 { writer.writeall(&[i]).await.unwrap(); } };
let readloop = async { for i in 0..16 { let mut buf = [0]; reader.readexact(&mut buf).await.unwrap();
assert_eq!(buf[0], i);
}
};
blockon(async { join!(writeloop, read_loop) }); ```
```rust use miniioqueue::blocking::queuefromparts; use miniioqueue::Ring; use miniioqueue::storage::{HeapBuffer, Storage};
// Create a queue with half of the underlying buffer in the read side. let ring = Ring::new(10); ring.advance_right(5);
let mut buffer = HeapBuffer::new(10); buffer.slicemut(0..5).copyfrom_slice(&[1, 2, 3, 4, 5]);
let (mut reader, ) = queuefrom_parts(ring, buffer);
for i in 1..=5 { let mut buf = [0]; reader.readexact(&mut buf).unwrap(); asserteq!(buf[0], i); } ```
Provided under the MIT license. Check the LICENSE file for details.