Release 6.1.7
This commit is contained in:
214
utility/rtos_compatibility_layers/posix/px_mq_send.c
Normal file
214
utility/rtos_compatibility_layers/posix/px_mq_send.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** POSIX wrapper for THREADX */
|
||||
/** */
|
||||
/** */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h" /* Threadx API */
|
||||
#include "pthread.h" /* Posix API */
|
||||
#include "px_int.h" /* Posix helper functions */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* mq_send PORTABLE C */
|
||||
/* 6.x */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* The mq_send() function puts a message of size msg_len and pointed to*/
|
||||
/* by msg_ptr into the queue indicated by mqdes. The new message has a */
|
||||
/* priority of msg_prio. */
|
||||
/* The queue maintained is in priority order (priorities may range from*/
|
||||
/* 0 to MQ_PRIO_MAX), and in FIFO order within the same priority. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* mqdes Queue descriptor */
|
||||
/* msg_ptr Message pointer */
|
||||
/* msg_len length of message */
|
||||
/* msg_prio Priority of the message */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* OK no of bytes received */
|
||||
/* ERROR If error occurs */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* tx_thread_identify returns currently running thread */
|
||||
/* tx_byte_allocate allocate memory */
|
||||
/* tx_queue_send ThreadX queue send */
|
||||
/* posix_priority_search search message for same priority */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* xx-xx-xxxx William E. Lamie Initial Version 6.x */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
INT mq_send( mqd_t mqdes, const CHAR * msg_ptr, size_t msg_len,
|
||||
ULONG msg_prio )
|
||||
{
|
||||
|
||||
TX_QUEUE *Queue;
|
||||
UINT temp1;
|
||||
POSIX_MSG_QUEUE *q_ptr;
|
||||
VOID *bp;
|
||||
UCHAR *source;
|
||||
UCHAR *destination;
|
||||
UCHAR *save_ptr;
|
||||
ULONG mycount;
|
||||
ULONG msg[4];
|
||||
|
||||
/* Assign a temporary variable for clarity. */
|
||||
Queue = &(mqdes->f_data->queue);
|
||||
q_ptr = (POSIX_MSG_QUEUE * )mqdes->f_data;
|
||||
|
||||
/* First, check for an invalid queue pointer. */
|
||||
if ( (!q_ptr) || ( (q_ptr -> px_queue_id) != PX_QUEUE_ID))
|
||||
{
|
||||
/* Queue pointer is invalid, return appropriate error code. */
|
||||
posix_errno = EBADF;
|
||||
posix_set_pthread_errno(EBADF);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
/* Make sure if we're calling this routine from a ISR timeout
|
||||
is set to zero. */
|
||||
if (!(tx_thread_identify()))
|
||||
{
|
||||
/* POSIX doesn't have error for this, hence give default. */
|
||||
posix_errno = EINTR ;
|
||||
posix_set_pthread_errno(EINTR);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
/* First, check for an invalid queue pointer. */
|
||||
if ( (!q_ptr) || ( (q_ptr->queue.tx_queue_id) != TX_QUEUE_ID))
|
||||
{
|
||||
/* Queue descriptor is invalid, set appropriate error code. */
|
||||
posix_errno = EBADF ;
|
||||
posix_set_pthread_errno(EBADF);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
if(((mqdes->f_flag & O_WRONLY) != O_WRONLY) && ((mqdes->f_flag & O_RDWR) != O_RDWR))
|
||||
{
|
||||
/* Queue pointer is invalid, return appropriate error code. */
|
||||
posix_errno = EBADF;
|
||||
posix_set_pthread_errno(EBADF);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
if( msg_prio > MQ_PRIO_MAX)
|
||||
{
|
||||
/* Return appropriate error. */
|
||||
posix_errno = EINVAL;
|
||||
posix_set_pthread_errno(EINVAL);
|
||||
|
||||
/* Return error. */
|
||||
return(ERROR);
|
||||
}
|
||||
/* Check for an invalid source for message. */
|
||||
if (! msg_ptr)
|
||||
{
|
||||
/* POSIX doesn't have error for this, hence give default. */
|
||||
posix_errno = EINTR ;
|
||||
posix_set_pthread_errno(EINTR);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
/* Now check the length of message. */
|
||||
if ( msg_len > (q_ptr->q_attr.mq_msgsize ) )
|
||||
{
|
||||
/* Return message length exceeds max length. */
|
||||
posix_errno = EMSGSIZE ;
|
||||
posix_set_pthread_errno(EMSGSIZE);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
/* Now try to allocate memory to save the message from the
|
||||
queue's byte pool. */
|
||||
temp1 = tx_byte_allocate((TX_BYTE_POOL * )&(q_ptr->vq_message_area), &bp,
|
||||
msg_len, TX_NO_WAIT);
|
||||
|
||||
if (temp1 != TX_SUCCESS)
|
||||
{
|
||||
posix_internal_error(9999);
|
||||
}
|
||||
/* Got the memory , Setup source and destination pointers
|
||||
Cast them in UCHAR as message length is in bytes. */
|
||||
source = (UCHAR * ) msg_ptr;
|
||||
destination = (UCHAR * ) bp;
|
||||
|
||||
/* Save start of message storage. */
|
||||
save_ptr = destination;
|
||||
|
||||
/* Copy the message into private buffer. */
|
||||
for ( mycount = 0; mycount < msg_len; mycount++)
|
||||
{
|
||||
|
||||
* destination++ = * source++;
|
||||
}
|
||||
/* Restore the pointer of save message. */
|
||||
source = save_ptr ;
|
||||
/* Create message that holds saved message pointer and message length. */
|
||||
msg[0] = (ULONG)source;
|
||||
msg[1] = msg_len;
|
||||
msg[2] = msg_prio;
|
||||
msg[3] = posix_priority_search(mqdes, msg_prio);
|
||||
|
||||
/* Attempt to post the message to the queue. */
|
||||
temp1 = tx_queue_send(Queue, msg, TX_WAIT_FOREVER);
|
||||
if ( temp1 != TX_SUCCESS)
|
||||
{
|
||||
/* POSIX doesn't have error for this, hence give default. */
|
||||
posix_errno = EINTR ;
|
||||
posix_set_pthread_errno(EINTR);
|
||||
|
||||
/* Return ERROR. */
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
/* All done. */
|
||||
return(OK);
|
||||
}
|
||||
Reference in New Issue
Block a user