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

📄 aiopxlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    pReq->state = AIO_COMPLETED;    taskUnlock ();    }/******************************************************************************** * aioClustRet - return a cluster** This routine frees <pClust> and  signals/wakes up the initiating task if* <pAiocb> is the last AIO request in the cluster.** RETURN: N/A** NOMANUAL*/LOCAL void aioClustRet    (    struct aiocb  *	pAiocb,			/* AIO control block */    AIO_CLUST *		pClust			/* AIO cluster */    )    {    BOOL		returnClust;		/* cluster goes to table */     int			signo;			/* signal number */    int			taskId;			/* lio_listio() task */    if (pClust == NULL)	return;     mutex_lock (&pClust->lock);    returnClust = ((pClust->refCnt > 0) && (--pClust->refCnt == 0));    mutex_unlock (&pClust->lock);    /* If we are the last one in the cluster.  Signal/wake up the caller     * and return the cluster.     */    if (returnClust)	{	signo = pClust->sigpend.sigp_info.si_signo;	taskId  = pAiocb->aio_sys.ioNode.taskId;	if (aioPrintRtn != NULL)	    (* aioPrintRtn) ("clust done signal (%d) to task %x\n", signo, 			     taskId, 0, 0, 0, 0);		/* send the user defined signal */	if (signo != 0)	    {	    sigPendKill (taskId, &pClust->sigpend);	    }	else	    {	    /* wake up waiting process */	    cond_signal (&pClust->wake);	    }	pClust->inuse = FALSE;		/* free cluster */	}    } /* DRIVER INTERFACE ROUTINES *//******************************************************************************** * aioDrvInstall - install an AIO driver ** This routine is called by an I/O driver to specify it supports AIO and * to insert it's AIO routines into the AIO driver table.  <drvnum> is * the driver number to install.   <pInsert> is the AIO insert routine.* <pIoctl> the the AIO ioctl routine.  <flags> gets filled into the * driver specific flags member of the AIO_DRV_ENTRY structure.  ** RETURNS: OK if successful, otherwise ERROR.** ERRNO: S_aioPxLib_DRV_NUM_INVALID** INTERNAL:  The aioDrvTable is similar to the drvTable in iosLib.  * aioDrvTable (and this routine) might go away if aioLib is more * integrated into iosLib.   Don't man this page until driver interface* is documented and supported.** NOMANUAL*/STATUS aioDrvInstall     (    int		drvnum,				/* driver number */    FUNCPTR	pInsert,			/* insert routine */    FUNCPTR	pIoctl,				/* ioctl routine */    int		flags				/* driver flags */    )    {    AIO_LOCK ();    if ((drvnum < 0) || (drvnum >= maxDrivers) || aioDrvTable [drvnum].inuse)	{	errno = S_aioPxLib_DRV_NUM_INVALID;	return (ERROR);				/* invalid driver number */	}    aioDrvTable [drvnum].insert = pInsert;	/* add to driver table */    aioDrvTable [drvnum].ioctl  = pIoctl;    aioDrvTable [drvnum].flags  = flags;    AIO_UNLOCK ();    return (OK);    }/******************************************************************************** * aioDrvFlagsGet - get AIO driver flags** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS aioDrvFlagsGet     (    int			fd, 			/* file descriptor */    int *		pFlags			/* return flags */    )    {    AIO_FD_ENTRY * 	pEntry; 		/* fd entry */    if ((pEntry = aioEntryFind (fd)) == NULL)	return (ERROR); 			/* error condition */    *pFlags = aioDrvTable [pEntry->drv_num].flags;    return (OK);    }/******************************************************************************** * aioDrvFlagsSet - set AIO driver flags** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS aioDrvFlagsSet    (    int			fd, 			/* file descriptor */    int			flags			/* flags to set */    )    {    AIO_FD_ENTRY * 	pEntry; 		/* fd entry */    if ((pEntry = aioEntryFind (fd)) == NULL)	return (ERROR); 			/* error condition */    aioDrvTable [pEntry->drv_num].flags |= flags;    return (OK);     }/******************************************************************************** * aioNext - obtain next AIO request to initiate** This routine obtains the next available AIO request in the work queue. * It finds the first request where the state is AIO_QUEUED. ** RETURNS: pointer to next queued AIO control block or NULL** NOMANUAL*/AIO_SYS * aioNext    (    AIO_DEV *		pDev				/* AIO device */    )    {    AIO_SYS *		pReq = NULL;			/* AIO request */    LIST *		pWorkQ = &pDev->ioQ.workQ;	/* work queue */    IOQ_LOCK (&pDev->ioQ);    for (pReq = (AIO_SYS *) lstFirst (pWorkQ); (pReq != NULL); 	 pReq = (AIO_SYS *) lstNext (&pReq->ioNode.node))	{	if (pReq->state == AIO_QUEUED) 	    {	    pReq->state = AIO_RUNNING;	    break;	    }	}    IOQ_UNLOCK (&pDev->ioQ);    return (pReq);    }/******************************************************************************* aioCancel - cancel an AIO request ** This routine tries to cancel an AIO request.  If the state of the AIO* request is not running, the request is deleted from the work queue * <pDev->workQ> and completed with a return value of -1 and an error * value of ECANCELED.** RETURNS: ERROR if request is RUNNING, otherwise OK.** NOMANUAL*/STATUS aioCancel    (    AIO_DEV *		pDev,			/* AIO device */    struct aiocb *	pAiocb			/* AIO control block */    )    {    int			state;			/* state */    IO_Q *		pQ = &pDev->ioQ;	/* queue */    AIO_SYS *		pReq = &pAiocb->aio_sys;/* AIO request */    IOQ_LOCK (pQ);				/* lock the ioQ */    state = pReq->state;    if (state == AIO_RUNNING)	{	IOQ_UNLOCK (pQ);        return (ERROR);				/* can't cancel running */	}    if (state == AIO_QUEUED) 	IOQ_WORK_DELETE (pQ, &pReq->ioNode);    else	{	if (state == AIO_WAIT)	    IOQ_WAIT_DELETE (pQ, &pReq->ioNode);	}    AIO_DONE_SET (pAiocb, ERROR, ECANCELED);	/* mark it as cancelled */    IOQ_UNLOCK (pQ);				/* unlock ioQ */    ioQNodeDone (&pReq->ioNode);    return (OK);    }/******************************************************************************* aioPush - push a queued request to head of work queue.** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS aioPush     (    AIO_DEV *		pDev,			/* AIO device */    struct aiocb *	pAiocb			/* AIO request */    )    {    IO_Q *		pQ    = &pDev->ioQ;    IO_NODE *		pNode = &pAiocb->aio_sys.ioNode;    IOQ_LOCK (pQ);    if (pAiocb->aio_state == AIO_QUEUED)	{	IOQ_WORK_DELETE (pQ, pNode);	IOQ_WORK_ADD_HEAD (pQ, pNode);	}        IOQ_UNLOCK (pQ);    return (OK);    }/******************************************************************************* aioSync - synchronize** This routine synchronizes all AIO requests assoicated with file descriptor* <pAiocb->aio_fildes>.  <syncReqRtn> specifies a driver provided * synchronization routine that gets called for each request associated with * the above specified file.  After each AIO request has been synchronized,* it is returned to the library via aioDone.** RETURNS: OK, or ERROR if couldn't find entry.** NOMANUAL*/STATUS aioSync     (    AIO_DEV *		pDev,			/* AIO device */    struct aiocb * 	pAiocb,			/* aio control block */    FUNCPTR		syncReqRtn		/* routine to sync a request */    )    {    FAST AIO_FD_ENTRY * pEntry;			/* fd entry */    ARGS 		args;    int			fd = pAiocb->aio_fildes;    if ((pEntry = aioEntryFind (fd)) == NULL)	return (ERROR);    args.pDev     = pDev;			/* device */    args.retVal   = OK;				/* return */    args.errorVal = 0;				/* errno */    args.syncRtn  = syncReqRtn;    semTake (&pEntry->ioQSem, WAIT_FOREVER);    dllEach (&pEntry->ioQ, aioSyncNode, (int) &args);    semGive (&pEntry->ioQSem);    if (ioctl (fd, FIOSYNC, 0) == ERROR)    	ioctl (fd, FIOFLUSH, 0);    /* one for the  aio_fsync() request */    IOQ_LOCK (&pDev->ioQ);    AIO_DONE_SET (pAiocb, args.retVal, args.errorVal);    IOQ_WORK_DELETE (&pDev->ioQ, &pAiocb->aio_sys.ioNode);    IOQ_UNLOCK (&pDev->ioQ);    ioQNodeDone (&pAiocb->aio_sys.ioNode);    return (OK);    }/******************************************************************************* aioSyncNode - synchronize an AIO request* * This routine gets called from aioSync for each AIO request on the fd list.* It calls the driver provided sync routine for each request whose * state is not completed. */LOCAL STATUS aioSyncNode    (    DL_NODE *		pFdNode,		/* node on fd list */    ARGS *		pArgs			/* arguments */    )    {    AIO_SYS *		pReq;			/* AIO request */    BOOL		retVal = TRUE;		/* return value */    pReq = FD_NODE_TO_SYS (pFdNode);     if (pReq->state != AIO_COMPLETED)	{    	if (((* pArgs->syncRtn) (pArgs->pDev, pReq)) == ERROR)	    {	    pArgs->retVal = ERROR;	    pArgs->errorVal = errno;  	    retVal = FALSE;  	    }	}    return (retVal);    }/* The following routines are support routines for iosLib.  They wont  * be needed if fully integerated into the I/O system. *//******************************************************************************* aioFdNew - initialize an AIO file descriptor** This routine gets called from iosFdNew when allocating a new file* descriptor. ** RETURNS: N/A*/LOCAL void aioFdNew    (    int			fd			/* file descriptor */    )    {    AIO_FD_ENTRY *	pEntry 	 = &aioFdTable [STD_UNFIX(fd)];    semTake (&pEntry->ioQSem, WAIT_FOREVER);    dllInit (&pEntry->ioQ);    pEntry->ioQActive = TRUE;    semGive (&pEntry->ioQSem);    }/******************************************************************************* aioFdFree - free a file descriptor** This routine gets called from iosFdFree after closing a file descriptor. * It cancels (or waits for, if it can't cancel) all the outstanding AIO* submitted to file descriptor <fd>.** RETURNS: N/A*/LOCAL void aioFdFree    (    int			fd			/* file descriptor */    )    {    AIO_SYS *		pReq;			/* AIO request */    DL_NODE *		pNode;			/* fd node */    FAST AIO_FD_ENTRY *	pEntry = &aioFdTable [STD_UNFIX(fd)];    semTake (&pEntry->ioQSem, WAIT_FOREVER);    FOREVER 	{	if ((pNode = DLL_FIRST (&pEntry->ioQ)) == NULL)	    break;				/* list empty */        	pReq = FD_NODE_TO_SYS (pNode);	/* Try to cancel it.  If can't, then wait for it */	if (aio_cancel (fd, pReq->pAiocb) == AIO_NOTCANCELED)	    aio_suspend ((const struct aiocb **) &pReq->pAiocb, 1, 			 (const struct timespec *) NULL);	dllRemove (&pEntry->ioQ, pNode);	/* remove it */	}        pEntry->ioQActive = FALSE;    semGive (&pEntry->ioQSem);    }/******************************************************************************* aioEntryFind - find the aio fd entry** aiEntryFind validates <fd> and finds the AIO_FD_ENTRY associated with* <fd>. ** RETURNS: a pointer to the AIO_FD_ENTRY or NULL if error.** NOMANUAL*/AIO_FD_ENTRY * aioEntryFind     (    int 		fd			/* file descriptor */    )    {    int			xfd = STD_MAP (fd);	/* mapped fd */    if (FD_CHECK (xfd) == NULL)	{	errno = EBADF;	return (NULL);				/* file descriptor invalid */	}    return (&aioFdTable [xfd]);	    }

⌨️ 快捷键说明

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