in FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_mqueue.c [724:825]
int mq_timedsend( mqd_t mqdes,
const char * msg_ptr,
size_t msg_len,
unsigned int msg_prio,
const struct timespec * abstime )
{
int iStatus = 0, iCalculateTimeoutReturn = 0;
TickType_t xTimeoutTicks = 0;
QueueListElement_t * pxMessageQueue = ( QueueListElement_t * ) mqdes;
QueueElement_t xSendData = { 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;
iStatus = -1;
}
/* Verify that mq_msgsize is large enough. */
if( iStatus == 0 )
{
if( msg_len > ( size_t ) pxMessageQueue->xAttr.mq_msgsize )
{
/* msg_len too large. */
errno = EMSGSIZE;
iStatus = -1;
}
}
if( iStatus == 0 )
{
/* Convert abstime to a tick timeout. */
iCalculateTimeoutReturn = prvCalculateTickTimeout( pxMessageQueue->xAttr.mq_flags,
abstime,
&xTimeoutTicks );
if( iCalculateTimeoutReturn != 0 )
{
errno = iCalculateTimeoutReturn;
iStatus = -1;
}
}
/* Release the mutex protecting the queue list. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
/* Allocate memory for the message. */
if( iStatus == 0 )
{
xSendData.xDataSize = msg_len;
xSendData.pcData = pvPortMalloc( msg_len );
/* Check that memory allocation succeeded. */
if( xSendData.pcData == NULL )
{
/* msg_len too large. */
errno = EMSGSIZE;
iStatus = -1;
}
else
{
/* Copy the data to send. */
( void ) memcpy( xSendData.pcData, msg_ptr, msg_len );
}
}
if( iStatus == 0 )
{
/* Send data to the FreeRTOS queue. */
if( xQueueSend( pxMessageQueue->xQueue,
&xSendData,
xTimeoutTicks ) == pdFALSE )
{
/* If queue send 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;
}
/* Free the allocated queue data. */
vPortFree( xSendData.pcData );
iStatus = -1;
}
}
return iStatus;
}