### Async Framed Producer/Consumer Example Source: https://context7.com/jamesmunns/bbqueue/llms.txt The async framed producer and consumer support backpressure-aware frame passing in async runtimes when paired with an async notifier. ```rust use bbqueue::{BBQueue, traits::{coordination::cas::AtomicCoord, storage::Inline}}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; static BBQ: BBQueue, AtomicCoord, MaiNotSpsc> = BBQueue::new(); #[tokio::test] async fn async_framed_example() { let prod = BBQ.framed_producer(); let cons = BBQ.framed_consumer(); let rx = tokio::spawn(async move { let rgr = cons.wait_read().await; assert_eq!(&*rgr, &[0xCA, 0xFE]); rgr.release(); }); let tx = tokio::spawn(async move { // Await space for a 2-byte frame (header bytes are handled internally) let mut wgr = prod.wait_grant(2u16).await; wgr.copy_from_slice(&[0xCA, 0xFE]); wgr.commit(2u16); }); rx.await.unwrap(); tx.await.unwrap(); } ``` -------------------------------- ### Framed Producer/Consumer Example Source: https://context7.com/jamesmunns/bbqueue/llms.txt Use the framed interface to prepend a length header before each payload, ensuring the consumer reads complete frames. Ideal for message-oriented protocols. ```rust use bbqueue::{BBQueue, traits::{coordination::cas::AtomicCoord, notifier::polling::Polling, storage::Inline}}; use core::ops::Deref; static BBQ: BBQueue, AtomicCoord, Polling> = BBQueue::new(); // Use static handles for const contexts static PROD: bbqueue::prod_cons::framed::FramedProducer<&'static BBQueue, AtomicCoord, Polling>> = BBQ.framed_producer(); static CONS: bbqueue::prod_cons::framed::FramedConsumer<&'static BBQueue, AtomicCoord, Polling>> = BBQ.framed_consumer(); fn send_packet(payload: &[u8]) { let sz = payload.len() as u16; match PROD.grant(sz) { Ok(mut wgr) => { wgr.copy_from_slice(payload); wgr.commit(sz); // header is written automatically } Err(e) => eprintln!("framed grant failed: {:?}", e), } } fn recv_packet() { match CONS.read() { Ok(rgr) => { println!("received {} bytes: {:?}", rgr.len(), rgr.deref()); rgr.release(); // release the entire frame at once } Err(_) => println!("no frame available"), } } send_packet(b"\x01\x02\x03\x04"); send_packet(b"\xAB\xCD"); recv_packet(); // prints: received 4 bytes: [1, 2, 3, 4] recv_packet(); // prints: received 2 bytes: [171, 205] ``` -------------------------------- ### BBQueue Initialization Examples Source: https://context7.com/jamesmunns/bbqueue/llms.txt Demonstrates the initialization of different BBQueue configurations using nickname type aliases. Includes embedded no-alloc polling, embedded async, and heap-backed Arc async queues. ```rust use bbqueue::nicknames::{Churrasco, Texas, Lechon}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; use bbqueue::ArcBBQueue; use bbqueue::traits::{coordination::cas::AtomicCoord, storage::BoxedSlice}; // Embedded no-alloc polling static EMBEDDED_Q: Churrasco<128> = Churrasco::new(); // Embedded async (inline, borrowed) static ASYNC_Q: Texas<64, MaiNotSpsc> = Texas::new(); // Heap-backed Arc async (for std programs where buffer size is runtime-determined) let dynamic_q: Lechon = ArcBBQueue::new_with_storage(BoxedSlice::new(4096)); let prod = dynamic_q.stream_producer(); let cons = dynamic_q.stream_consumer(); assert_eq!(prod.capacity(), 4096); ``` -------------------------------- ### Async Stream Producer/Consumer Example Source: https://context7.com/jamesmunns/bbqueue/llms.txt Utilize the async stream interface with an async-capable notifier for non-polling producer and consumer operations. Futures automatically wake up when data or space becomes available. ```rust use bbqueue::{ArcBBQueue, traits::{coordination::cas::AtomicCoord, storage::Inline}}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; #[tokio::main] async fn main() { let bbq: ArcBBQueue, AtomicCoord, MaiNotSpsc> = ArcBBQueue::new_with_storage(Inline::new()); let prod = bbq.stream_producer(); let cons = bbq.stream_consumer(); // Spawn consumer task — blocks until data is available let rx = tokio::spawn(async move { let rgr = cons.wait_read().await; // no spin-loop needed println!("async received: {:?}", &*rgr); assert_eq!(&*rgr, &[10, 20, 30]); rgr.release(3); }); // Spawn producer task — blocks until space is available let tx = tokio::spawn(async move { let mut wgr = prod.wait_grant_exact(3).await; wgr.copy_from_slice(&[10, 20, 30]); wgr.commit(3); }); rx.await.unwrap(); tx.await.unwrap(); } ``` -------------------------------- ### Local Usage of BBQueue Source: https://github.com/jamesmunns/bbqueue/blob/main/README.md Demonstrates creating and using a BBQueue buffer for local producer-consumer interaction. Ensure the 'Churrasco' flavor is appropriate for your target environment. ```rust use bbqueue::nicknames::Churrasco; // Create a buffer with six elements let bb: Churrasco<6> = Churrasco::new(); let prod = bb.stream_producer(); let cons = bb.stream_consumer(); // Request space for one byte let mut wgr = prod.grant_exact(1).unwrap(); // Set the data wgr[0] = 123; assert_eq!(wgr.len(), 1); // Make the data ready for consuming wgr.commit(1); // Read all available bytes let rgr = cons.read().unwrap(); assert_eq!(rgr[0], 123); // Release the space for later writes rgr.release(1); ``` -------------------------------- ### Create BBQueue with Inline Static Storage Source: https://context7.com/jamesmunns/bbqueue/llms.txt Use `Churrasco::new()` for creating a static BBQueue with inline storage in a const context. This is common for embedded applications. ```rust use bbqueue::nicknames::Churrasco; // BBQueue, AtomicCoord, Polling> // Declare a static queue with 256 bytes of inline storage static BBQ: Churrasco<256> = Churrasco::new(); fn main() { let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); // Write 4 bytes let mut wgr = prod.grant_exact(4).expect("not enough space"); wgr.copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); wgr.commit(4); // Read them back let rgr = cons.read().expect("no data available"); assert_eq!(&*rgr, &[0xDE, 0xAD, 0xBE, 0xEF]); rgr.release(4); } ``` -------------------------------- ### BBQueue::new_with_storage() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Creates a BBQueue by providing a storage instance. This method is useful for runtime-created buffers (e.g., heap-allocated) or when storage is managed externally. ```APIDOC ## BBQueue::new_with_storage() ### Description Creates a `BBQueue` by supplying a storage instance at construction time. Useful when a buffer needs to be created at runtime (heap-allocated) or when the storage is owned externally. ### Method `BBQueue::new_with_storage(storage)` ### Parameters - **storage**: An instance of a type implementing the `Storage` trait (e.g., `Inline`, `BoxedSlice`). ### Request Example ```rust use bbqueue::{BBQueue, traits::{coordination::cas::AtomicCoord, notifier::polling::Polling, storage::{Inline, BoxedSlice}}}; // Inline storage (stack/static) let buf = Inline::<128>::new(); let bbq: BBQueue<_, AtomicCoord, Polling> = BBQueue::new_with_storage(&buf); let prod = bbq.stream_producer(); let cons = bbq.stream_consumer(); // Heap storage (requires `alloc` feature) let heap_buf = BoxedSlice::new(1024); let bbq2: BBQueue<_, AtomicCoord, Polling> = BBQueue::new_with_storage(heap_buf); let prod2 = bbq2.stream_producer(); let cons2 = bbq2.stream_consumer(); assert_eq!(prod.capacity(), 128); assert_eq!(prod2.capacity(), 1024); ``` ### Response Returns a `BBQueue` instance. ``` -------------------------------- ### BBQueue::new() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Creates a BBQueue with inline static storage using `[u8; N]`. This is suitable for `static` variables in embedded applications and requires the storage type to implement `ConstStorage`. ```APIDOC ## BBQueue::new() ### Description Creates a `BBQueue` in a `const` context using inline `[u8; N]` storage. This is the primary constructor for `static` variables in embedded applications. Requires the storage type to implement `ConstStorage`. ### Method `BBQueue::new()` ### Parameters None ### Request Example ```rust use bbqueue::nicknames::Churrasco; // BBQueue, AtomicCoord, Polling> // Declare a static queue with 256 bytes of inline storage static BBQ: Churrasco<256> = Churrasco::new(); fn main() { let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); // Write 4 bytes let mut wgr = prod.grant_exact(4).expect("not enough space"); wgr.copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); wgr.commit(4); // Read them back let rgr = cons.read().expect("no data available"); assert_eq!(&*rgr, &[0xDE, 0xAD, 0xBE, 0xEF]); rgr.release(4); } ``` ### Response Returns a `BBQueue` instance. ``` -------------------------------- ### Async Stream Interface - `wait_grant_exact()` / `wait_read()` Source: https://context7.com/jamesmunns/bbqueue/llms.txt Enables asynchronous data transfer using futures that automatically wake up when data or space becomes available, suitable for async runtimes. ```APIDOC ## Async Stream Interface - `wait_grant_exact()` / `wait_read()` ### Description With an async-capable notifier (e.g. `MaiNotSpsc`), the producer and consumer can `.await` instead of polling. The futures wake up automatically when space or data becomes available. ### Producer Methods - `wait_grant_exact(size: usize)`: Asynchronously waits until a contiguous buffer of the exact specified size is available for writing. Returns a `WritableGrant`. - `commit(size: usize)`: Commits the granted buffer of the specified size. ### Consumer Methods - `wait_read()`: Asynchronously waits until at least one complete message is available for reading. Returns a `ReadableGrant`. - `release(size: usize)`: Releases the specified number of bytes from the read buffer. ### Example Usage ```rust use bbqueue::{ArcBBQueue, traits::{coordination::cas::AtomicCoord, storage::Inline}}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; #[tokio::main] async fn main() { let bbq: ArcBBQueue, AtomicCoord, MaiNotSpsc> = ArcBBQueue::new_with_storage(Inline::new()); let prod = bbq.stream_producer(); let cons = bbq.stream_consumer(); // Spawn consumer task — blocks until data is available let rx = tokio::spawn(async move { let rgr = cons.wait_read().await; // no spin-loop needed println!("async received: {:?}", &*rgr); assert_eq!(&*rgr, &[10, 20, 30]); rgr.release(3); }); // Spawn producer task — blocks until space is available let tx = tokio::spawn(async move { let mut wgr = prod.wait_grant_exact(3).await; wgr.copy_from_slice(&[10, 20, 30]); wgr.commit(3); }); rx.await.unwrap(); tx.await.unwrap(); } ``` ``` -------------------------------- ### Create BBQueue with Explicit Storage Source: https://context7.com/jamesmunns/bbqueue/llms.txt Use `BBQueue::new_with_storage()` to create a queue with externally provided or heap-allocated storage. This is useful for runtime buffer creation. ```rust use bbqueue::{BBQueue, traits::{coordination::cas::AtomicCoord, notifier::polling::Polling, storage::{Inline, BoxedSlice}}}; // Inline storage (stack/static) let buf = Inline::<128>::new(); let bbq: BBQueue<_, AtomicCoord, Polling> = BBQueue::new_with_storage(&buf); let prod = bbq.stream_producer(); let cons = bbq.stream_consumer(); // Heap storage (requires `alloc` feature) let heap_buf = BoxedSlice::new(1024); let bbq2: BBQueue<_, AtomicCoord, Polling> = BBQueue::new_with_storage(heap_buf); let prod2 = bbq2.stream_producer(); let cons2 = bbq2.stream_consumer(); assert_eq!(prod.capacity(), 128); assert_eq!(prod2.capacity(), 1024); ``` -------------------------------- ### Async Framed Interface - `wait_grant()` / `wait_read()` (framed) Source: https://context7.com/jamesmunns/bbqueue/llms.txt Combines the framed interface with asynchronous operations, allowing backpressure-aware frame passing in async environments. ```APIDOC ## Async Framed Interface - `wait_grant()` / `wait_read()` (framed) ### Description The framed producer and consumer also support `async` variants when paired with an async notifier, enabling backpressure-aware frame passing in async runtimes. ### Producer Methods - `wait_grant(size: u16)`: Asynchronously waits until space is available for a frame of the specified size (excluding header). Returns a `WritableGrant`. - `commit(size: u16)`: Commits the granted frame of the specified size. The length header is written automatically. ### Consumer Methods - `wait_read()`: Asynchronously waits until a complete frame is available. Returns a `ReadableGrant`. - `release()`: Releases the entire frame that was read. ### Example Usage ```rust use bbqueue::{BBQueue, traits::{coordination::cas::AtomicCoord, storage::Inline}}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; static BBQ: BBQueue, AtomicCoord, MaiNotSpsc> = BBQueue::new(); #[tokio::test] async fn async_framed_example() { let prod = BBQ.framed_producer(); let cons = BBQ.framed_consumer(); let rx = tokio::spawn(async move { let rgr = cons.wait_read().await; assert_eq!(&*rgr, &[0xCA, 0xFE]); rgr.release(); }); let tx = tokio::spawn(async move { // Await space for a 2-byte frame (header bytes are handled internally) let mut wgr = prod.wait_grant(2u16).await; wgr.copy_from_slice(&[0xCA, 0xFE]); wgr.commit(2u16); }); rx.await.unwrap(); tx.await.unwrap(); } ``` ``` -------------------------------- ### Static Usage of BBQueue Source: https://github.com/jamesmunns/bbqueue/blob/main/README.md Illustrates using a statically allocated BBQueue buffer across threads. Note the comment advising against using `sleep` in real-world scenarios; prefer `Notify` for synchronization. ```rust use bbqueue::nicknames::Churrasco; use std::{thread::{sleep, spawn}, time::Duration}; // Create a buffer with six elements static BB: Churrasco<6> = Churrasco::new(); fn receiver() { let cons = BB.stream_consumer(); loop { if let Ok(rgr) = cons.read() { assert_eq!(rgr.len(), 1); assert_eq!(rgr[0], 123); rgr.release(1); break; } // don't do this in real code, use Notify! sleep(Duration::from_millis(10)); } } fn main() { let prod = BB.stream_producer(); // spawn the consumer let hdl = spawn(receiver); // Request space for one byte let mut wgr = prod.grant_exact(1).unwrap(); // Set the data wgr[0] = 123; assert_eq!(wgr.len(), 1); // Make the data ready for consuming wgr.commit(1); // make sure the receiver terminated hdl.join().unwrap(); } ``` -------------------------------- ### Querying BBQueue Capacity Source: https://context7.com/jamesmunns/bbqueue/llms.txt The `capacity()` method returns the total byte capacity of the underlying storage. It is available on `BBQueue`, `ArcBBQueue`, and their producer/consumer handles. ```rust use bbqueue::nicknames::{Churrasco, Tandoori}; use bbqueue::ArcBBQueue; use bbqueue::traits::{coordination::cas::AtomicCoord, storage::BoxedSlice}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; // Inline: capacity is the const generic N static BBQ: Churrasco<512> = Churrasco::new(); assert_eq!(BBQ.capacity(), 512); // From a producer handle let prod = BBQ.stream_producer(); assert_eq!(prod.capacity(), 512); // Heap: capacity is the runtime argument to BoxedSlice::new let bbq2: ArcBBQueue = ArcBBQueue::new_with_storage(BoxedSlice::new(1024)); assert_eq!(bbq2.capacity(), 1024); ``` -------------------------------- ### Create Reference-Counted BBQueue with Inline Storage Source: https://context7.com/jamesmunns/bbqueue/llms.txt Use `ArcBBQueue::new_with_storage()` to wrap a BBQueue in an `Arc`, enabling producer and consumer handles to be shared across threads. Requires the `alloc` feature. ```rust use bbqueue::{ArcBBQueue, traits::{coordination::cas::AtomicCoord, storage::Inline}}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; use std::thread; let bbq: ArcBBQueue, AtomicCoord, MaiNotSpsc> = ArcBBQueue::new_with_storage(Inline::new()); let prod = bbq.stream_producer(); let cons = bbq.stream_consumer(); // Producer and consumer can be moved across thread boundaries freely let writer = thread::spawn(move || { let mut wgr = prod.grant_exact(3).unwrap(); wgr.copy_from_slice(&[1, 2, 3]); wgr.commit(3); }); let reader = thread::spawn(move || { // Poll until data is available loop { if let Ok(rgr) = cons.read() { assert_eq!(&*rgr, &[1, 2, 3]); rgr.release(3); break; } } }); writer.join().unwrap(); reader.join().unwrap(); ``` -------------------------------- ### StreamProducer::grant_exact() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Obtains a contiguous write grant of exactly a specified size. This method is crucial for requesting a precise amount of space for writing data into the ring buffer. It returns an error if no space is available or if a grant is already in progress. ```APIDOC ## StreamProducer::grant_exact() ### Description Obtains a contiguous write slice of exactly `sz` bytes. Will wrap around the ring buffer if there is insufficient contiguous space at the tail. Returns `Err(WriteGrantError::InsufficientSize)` if no space is available, or `Err(WriteGrantError::GrantInProgress)` if a grant is already outstanding. ### Method `grant_exact(sz: usize)` ### Parameters #### Path Parameters - **sz** (usize) - Required - The exact number of bytes to grant. ### Request Example ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<16> = Churrasco::new(); let prod = BBQ.stream_producer(); // Request exactly 8 bytes match prod.grant_exact(8) { Ok(mut wgr) => { let data = b"hello!!!\0"; wgr[..8].copy_from_slice(&data[..8]); wgr.commit(8); // make all 8 bytes visible to consumer } Err(e) => eprintln!("grant failed: {:?}", e), } ``` ### Response #### Success Response (Ok(StreamGrantW)) - **StreamGrantW** - A writable grant representing the requested contiguous memory slice. #### Error Response (Err(WriteGrantError)) - **WriteGrantError::InsufficientSize** - If no space is available in the buffer. - **WriteGrantError::GrantInProgress** - If a grant is already outstanding. ``` -------------------------------- ### Free Read Bytes with StreamGrantR::release() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Returns `used` bytes back to the producer. Partial release leaves unconsumed bytes available for the next `read()` call. ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<32> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let mut wgr = prod.grant_exact(8).unwrap(); wgr.copy_from_slice(b"ABCDEFGH"); wgr.commit(8); let rgr = cons.read().unwrap(); assert_eq!(rgr.len(), 8); // Only consume 4 bytes; the next read will see "EFGH" rgr.release(4); let rgr2 = cons.read().unwrap(); assert_eq!(&*rgr2, b"EFGH"); rgr2.release(4); ``` -------------------------------- ### Request Exact Size Write Grant with StreamProducer::grant_exact() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Obtains a contiguous write slice of exactly `sz` bytes. Wraps around the ring buffer if necessary. Returns an error if insufficient space is available or a grant is already outstanding. ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<16> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); // Request exactly 8 bytes match prod.grant_exact(8) { Ok(mut wgr) => { let data = b"hello!!!\0"; wgr[..8].copy_from_slice(&data[..8]); wgr.commit(8); // make all 8 bytes visible to consumer } Err(e) => eprintln!("grant failed: {:?}", e), } let rgr = cons.read().unwrap(); assert_eq!(rgr.len(), 8); rgr.release(8); ``` -------------------------------- ### `BBQueue::capacity()` - Query total buffer size Source: https://context7.com/jamesmunns/bbqueue/llms.txt Retrieves the total byte capacity of the underlying storage for BBQueue and ArcBBQueue, as well as producer and consumer handles. ```APIDOC ## `BBQueue::capacity()` — Query total buffer size ### Description Returns the total byte capacity of the underlying storage. Available on both `BBQueue` and `ArcBBQueue`, as well as on all producer and consumer handles. ### Usage This method can be called on the `BBQueue` or `ArcBBQueue` instance, or on any producer or consumer handle obtained from it. ### Example Usage ```rust use bbqueue::nicknames::{Churrasco, Tandoori}; use bbqueue::ArcBBQueue; use bbqueue::traits::{coordination::cas::AtomicCoord, storage::BoxedSlice}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; // Inline: capacity is the const generic N static BBQ: Churrasco<512> = Churrasco::new(); assert_eq!(BBQ.capacity(), 512); // From a producer handle let prod = BBQ.stream_producer(); assert_eq!(prod.capacity(), 512); // Heap: capacity is the runtime argument to BoxedSlice::new let bbq2: ArcBBQueue = ArcBBQueue::new_with_storage(BoxedSlice::new(1024)); assert_eq!(bbq2.capacity(), 1024); ``` ``` -------------------------------- ### Framed Interface - `framed_producer()` / `framed_consumer()` Source: https://context7.com/jamesmunns/bbqueue/llms.txt The framed interface prepends a length header before each payload, ensuring the consumer reads complete frames. This is ideal for message-oriented protocols. ```APIDOC ## Framed Interface - `framed_producer()` / `framed_consumer()` ### Description This interface prepends a length header (`u16` by default, or `usize`) before each payload, so the consumer always reads exactly one complete frame at a time. Ideal for message-oriented protocols (network packets, COBS frames, etc.). ### Producer Methods - `grant(size: u16)`: Attempts to grant a contiguous buffer of the specified size for writing. Returns `Ok(WritableGrant)` on success or `Err(GrantError)` on failure. - `commit(size: u16)`: Commits the granted buffer of the specified size. The length header is written automatically. ### Consumer Methods - `read()`: Attempts to read a complete frame from the queue. Returns `Ok(ReadableGrant)` containing the frame data on success or `Err(ReadError)` if no frame is available. - `release()`: Releases the entire frame that was read. ### Example Usage ```rust use bbqueue::{BBQueue, traits::{coordination::cas::AtomicCoord, notifier::polling::Polling, storage::Inline}}; use core::ops::Deref; static BBQ: BBQueue, AtomicCoord, Polling> = BBQueue::new(); // Use static handles for const contexts static PROD: bbqueue::prod_cons::framed::FramedProducer<&'static BBQueue, AtomicCoord, Polling>> = BBQ.framed_producer(); static CONS: bbqueue::prod_cons::framed::FramedConsumer<&'static BBQueue, AtomicCoord, Polling>> = BBQ.framed_consumer(); fn send_packet(payload: &[u8]) { let sz = payload.len() as u16; match PROD.grant(sz) { Ok(mut wgr) => { wgr.copy_from_slice(payload); wgr.commit(sz); // header is written automatically } Err(e) => eprintln!("framed grant failed: {:?}", e), } } fn recv_packet() { match CONS.read() { Ok(rgr) => { println!("received {} bytes: {:?}", rgr.len(), rgr.deref()); rgr.release(); // release the entire frame at once } Err(_) => println!("no frame available"), } } send_packet(b"\x01\x02\x03\x04"); send_packet(b"\xAB\xCD"); recv_packet(); // prints: received 4 bytes: [1, 2, 3, 4] recv_packet(); // prints: received 2 bytes: [171, 205] ``` ``` -------------------------------- ### ArcBBQueue::new_with_storage() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Wraps a BBQueue in an `Arc`, allowing producer and consumer handles to be shared across threads or tasks without lifetime constraints. Requires the `alloc` feature. ```APIDOC ## ArcBBQueue::new_with_storage() ### Description Wraps the queue in an `Arc` so that producer and consumer handles can be moved into separate threads or tasks without lifetime constraints. Requires the `alloc` feature. ### Method `ArcBBQueue::new_with_storage(storage)` ### Parameters - **storage**: An instance of a type implementing the `Storage` trait (e.g., `Inline`). ### Request Example ```rust use bbqueue::{ArcBBQueue, traits::{coordination::cas::AtomicCoord, storage::Inline}}; use bbqueue::traits::notifier::maitake::MaiNotSpsc; use std::thread; let bbq: ArcBBQueue, AtomicCoord, MaiNotSpsc> = ArcBBQueue::new_with_storage(Inline::new()); let prod = bbq.stream_producer(); let cons = bbq.stream_consumer(); // Producer and consumer can be moved across thread boundaries freely let writer = thread::spawn(move || { let mut wgr = prod.grant_exact(3).unwrap(); wgr.copy_from_slice(&[1, 2, 3]); wgr.commit(3); }); let reader = thread::spawn(move || { // Poll until data is available loop { if let Ok(rgr) = cons.read() { assert_eq!(&*rgr, &[1, 2, 3]); rgr.release(3); break; } } }); writer.join().unwrap(); reader.join().unwrap(); ``` ### Response Returns an `ArcBBQueue` instance. ``` -------------------------------- ### Read Available Bytes with StreamConsumer::read() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Returns a grant for the contiguous data available at the head of the ring buffer. May not cover all available bytes if data wraps around. Call `read()` again after `release()` to drain completely. ```rust use bbqueue::nicknames::Churrasco; use core::ops::Deref; static BBQ: Churrasco<64> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let mut wgr = prod.grant_exact(12).unwrap(); wgr.copy_from_slice(b"hello world!"); wgr.commit(12); // First read: gets available contiguous chunk match cons.read() { Ok(rgr) => { println!("read {} bytes: {:?}", rgr.len(), rgr.deref()); // Partially release: only consume 5 bytes rgr.release(5); } Err(_) => println!("queue empty"), } // Second read: gets the remaining 7 bytes let rgr2 = cons.read().unwrap(); assert_eq!(rgr2.len(), 7); rgr2.release(7); // Queue is now empty assert!(cons.read().is_err()); ``` -------------------------------- ### BBQueue Nickname Type Aliases Overview Source: https://context7.com/jamesmunns/bbqueue/llms.txt This table outlines the available nickname type aliases in BBQueue, detailing their storage, coordination, notifier, Arc support, and target use cases. Choose the alias that best matches your project's constraints. ```rust // ┌─────────────────────────────────────────────────────────────────────────────┐ // │ Nickname │ Storage │ Coordination │ Notifier │ Arc? │ Target │ // ├─────────────────────────────────────────────────────────────────────────────┤ // │ Jerk │ Inline │ Critical Section │ Polling │ No │ No-alloc, CS │ // │ Churrasco│ Inline │ Atomic CAS │ Polling │ No │ std / Cortex-M4│ // │ Texas │ Inline │ Atomic CAS │ Async │ No │ Async embedded │ // │ Barbacoa │ Inline │ Atomic CAS │ Polling │ Yes │ Arc, no-async │ // │ KansasCity │ Inline │ Atomic CAS │ Async │ Yes │ Arc + async │ // │ YakiNiku │ Heap │ Atomic CAS │ Polling │ No │ std heap │ // │ Tandoori │ Heap │ Atomic CAS │ Async │ No │ std heap async │ // │ Lechon │ Heap │ Atomic CAS │ Async │ Yes │ Arc heap async │ // └─────────────────────────────────────────────────────────────────────────────┘ ``` -------------------------------- ### Finalize Write Grant with StreamGrantW::commit() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Makes `used` bytes visible to the consumer. Must be called; dropping the grant without `commit` publishes zero bytes. Wakes an async consumer if applicable. ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<32> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let mut wgr = prod.grant_exact(10).unwrap(); // Write only 6 bytes even though we reserved 10 wgr[..6].copy_from_slice(b"short!"); wgr.commit(6); // only 6 bytes become readable; 4 reserved bytes are reclaimed let rgr = cons.read().unwrap(); assert_eq!(rgr.len(), 6); rgr.release(6); ``` -------------------------------- ### Request Best-Effort Write Grant with StreamProducer::grant_max_remaining() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Returns up to `max` bytes without causing a ring-buffer wrap-around. Useful for draining external buffers incrementally. If no space is available, it prompts draining the consumer first. ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<32> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let data = b"this is a longer message for the queue"; let mut remaining = data; while !remaining.is_empty() { match prod.grant_max_remaining(remaining.len()) { Ok(mut wgr) => { let n = wgr.len(); // may be less than requested wgr[..n].copy_from_slice(&remaining[..n]); wgr.commit(n); remaining = &remaining[n..]; } Err(_) => { // Drain the consumer first, then retry if let Ok(rgr) = cons.read() { let released = rgr.len(); rgr.release(released); } } } } ``` -------------------------------- ### StreamProducer::grant_max_remaining() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Requests a best-effort write grant, returning up to a specified maximum number of bytes without causing a ring-buffer wrap-around. This is useful for incrementally draining external buffers. ```APIDOC ## StreamProducer::grant_max_remaining() ### Description Returns up to `max` bytes without causing a ring-buffer wrap-around, giving back however much contiguous space is available before the wrap point. Useful for draining external buffers incrementally without requiring a contiguous `max`-byte gap. ### Method `grant_max_remaining(max: usize)` ### Parameters #### Path Parameters - **max** (usize) - Required - The maximum number of bytes to grant. ### Request Example ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<32> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let data = b"this is a longer message for the queue"; let mut remaining = data; while !remaining.is_empty() { match prod.grant_max_remaining(remaining.len()) { Ok(mut wgr) => { let n = wgr.len(); // may be less than requested wgr[..n].copy_from_slice(&remaining[..n]); wgr.commit(n); remaining = &remaining[n..]; } Err(_) => { // Drain the consumer first, then retry if let Ok(rgr) = cons.read() { let released = rgr.len(); rgr.release(released); } } } } ``` ### Response #### Success Response (Ok(StreamGrantW)) - **StreamGrantW** - A writable grant representing the available contiguous memory slice, up to `max` bytes. #### Error Response (Err(())) - Indicates that no contiguous space is available before the wrap point. ``` -------------------------------- ### StreamConsumer::read() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Reads available contiguous bytes from the head of the ring buffer. The returned grant may not cover all available bytes if the data wraps around the buffer. Subsequent calls to `read()` after `release()` can be used to consume the remaining data. ```APIDOC ## StreamConsumer::read() ### Description Returns a `StreamGrantR` containing whatever contiguous data is available at the head of the ring buffer. The grant may not cover all available bytes if the data wraps around the buffer; call `read()` again after `release()` to drain completely. ### Method `read()` ### Parameters None ### Request Example ```rust use bbqueue::nicknames::Churrasco; use core::ops::Deref; static BBQ: Churrasco<64> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let mut wgr = prod.grant_exact(12).unwrap(); wgr.copy_from_slice(b"hello world!"); wgr.commit(12); // First read: gets available contiguous chunk match cons.read() { Ok(rgr) => { println!("read {} bytes: {:?}", rgr.len(), rgr.deref()); // Partially release: only consume 5 bytes rgr.release(5); } Err(_) => println!("queue empty"), } // Second read: gets the remaining 7 bytes let rgr2 = cons.read().unwrap(); assert_eq!(rgr2.len(), 7); rgr2.release(7); // Queue is now empty assert!(cons.read().is_err()); ``` ### Response #### Success Response (Ok(StreamGrantR)) - **StreamGrantR** - A readable grant containing the contiguous data available at the head of the buffer. #### Error Response (Err(())) - Indicates that the queue is empty. ``` -------------------------------- ### StreamGrantR::release() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Frees a specified number of read bytes back to the producer, making space in the ring buffer. Partial release allows unconsumed bytes to remain available for subsequent read operations. ```APIDOC ## StreamGrantR::release() ### Description Returns `used` bytes (capped to grant length) back to the write side of the ring buffer. Partial release leaves the unconsumed bytes available for the next `read()` call. ### Method `release(used: usize)` ### Parameters #### Path Parameters - **used** (usize) - Required - The number of bytes to release, capped to the grant length. ### Request Example ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<32> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let mut wgr = prod.grant_exact(8).unwrap(); wgr.copy_from_slice(b"ABCDEFGH"); wgr.commit(8); let rgr = cons.read().unwrap(); assert_eq!(rgr.len(), 8); // Only consume 4 bytes; the next read will see "EFGH" rgr.release(4); let rgr2 = cons.read().unwrap(); assert_eq!(&*rgr2, b"EFGH"); rgr2.release(4); ``` ### Response None. This method modifies the queue state. ``` -------------------------------- ### StreamGrantW::commit() Source: https://context7.com/jamesmunns/bbqueue/llms.txt Finalizes a write grant, making a specified number of bytes visible to the consumer. This method must be called to publish data; dropping the grant without calling `commit` results in zero bytes being published. It also wakes any sleeping asynchronous consumers. ```APIDOC ## StreamGrantW::commit() ### Description Makes `used` bytes (capped to the grant length) visible to the consumer. **Must be called** — dropping the grant without calling `commit` commits zero bytes (no data published). Wakes a sleeping async consumer if applicable. ### Method `commit(used: usize)` ### Parameters #### Path Parameters - **used** (usize) - Required - The number of bytes to commit, capped to the grant length. ### Request Example ```rust use bbqueue::nicknames::Churrasco; static BBQ: Churrasco<32> = Churrasco::new(); let prod = BBQ.stream_producer(); let cons = BBQ.stream_consumer(); let mut wgr = prod.grant_exact(10).unwrap(); // Write only 6 bytes even though we reserved 10 wgr[..6].copy_from_slice(b"short!"); wgr.commit(6); // only 6 bytes become readable; 4 reserved bytes are reclaimed let rgr = cons.read().unwrap(); assert_eq!(rgr.len(), 6); rgr.release(6); ``` ### Response None. This method modifies the queue state. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.