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

📄 aiosysdrv.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    }	if (aioSysBlockingDev (fd) && aioSysOpWillBlock (fd, op))	    {	    /* If the device is a blocking device and the requested	     * operation will block, then move it from the work queue to 	     * to the wait queue, and notify the aioWaitTask of new waiter.	     */	    semGive (&aioIOSem);    	    IOQ_LOCK (&pDev->ioQ);	    IOQ_WORK_DELETE (&pDev->ioQ, &pReq->ioNode);	    IOQ_WAIT_ADD (&pDev->ioQ, &pReq->ioNode, pReq->ioNode.prio);	    pReq->state = AIO_WAIT;			/* wait state */    	    IOQ_UNLOCK (&pDev->ioQ);	    waitMsg.op = IO_OP (op);	    waitMsg.fd = fd;	    write (aioSysFd, (char *) &waitMsg, sizeof (WAIT_MSG));	    continue;	    }	/* Perform the requested I/O */ 	switch (op)	    {	    case IO_READ:	    	retVal = aioSysRead (pReq->pAiocb, &errorVal); 		break;	    case IO_WRITE:            	retVal = aioSysWrite (pReq->pAiocb, &errorVal);		break;		    default:	    	retVal   = ERROR;	    	errorVal = EINVAL;		break;	    }	semGive (&aioIOSem);	/* Mark request as completed and send the request back to aioLib */    	IOQ_LOCK (&pDev->ioQ);	AIO_DONE_SET (pReq->pAiocb, retVal, errorVal);        IOQ_WORK_DELETE (&pDev->ioQ, &pReq->ioNode);	IOQ_UNLOCK (&pDev->ioQ);	ioQNodeDone (&pReq->ioNode);        }    }/******************************************************************************* aioSysSyncReq - synchronize an AIO request ** This routine attempts to synchronize the AIO request <pReq> to the * synchronized I/O completion state.* * RETURNS: OK if successful, ERROR otherwise.*/LOCAL STATUS aioSysSyncReq    (    AIO_DEV *		pDev,			/* AIO device */    AIO_SYS *		pReq			/* AIO request */    )    {    int			errorVal;		/* error value */    IO_Q *		pQ = &pDev->ioQ;	/* I/O queue */    STATUS 		retVal = OK;		/* return value */    if ((pReq->state == AIO_QUEUED) && (pReq->ioNode.op == IO_WRITE))	{	if (aioSysWrite (pReq->pAiocb, &errorVal) == ERROR)	    retVal = ERROR;			/* write failed */   	/* complete the AIO operation */        AIO_DONE_SET (pReq->pAiocb, retVal, errorVal);        IOQ_LOCK (pQ);	IOQ_WORK_DELETE (pQ, &pReq->ioNode);    	IOQ_UNLOCK (pQ);	ioQNodeDone (&pReq->ioNode);	}    return (retVal);    }/******************************************************************************* aioSysWrite - AIO system driver write routine ** This routine performs a write call for the AIO request <pAiocb>.** RETURNS: return value for the write call. ** INTERNAL* POSIX says that writes can append to the file if O_APPEND is set* for the file.  When we implement O_APPEND, the following code will * need to be changed.*/    LOCAL STATUS aioSysWrite    (    struct aiocb *	pAiocb,			/* AIO control block */    int *		pError    )    {    int			retVal = ERROR;		/* return value */    /* lseek protected by aioIOSem */    lseek (pAiocb->aio_fildes, pAiocb->aio_offset, SEEK_SET);     retVal = write (pAiocb->aio_fildes, (char *) pAiocb->aio_buf, 		    pAiocb->aio_nbytes);     if (aioSysPrintRtn != NULL)	(* aioSysPrintRtn) 	    ("aioSysWrite:fd (%d) wrote %d bytes buffer 0x%x loc %d \n", 	     pAiocb->aio_fildes, retVal, pAiocb->aio_buf, pAiocb->aio_offset);    *pError = (retVal == ERROR) ? errno : 0;    return (retVal);     }/******************************************************************************* aioSysRead - AIO system driver read routine** This routine performs a read call for the AIO request <pAiocb>.** RETURNS:  return value from the read call. */LOCAL STATUS aioSysRead     (    struct aiocb *	pAiocb,			/* AIO control block */    int *		pError    )    {    int			retVal = ERROR;		/* return value */    /* lseek protected by aioIOSem */    lseek (pAiocb->aio_fildes, pAiocb->aio_offset, SEEK_SET);     retVal = read (pAiocb->aio_fildes, (char *) pAiocb->aio_buf, 		   pAiocb->aio_nbytes);    if (aioSysPrintRtn != NULL)	(* aioSysPrintRtn) 	    ("aioSysRead:fd (%d) read %d bytes buffer 0x%x loc %d \n", 	     pAiocb->aio_fildes, retVal, pAiocb->aio_buf, pAiocb->aio_offset);    *pError = (retVal == ERROR) ? errno : 0;    return (retVal);     }/********************************************************************************* aioWaitTask - AIO wait task** The AIO wait task is responsible for managing the AIO requests that are* are in AIO_WAIT state.  These are requests that can not be completed * immediately because they are waiting for I/O on blocking devices.  * When data becomes available on a file descriptor, the aioWaitTask finds* the waiting request and moves it back to the work queue to be executed* by the aioIoTask.** RETURNS: N/A* NOMANUAL*/void aioWaitTask (void)    {    int			ndone;				/* num done */    WAIT_MSG 		waitMsg;			/* control message */    IO_Q *		pIoQ = &aioDev.ioQ;		/* I/O queue */    /* clear out the file descriptors - set control fd */    FD_ZERO (&ioFds.ioWait [READ_OP]);    FD_ZERO (&ioFds.ioWait [WRITE_OP]);    FD_SET (aioSysFd, &ioFds.ioWait [READ_OP]);    FOREVER 	{	ioFds.io [READ_OP] = ioFds.ioWait [READ_OP];	ioFds.io [WRITE_OP] = ioFds.ioWait [WRITE_OP];	/* Wait for data and/or control messages */	ndone = select (FD_SETSIZE, &ioFds.io [READ_OP], &ioFds.io [WRITE_OP], 			NULL, NULL);  	if (FD_ISSET (aioSysFd, &ioFds.io [READ_OP]))	    {	    	    /* Got a control message with new fd to wait on */	    read (aioSysFd, (caddr_t) &waitMsg, sizeof (WAIT_MSG));	    if (aioSysPrintRtn != NULL)		(* aioSysPrintRtn) ("aioWaitTask: control op %s fd %d\n",  			            (waitMsg.op == READ_OP) ? "read" : "write",				    waitMsg.fd);	    	    /* mask in the new fd to wait on */	    FD_SET (waitMsg.fd, &ioFds.ioWait [waitMsg.op]);		    	    if (--ndone == 0)		continue;			/* only got control info */	    }	/* Data became available.  Find the request(s) this will satisfy */    	IOQ_LOCK (pIoQ);	FD_ZERO (&ioFds.ioWait [READ_OP]);	FD_ZERO (&ioFds.ioWait [WRITE_OP]);        ioQEach (&pIoQ->waitQ, aioSysWaitFind, (int) pIoQ, 0);	IOQ_UNLOCK (pIoQ);        FD_SET (aioSysFd, &ioFds.ioWait [READ_OP]);	/* add control fd */	}    }/******************************************************************************* aioSysBlockingDev - check if a device is a blocking device** This routine determines if the device associated with file descriptor* <fd> is a blocking (select) device.** RETURNS: TRUE if the device supports select, FALSE otherwise.* NOMANUAL*/BOOL aioSysBlockingDev    (    int 		fd 			/* file descriptor */    )    {    fd_set		readFds;		/* read fds */    BOOL		selectDev;		/* device supports select */    int			flags;			/* driver flags */    struct timeval	timeOut = {0, 0};	/* timeout */    if (aioDrvFlagsGet (fd, &flags) == ERROR)	return (FALSE);    /* check flags if we already know this information */    if (flags & DRV_NOSELECT)	return (FALSE);					/* no select */    if (flags & DRV_SELECT)	return (TRUE);					/* has select */    /* Poll driver to see if select fails */    FD_ZERO (&readFds);    FD_SET (fd, &readFds);    selectDev = select (FD_SETSIZE, &readFds, NULL, NULL, &timeOut) == ERROR ?		FALSE : TRUE;    aioDrvFlagsSet (fd, selectDev ? DRV_SELECT : DRV_NOSELECT);    return (selectDev);    }/********************************************************************************* aioSysOpWillBlock - requested operation will block** This routine determines if the the operation specified by <op> will block* on the device associated with file descriptor <fd>.** RETURNS: TRUE if the operation will block, FALSE otherwise.*/LOCAL BOOL aioSysOpWillBlock     (    int			fd,			/* file descriptor */    int			op			/* operation */    )    {    fd_set		readFds;		/* read fds */    fd_set		writeFds;		/* write fds */    struct timeval	timeOut = {0, 0};	/* timeout */        /* Poll the device to see if the requested operation will block */    FD_ZERO (&readFds);     FD_ZERO (&writeFds);    FD_SET (fd, (op == IO_READ) ? &readFds : &writeFds);    return ((select (FD_SETSIZE, &readFds, &writeFds, NULL, &timeOut) == 0) ? 	    TRUE : FALSE);    }/********************************************************************************* aioSysWaitFind - find waiting requests (each routine)** This routine gets called once for each AIO request in the wait queue.* It looks at the AIO request <pReq> to determine if the waiting request may * have been satisfied by the recent wake up.  It also reconstructs the * file descriptors for the aioWaitTask to select on.*  * RETURNS: TRUE*/LOCAL BOOL aioSysWaitFind    (    AIO_SYS *		pReq,			/* AIO request */    IO_Q *		pQ,			/* I/O queue */    int			bogus			/* not used */    )    {    int			op;			/* operation */    int			fd; 			/* file descriptor */    op = IO_OP (pReq->ioNode.op);    fd = pReq->pAiocb->aio_fildes;    if (FD_ISSET (fd, &ioFds.io [op]))	{	/* Request may have been satisfied, move it from the 	 * wait queue to the work queue and notify the I/O tasks 	 * of new work. 	 */	IOQ_WAIT_DELETE (pQ, &pReq->ioNode);    	IOQ_WORK_ADD (pQ, &pReq->ioNode, pReq->ioNode.prio);    	pReq->pAiocb->aio_sys.state = AIO_QUEUED;	FD_CLR (fd, &ioFds.io [op]);        semGive (&aioSysWorkSem);			/* notify i/o task */	}    else    	FD_SET (fd, &ioFds.ioWait [op]);    return (TRUE);					/* do entire list */    }

⌨️ 快捷键说明

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