#[derive(Debug)]
#[repr(transparent)]
pub struct ShareableExpressDataPathInstance<ROTOB: ReceiveOrTransmitOrBoth, FFQ: FreeFrameQueue>(Arc<(ExpressDataPathInstance<ROTOB, FFQ>, BestForCompilationTargetSpinLock, BestForCompilationTargetSpinLock, Mutex<HashSet<QueueIdentifier>>)>);
unsafe impl<ROTOB: ReceiveOrTransmitOrBoth, FFQ: FreeFrameQueue> Sync for ShareableExpressDataPathInstance<ROTOB, FFQ>
{
}
unsafe impl<ROTOB: ReceiveOrTransmitOrBoth, FFQ: FreeFrameQueue> Send for ShareableExpressDataPathInstance<ROTOB, FFQ>
{
}
impl<ROTOB: ReceiveOrTransmitOrBoth, FFQ: FreeFrameQueue> Clone for ShareableExpressDataPathInstance<ROTOB, FFQ>
{
#[inline(always)]
fn clone(&self) -> Self
{
Self(self.0.clone())
}
}
impl<ROTOB: ReceiveOrTransmitOrBoth, FFQ: FreeFrameQueue> ShareableExpressDataPathInstance<ROTOB, FFQ>
{
pub fn share<RingQueueDepths: CreateReceiveOrTransmitOrBoth<ReceiveOrTransmitOrBoth=ROTOB>>(&self, receive_or_transmit_or_both_ring_queue_depths: RingQueueDepths, queue_identifier: QueueIdentifier, arguments: RingQueueDepths::Arguments) -> Result<SharedExpressDataPathSocket<ROTOB, FFQ>, ExpressDataPathSocketCreationError>
{
let is_first =
{
let mut queue_identifiers = self.queue_identifiers();
let is_first = queue_identifiers.is_empty();
let inserted = queue_identifiers.insert(queue_identifier);
debug_assert!(inserted, "queue_identifier `{:?}` is already in use", queue_identifier);
is_first
};
let express_data_path_socket_file_descriptor = if is_first
{
loop
{
match self.user_memory().user_memory_socket_file_descriptor.duplicate_with_close_on_exec_non_blocking()
{
Ok(Some(express_data_path_socket_file_descriptor)) => break express_data_path_socket_file_descriptor,
Ok(None) | Err(CreationError::KernelWouldBeOutOfMemory) => continue,
Err(error) => panic!("{}", error),
}
}
}
else
{
ExpressDataPathSocketFileDescriptor::new().map_err(ExpressDataPathSocketCreationError::CouldNotCreateUserMemorySocketFileDescriptor)?
};
self.express_data_path_instance().shared(receive_or_transmit_or_both_ring_queue_depths, queue_identifier, arguments, self, express_data_path_socket_file_descriptor)
}
}
impl<ROTOB: ReceiveOrTransmitOrBoth, FFQ: FreeFrameQueue> ShareableExpressDataPathInstance<ROTOB, FFQ>
{
#[inline(always)]
fn user_memory(&self) -> &UserMemory<FFQ>
{
&self.express_data_path_instance().user_memory
}
#[doc(hidden)]
#[inline(always)]
fn express_data_path_instance(&self) -> &ExpressDataPathInstance<ROTOB, FFQ>
{
&(self.fields().0)
}
#[inline(always)]
fn fill_queue_spin_lock(&self) -> &BestForCompilationTargetSpinLock
{
&(self.fields().1)
}
#[inline(always)]
fn completion_queue_spin_lock(&self) -> &BestForCompilationTargetSpinLock
{
&(self.fields().2)
}
#[inline(always)]
fn queue_identifiers(&self) -> MutexGuard<HashSet<QueueIdentifier>>
{
(&(self.fields().3)).lock().unwrap()
}
#[doc(hidden)]
#[inline(always)]
fn fields(&self) -> &(ExpressDataPathInstance<ROTOB, FFQ>, BestForCompilationTargetSpinLock, BestForCompilationTargetSpinLock, Mutex<HashSet<QueueIdentifier>>)
{
self.0.deref()
}
}