use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use crate::mem::Allocation;
use crate::spmc::queue::{Queue, Slot};
#[repr(C, align(128))]
pub(super) struct ProducerState {
pub(super) write_cursor: AtomicUsize,
}
pub struct Producer<T: bytemuck::AnyBitPattern, const CAPACITY: usize, AllocT: Allocation<Slot<T>>>
{
inner: Arc<Queue<T, CAPACITY, AllocT>>,
_not_sync: PhantomData<*const ()>,
}
impl<T: bytemuck::AnyBitPattern, const CAPACITY: usize, AllocT: Allocation<Slot<T>>> std::fmt::Debug
for Producer<T, CAPACITY, AllocT>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Producer")
.field("capacity", &CAPACITY)
.finish_non_exhaustive()
}
}
unsafe impl<T: bytemuck::AnyBitPattern, const CAPACITY: usize, AllocT: Allocation<Slot<T>>> Send
for Producer<T, CAPACITY, AllocT>
{
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mem::test_util::NeverAlloc;
static_assertions::assert_impl_all!(Producer<u32, 1, NeverAlloc>: Send);
static_assertions::assert_not_impl_any!(Producer<u32, 1, NeverAlloc>: Sync, Clone, Copy);
}
impl<T, const CAPACITY: usize, AllocT> Producer<T, CAPACITY, AllocT>
where
T: bytemuck::AnyBitPattern,
AllocT: Allocation<Slot<T>>,
{
pub(super) fn new(queue: Arc<Queue<T, CAPACITY, AllocT>>) -> Self {
Self {
inner: queue,
_not_sync: PhantomData,
}
}
#[inline]
pub fn publish(&self, value: T) {
self.inner.publish(value)
}
}