in FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_mqueue.c [631:720]
ssize_t mq_timedreceive( mqd_t mqdes,
char * msg_ptr,
size_t msg_len,
unsigned * msg_prio,
const struct timespec * abstime )
{
ssize_t xStatus = 0;
int iCalculateTimeoutReturn = 0;
TickType_t xTimeoutTicks = 0;
QueueListElement_t * pxMessageQueue = ( QueueListElement_t * ) mqdes;
QueueElement_t xReceiveData = { 0 };
/* Silence warnings about unused parameters. */
( void ) msg_prio;
/* Lock the mutex that guards access to the queue list. This call will
* never fail because it blocks forever. */
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
/* Find the mq referenced by mqdes. */
if( prvFindQueueInList( NULL, NULL, mqdes ) == pdFALSE )
{
/* Queue not found; bad descriptor. */
errno = EBADF;
xStatus = -1;
}
/* Verify that msg_len is large enough. */
if( xStatus == 0 )
{
if( msg_len < ( size_t ) pxMessageQueue->xAttr.mq_msgsize )
{
/* msg_len too small. */
errno = EMSGSIZE;
xStatus = -1;
}
}
if( xStatus == 0 )
{
/* Convert abstime to a tick timeout. */
iCalculateTimeoutReturn = prvCalculateTickTimeout( pxMessageQueue->xAttr.mq_flags,
abstime,
&xTimeoutTicks );
if( iCalculateTimeoutReturn != 0 )
{
errno = iCalculateTimeoutReturn;
xStatus = -1;
}
}
/* Release the mutex protecting the queue list. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
if( xStatus == 0 )
{
/* Receive data from the FreeRTOS queue. */
if( xQueueReceive( pxMessageQueue->xQueue,
&xReceiveData,
xTimeoutTicks ) == pdFALSE )
{
/* If queue receive fails, set the appropriate errno. */
if( pxMessageQueue->xAttr.mq_flags & O_NONBLOCK )
{
/* Set errno to EAGAIN for nonblocking mq. */
errno = EAGAIN;
}
else
{
/* Otherwise, set errno to ETIMEDOUT. */
errno = ETIMEDOUT;
}
xStatus = -1;
}
}
if( xStatus == 0 )
{
/* Get the length of data for return value. */
xStatus = ( ssize_t ) xReceiveData.xDataSize;
/* Copy received data into given buffer, then free it. */
( void ) memcpy( msg_ptr, xReceiveData.pcData, xReceiveData.xDataSize );
vPortFree( xReceiveData.pcData );
}
return xStatus;
}