⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mqpxlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* mqPxLib.c - message queue library (POSIX) *//* Copyright 1984-2002 Wind River Systems, Inc.  */#include "copyright_wrs.h"/*modification history--------------------01s,17jul00,jgn  merge DOT-4 pthreads changes01r,29sep00,pai  added Andrew Gaiarsa's fix for mq_send() during kernelState                 (SPR #32033)01q,16oct96,dgp  doc: modify mq_send to show maximum priority <= 31 		      (SPR #7019)01p,19aug96,dbt  added use of MQ_PRIO_MAX (SPR #7039).01o,11feb95,jdi  corrected spelling error.01n,25jan95,rhp  doc tweaks.    19jan95,jdi  doc cleanup.01m,15apr94,dvs  fix mq_send to unlock interrupts on error.	   +rrr01l,08apr94,dvs  doc cleanup of mq_close (SPR #3099).01k,08apr94,dvs  fixed error in args when calling symFindByName (SPR #3090).01j,03feb94,kdl  moved structure definitions to mqPxLibP.h.01i,01feb94,dvs  documentation changes.01h,30jan94,kdl  changed #if for conditional ffsMsb() prototype (!=I960).01g,28jan94,kdl  added check for invalid msg and queue sizes in mq_open().01f,28jan94,dvs  fixed i960 ffsMsb() problem01e,24jan94,smb  added instrumentation macros01d,12jan94,rrr  fixed bug sending message to self; change to follow wrs 	   +kdl  coding conventions; change mqLibInit() to mqPxLibInit().01c,21dec93,kdl	 fixed errno if opening non-existant queue.01b,12nov93,rrr	 rewrite01a,06apr93,smb	 created*//*DESCRIPTIONThis library implements the message-queue interface defined in thePOSIX 1003.1b standard, as an alternative to the VxWorks-specificmessage queue design in msgQLib.  These message queues are accessedthrough names; each message queue supports multiple sending and receiving tasks.The message queue interface imposes a fixed upper bound on the size ofmessages that can be sent to a specific message queue.  The size is set onan individual queue basis.  The value may not be changed dynamically.This interface allows a task be notified asynchronously of theavailability of a message on the queue.  The purpose of this feature is tolet the task to perform other functions and yet still be notified that amessage has become available on the queue.MESSAGE QUEUE DESCRIPTOR DELETIONThe mq_close() call terminates a message queue descriptor anddeallocates any associated memory.  When deleting message queuedescriptors, take care to avoid interfering with other tasks that areusing the same descriptor.  Tasks should only close messagequeue descriptors that the same task has opened successfully.The routines in this library conform to POSIX 1003.1b.INCLUDE FILES: mqueue.hSEE ALSO: POSIX 1003.1b document, msgQLib,.pG "Basic OS"*/#include "vxWorks.h"#include "errno.h"#include "stdarg.h"#include "string.h"#include "intLib.h"#include "qLib.h"#include "fcntl.h"#include "objLib.h"#include "taskLib.h"#include "semLib.h"#include "private/mqPxLibP.h"#include "private/sigLibP.h"#include "private/kernelLibP.h"#include "private/windLibP.h"#include "private/workQLibP.h"#include "private/eventP.h"#include "symLib.h"#include "memLib.h"#define __PTHREAD_SRC#include "pthread.h"#if CPU_FAMILY != I960extern int ffsMsb (unsigned long);	/* not in any header except for i960 */#endif#undef FREAD#undef FWRITE#define FREAD	1#define FWRITE	2static OBJ_CLASS 	mqClass;CLASS_ID 		mqClassId = &mqClass;SYMTAB_ID 		mqNameTbl;BOOL 			mqLibInstalled = FALSE;#ifdef __GNUC__#define INLINE	__inline__#else#define INLINE#endif/********************************************************************************* sll_ins - insert into a singly linked list** These list have the following form:** ---------* | head  |-------------* ---------             \*                        \*          ----------     \   ----------      ----------        ----------*      ,-->| New - 1|-------->| Newest |----->| Oldest |--~~~-->|        |-*     /    ----------         ----------      ----------        ---------- \*     \____________________________________________________________________/** To insert, put it after the Newest and move the head up one.*/static INLINE void sll_ins    (    struct sll_node *   pNode,		/* node to insert */    struct sll_node **  ppHead		/* addr of head of list */    )    {    if (*ppHead == NULL)	*ppHead = pNode->sll_next = pNode;    else	{	pNode->sll_next = (*ppHead)->sll_next;	(*ppHead)->sll_next = pNode;	*ppHead = pNode;	}    }/********************************************************************************* sll_head - remove the oldest node off a singly linked list** These list have the following form:** ---------* | head  |-------------* ---------             \*                        \*          ----------     \   ----------      ----------        ----------*      ,-->| New - 1|-------->| Newest |------| Oldest |--~~~-->|        |-*     /    ----------         ----------      ----------        ---------- \*     \____________________________________________________________________/** To remove, pull off the one after the Newest, then make sure there are* still some nodes left otherwise null out the head.** RETURNS: A pointer to the oldest node.*/static INLINE struct sll_node *sll_head    (    struct sll_node ** ppHead		/* addr of head of list */    )    {    struct sll_node *pRetval;    if ((pRetval = (*ppHead)->sll_next) == *ppHead)	*ppHead = NULL;    else	(*ppHead)->sll_next = pRetval->sll_next;    return (pRetval);    }/********************************************************************************* mqPxLibInit - initialize the POSIX message queue library** This routine initializes the POSIX message queue facility.  If <hashSize> is* 0, the default value is taken from MQ_HASH_SIZE_DEFAULT.** RETURNS: OK or ERROR.*/int mqPxLibInit    (    int hashSize		/* log2 of number of hash buckets */    )    {    if (!mqLibInstalled)	{	if (hashSize == 0)	    hashSize = MQ_HASH_SIZE_DEFAULT;	if (((mqNameTbl = symTblCreate (hashSize, FALSE, memSysPartId)) != NULL)	    && (classInit (mqClassId, sizeof (struct mq_des),			  OFFSET (struct mq_des, f_objCore),			  (FUNCPTR) NULL,(FUNCPTR) NULL,(FUNCPTR) NULL) == OK))	    mqLibInstalled = TRUE;	}    return (mqLibInstalled) ? OK : ERROR;    }/********************************************************************************* mq_init - quick and dirty init of the guts of a message queue.** The needs to be redone with objects!!! XXX**/static void mq_init    (    void *	pMem,		/* memory to hold queue */    int		nMsgs,		/* number of messages in queue */    int		msgSize		/* size of each message */    )    {    struct sll_node *pNode;    struct msg_que *pMq;    size_t nBytes;    nBytes = MEM_ROUND_UP (msgSize + sizeof (struct sll_node));    pMq = (struct msg_que *) pMem;    bzero ((void *) pMq, sizeof (struct msg_que));    qInit (&pMq->msgq_cond_read, Q_PRI_LIST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);    qInit (&pMq->msgq_cond_data, Q_PRI_LIST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);    pMq->msgq_sigTask		= -1;    pMq->msgq_attr.mq_maxmsg	= nMsgs;    pMq->msgq_attr.mq_msgsize	= msgSize;    pNode = (struct sll_node *) (void *) ((char *)pMem +	    MEM_ROUND_UP (sizeof (struct msg_que)));    while (nMsgs-- > 0)	{	sll_ins (pNode, &pMq->msgq_free_list);	pNode = (struct sll_node *) (void *) ((char *)pNode + nBytes);	}    }/********************************************************************************* mq_terminate - quick and dirty termination of the guts of a message queue.** The needs to be redone with objects!!! XXX**/static void mq_terminate    (    struct msg_que *pMq    )    {    kernelState = TRUE;			/* ENTER KERNEL */    /* windview - level 2 instrumentation */    EVT_TASK_1 (EVENT_OBJ_MSGDELETE, pMq);    windPendQTerminate (&pMq->msgq_cond_read);    /* windview - level 2 instrumentation */    EVT_TASK_1 (EVENT_OBJ_MSGDELETE, pMq);    windPendQTerminate (&pMq->msgq_cond_data);    windExit ();			/* EXIT KERNEL */    /*     * notification processing     */    if (pMq->msgq_sigTask != -1)	{	sigPendDestroy (&pMq->msgq_sigPend);	pMq->msgq_sigTask = -1;	}    free (pMq);    }/********************************************************************************* mq_create - create a message queue** The function mq_create() is used to create a message queue.  The maximum* size of any message that can be sent is <msgSize>.  The message queue* can hold <nMsgs> messages before a mq_send() will block.** RETURNS: Upon successful completion, mq_create() will return a* message queue descriptor.  Otherwise, the function will return (<mqd_t>)-1* and set <errno> to indicate the error.** ERRORS: If any of the following conditions occur, the mq_create() function* will return (<mqd_t>)-1 and set <errno> to the corresponding value:* .iP ENOMEM** NOMANUAL*/mqd_t mq_create    (    size_t nMsgs,		/* number of messages in queue */    size_t msgSize		/* size of each message in queue */    )    {    struct mq_des	*pMqDesc;    void		*pQMem;    if (INT_RESTRICT () != OK)	return ((mqd_t) -1);	/* restrict ISR from calling */    if ((!mqLibInstalled) && (mqPxLibInit (0) != OK))	return ((mqd_t) -1);	/* package init problem */    pQMem = malloc (MEM_ROUND_UP (sizeof (struct msg_que)) + 	        nMsgs * MEM_ROUND_UP (msgSize + sizeof (struct sll_node)));    if (pQMem == NULL)	{	errno = ENOSPC;	return ((mqd_t) -1);	}    if ((pMqDesc = (mqd_t) objAlloc (mqClassId)) == NULL)	{	free (pQMem);       	errno = ENOSPC;       	return ((mqd_t) -1);	}    mq_init (pQMem, nMsgs, msgSize);    pMqDesc->f_flag = FREAD | FWRITE;    pMqDesc->f_data = pQMem;    pMqDesc->f_data->msgq_links++;    objCoreInit (&pMqDesc->f_objCore, mqClassId);	/* valid file obj */    return (pMqDesc);    }/********************************************************************************* mq_open - open a message queue (POSIX)** This routine establishes a connection between a named message queue and the* calling task.  After a call to mq_open(), the task can reference the* message queue using the address returned by the call.  The message queue* remains usable until the queue is closed by a successful call to mq_close().** The <oflags> argument controls whether the message queue is created or merely* accessed by the mq_open() call.  The following flag bits can be set* in <oflags>:* .iP O_RDONLY* Open the message queue for receiving messages.  The task can use the * returned message queue descriptor with mq_receive(), but not mq_send().* .iP O_WRONLY* Open the message queue for sending messages.  The task can use the* returned message queue descriptor with mq_send(), but not mq_receive().* .iP O_RDWR* Open the queue for both receiving and sending messages.  The task can use* any of the functions allowed for O_RDONLY and O_WRONLY.* .LP** Any combination of the remaining flags can be specified in <oflags>:* .iP O_CREAT* This flag is used to create a message queue if it does not already exist.* If O_CREAT is set and the message queue already exists, then O_CREAT has* no effect except as noted below under O_EXCL.  Otherwise, mq_open()* creates a message queue.  The O_CREAT flag requires a third and fourth* argument: <mode>, which is of type `mode_t', and <pAttr>, which is of type* pointer to an `mq_attr' structure.  The value of <mode> has no effect in* this implementation.  If <pAttr> is NULL, the message queue is created* with implementation-defined default message queue attributes.  If <pAttr>* is non-NULL, the message queue attributes `mq_maxmsg' and `mq_msgsize' are* set to the values of the corresponding members in the `mq_attr' structure* referred to by <pAttr>; if either attribute is less than or equal to zero,* an error is returned and errno is set to EINVAL.* .iP O_EXCL* This flag is used to test whether a message queue already exists.* If O_EXCL and O_CREAT are set, mq_open() fails if the message queue name* exists.* .iP O_NONBLOCK* The setting of this flag is associated with the open message queue descriptor* and determines whether a mq_send() or mq_receive() will wait for resources* or messages that are not currently available, or fail with errno set * to EAGAIN.  * .LP** The mq_open() call does not add or remove messages from the queue.** NOTE:* Some POSIX functionality is not yet supported:**     - A message queue cannot be closed with calls to _exit() or exec().*     - A message queue cannot be implemented as a file.*     - Message queue names will not appear in the file system.** RETURNS: A message queue descriptor, otherwise -1 (ERROR).** ERRNO: EEXIST, EINVAL, ENOENT, ENOSPC** SEE ALSO: mq_send(), mq_receive(), mq_close(), mq_setattr(), mq_getattr(),* mq_unlink()**/ mqd_t mq_open    (    const char	*mqName,	/* name of queue to open */    int		oflags,		/* open flags */    ...				/* extra optional parameters */    )    {    va_list		vaList;		/* arg list (if O_CREAT) */    struct mq_des *	pMqDesc;	/* memory for queue descriptor */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -