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

📄 pipedrv.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
* EMFILE                    - pipe still has other openings* EBUSY                     - pipe is selected by at least one pending task*/STATUS pipeDevDelete    (    char * name,	/* name of pipe to be deleted */    BOOL   force	/* if TRUE, force pipe deletion */    )    {    FAST PIPE_DEV *   pPipeDev;    char *            pTail = NULL;    SEL_WAKEUP_NODE * pNode = NULL;    /* can't be called from ISR */    if (INT_RESTRICT () != OK)        {        return (ERROR);        }    /* driver must be initialized */    if (pipeDrvNum == ERROR)        {        errno = S_ioLib_NO_DRIVER;        return (ERROR);        }    /* get pointer to pipe device descriptor */    if ((pPipeDev = (PIPE_DEV *) iosDevFind (name, &pTail)) == NULL)        {	return (ERROR);        }    /* if not forced, check for other opens and non-empty select list */    if (!force)        {        if (pPipeDev->numOpens != 0)            {            errno = EMFILE;            return (ERROR);            }        if (selWakeupListLen (&pPipeDev->selWakeupList) != 0)            {            errno = EBUSY;            return (ERROR);            }        }    /* I/O device no longer in system */    iosDevDelete (&pPipeDev->devHdr);    /* force clearing of any select list */    if(force && (selWakeupListLen (&pPipeDev->selWakeupList) != 0))        {        pNode = (SEL_WAKEUP_NODE *)lstFirst ((LIST *)&pPipeDev->selWakeupList);        do            {            selNodeDelete (&pPipeDev->selWakeupList, pNode);            } while ((pNode = (SEL_WAKEUP_NODE *) lstNext ((NODE *)pNode))                           != NULL);        lstFree ((LIST *)&pPipeDev->selWakeupList);        selWakeupListTerm (&pPipeDev->selWakeupList);        }    /* terminate message queue */    msgQTerminate (&pPipeDev->msgQ);    /* free pipe memory */    KHEAP_FREE ((char *)pPipeDev);    return (OK);    }/* routines supplied to I/O system *//********************************************************************************* pipeOpen - open a pipe file** This routine is called to open a pipe.  It returns a pointer to the* device.  This routine is normally reached only via the I/O system.** RETURNS  pPipeDev or ERROR if pipe has not been created by pipeDevCreate().*/LOCAL int pipeOpen    (    PIPE_DEV * pPipeDev,	/* pipe descriptor */    char *     name,    int        flags,    int        mode    )    {    if ((name != NULL) && (strlen (name) > 0))	{	/* Only the first part of the name match with the driver's name */ 	errnoSet (S_ioLib_NO_DEVICE_NAME_IN_PATH);	return (ERROR);	}    else	{	/* track number of openings to pipe */	++pPipeDev->numOpens;    	return ((int) pPipeDev);	}    }/********************************************************************************* pipeClose - close a pipe file** This routine is called to close a pipe.  This routine is normally reached* only via the I/O system.** RETURNS  OK or ERROR if NULL pipe device pointer.*/LOCAL int pipeClose    (    PIPE_DEV * pPipeDev		/* pipe descriptor */    )    {    if (pPipeDev != NULL)	{	/* decrement the open counter, but not past zero */ 	if (pPipeDev->numOpens > 0)	  --pPipeDev->numOpens;	return (OK);	}    else	{    	return (ERROR);	}    }/********************************************************************************* pipeRead - read bytes from a pipe** This routine reads up to maxbytes bytes of the next message in the pipe.* If the message is too long, the additional bytes are just discarded.** RETURNS:*  number of bytes actually read;*  will be between 1 and maxbytes, or ERROR*/LOCAL int pipeRead    (    FAST PIPE_DEV * pPipeDev,	/* pointer to pipe descriptor */    char *          buffer,	/* buffer to receive bytes */    unsigned int    maxbytes	/* max number of bytes to copy into buffer */    )    {    int nbytes;    /* wait for something to be in pipe */    nbytes = msgQReceive (&pPipeDev->msgQ, buffer, maxbytes, WAIT_FOREVER);    if (nbytes == ERROR)	return (ERROR);    /* wake up any select-blocked writers */    selWakeupAll (&pPipeDev->selWakeupList, SELWRITE);    return (nbytes);    }/********************************************************************************* pipeWrite - write bytes to a pipe** This routine writes a message of `nbytes' to the pipe.** RETURNS: number of bytes written or ERROR*/LOCAL int pipeWrite    (    FAST PIPE_DEV * pPipeDev,	/* pointer to pipe descriptor */    char *          buffer,	/* buffer from which to copy bytes */    int             nbytes	/* number of bytes to copy from buffer */    )    {    if (!INT_CONTEXT ())	TASK_LOCK ();				/* LOCK PREEMPTION */    /*      * We lock preemption so after we send the message we can guarantee that     * we get to the selWakeupAll() call before unblocking any readers.  This     * is to avoid a race in which a higher priority reader of the pipe is     * unblocked by the msgQSend() below and subsequently enters and blocks     * in a call to select(), only to be inadvertently awakened when we return     * here and call selWakeupAll().  To minimize preemption latency we     * release the preemption lock after we obtain the selWakeupList mutual     * exclusion semaphore.  This semaphore is a mutual exclusion semaphore     * which allows recursive takes.  Avoiding a preemption lock by utilizing     * the selWakeupList semaphore as the only means of mutual exclusion is     * not viable because deadlock can occur by virtue of the fact that     * msgQSend() can block if the the message queue is full at which time a     * call to select() could block waiting for the listMutex instead of     * returning that a read is OK.  A problem this approach does not account     * for is the possibility that the selWakeupList semaphore is unavailable     * when the semTake() is attempted below.  If this were the case, the     * task could be preempted and therefore be vulnerable to the same     * scenario outlined above.       */    if (msgQSend (&pPipeDev->msgQ, buffer, (UINT) nbytes,		  INT_CONTEXT() ? NO_WAIT : WAIT_FOREVER, MSG_PRI_NORMAL) != OK)	{	if (!INT_CONTEXT ())	    TASK_UNLOCK ();			/* UNLOCK PREEMPTION */	return (ERROR);	}    if (!INT_CONTEXT ())	{	semTake (&pPipeDev->selWakeupList.listMutex, WAIT_FOREVER);	TASK_UNLOCK ();				/* UNLOCK PREEMPTION */	}    /* wake up any select-blocked readers */    selWakeupAll (&pPipeDev->selWakeupList, SELREAD);    if (!INT_CONTEXT ())	semGive (&pPipeDev->selWakeupList.listMutex);    return (nbytes);    }/********************************************************************************* pipeIoctl - do device specific control function** The ioctl requests recognized are FIONREAD, FIONMSGS, and FIOFLUSH.** RETURNS:*  OK and `argptr' gets number of bytes in pipe, or*  ERROR if request is not FIONREAD, FIONMSGS, or FIOFLUSH.*/LOCAL STATUS pipeIoctl    (    FAST PIPE_DEV *pPipeDev,	/* pointer to pipe descriptor */    int           request,	/* ioctl code */    int           *argptr	/* where to send answer */    )    {    STATUS	status = OK;    MSG_Q_INFO	msgQInfo;    SEL_WAKEUP_NODE * wakeNode = (SEL_WAKEUP_NODE *) argptr;    switch (request)	{	case FIONREAD:	    /* number of bytes in 1st message in the queue */	    bzero ((char *) &msgQInfo, sizeof (msgQInfo));	    msgQInfo.msgListMax	= 1;	    msgQInfo.msgLenList	= argptr;	    *argptr = 0;	    msgQInfoGet (&pPipeDev->msgQ, &msgQInfo);	    break;	case FIONMSGS:	    /* number of messages in pipe */	    *argptr = msgQNumMsgs (&pPipeDev->msgQ);	    break;	case FIOFLUSH:	    /* discard all outstanding messages */	    taskLock ();	    while (msgQReceive (&pPipeDev->msgQ, (char *) NULL, 0, NO_WAIT) !=									ERROR)		;	    taskUnlock ();	    break;	case FIOSELECT:	    selNodeAdd (&pPipeDev->selWakeupList, (SEL_WAKEUP_NODE *) argptr);	    switch (wakeNode->type)		{		case SELREAD:		    if (msgQNumMsgs (&pPipeDev->msgQ) > 0)		        selWakeup ((SEL_WAKEUP_NODE *) argptr);		    break;		    		case SELWRITE:		    if (pPipeDev->msgQ.maxMsgs >			msgQNumMsgs (&pPipeDev->msgQ))		        selWakeup ((SEL_WAKEUP_NODE *) argptr);                    break;		}            break;        case FIOUNSELECT:	    selNodeDelete (&pPipeDev->selWakeupList, (SEL_WAKEUP_NODE *)argptr);            break;	default:	    status = ERROR;	    errnoSet (S_ioLib_UNKNOWN_REQUEST);	    break;	}    return (status);    }

⌨️ 快捷键说明

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