Beispiel #1
0
/*********************************************************************************************************
** 函数名称: aio_fsync
** 功能描述: aio 同步文件的内容, 将缓冲内部的数据写入文件
** 输 入  : op                操作选项 (O_SYNC or O_DSYNC)
**           paiocb            aio 请求控制块
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  aio_fsync (int op, struct aiocb *paiocb)
{
    INT     iRet;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */

    if (!paiocb) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    paiocb->aio_lio_opcode = LIO_SYNC;
    
    paiocb->aio_req.aioreq_thread = API_ThreadIdSelf();
    paiocb->aio_pwait = LW_NULL;
    
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    iRet = __aioEnqueue(paiocb);
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
    
    return  (iRet);
}
Beispiel #2
0
/*********************************************************************************************************
** 函数名称: __aioCancelFd
** 功能描述: 取消一个 AIO_REQ_CHAIN 节点, 
** 输 入  : paiorc            AIO_REQ_CHAIN 节点
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  __aioCancelFd (AIO_REQ_CHAIN  *paiorc)
{
    API_SemaphoreMPend(paiorc->aiorc_mutex, LW_OPTION_WAIT_INFINITE);
    __aioRemoveAllAiocb(paiorc, PX_ERROR, ECANCELED);                   /*  删除所有同文件描述符节点    */
    paiorc->aiorc_iscancel = 1;
    API_ThreadCondSignal(&paiorc->aiorc_cond);                          /*  通知代理线程删除 aiorc      */
    API_SemaphoreMPost(paiorc->aiorc_mutex);
}
/*********************************************************************************************************
** 函数名称: __pthread_rwlock_init_invisible
** 功能描述: 读写锁隐形创建. (静态初始化)
** 输 入  : prwlock        句柄
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static void  __pthread_rwlock_init_invisible (pthread_rwlock_t  *prwlock)
{
    if (prwlock) {
        if (prwlock->PRWLOCK_ulMutex == LW_OBJECT_HANDLE_INVALID) {
            API_SemaphoreMPend(_G_ulPRWLockInitLock, LW_OPTION_WAIT_INFINITE);
            if (prwlock->PRWLOCK_ulMutex == LW_OBJECT_HANDLE_INVALID) {
                pthread_rwlock_init(prwlock, LW_NULL);
            }
            API_SemaphoreMPost(_G_ulPRWLockInitLock);
        }
    }
}
Beispiel #4
0
/*********************************************************************************************************
** 函数名称: __aioAttachWait
** 功能描述: 向指定的 aiocb 中连接 wait 信息 (这里必须锁定 _G_aioqueue)
** 输 入  : paiocb            指定的 aiocb 
**           paiowait          wait 信息
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
INT  __aioAttachWait (const struct aiocb  *paiocb, struct aiowait  *paiowait)
{
    PLW_LIST_LINE   plineTempAiorc;
    PLW_LIST_LINE   plineTempAiocb;
    
    AIO_REQ_CHAIN   *paiorc;
    struct aioreq   *paioreqTemp;
    struct aiocb    *paiocbTemp;
    
    BOOL             bIsOk = LW_FALSE;
    
    for (plineTempAiorc  = _G_aioqueue.aioq_plinework;
         plineTempAiorc != LW_NULL;
         plineTempAiorc  = _list_line_get_next(plineTempAiorc)) {
         
        paiorc = _LIST_ENTRY(plineTempAiorc, AIO_REQ_CHAIN, aiorc_line);
        if (paiorc->aiorc_fildes == paiocb->aio_fildes) {
            API_SemaphoreMPend(paiorc->aiorc_mutex, LW_OPTION_WAIT_INFINITE);
            for (plineTempAiocb  = paiorc->aiorc_plineaiocb;
                 plineTempAiocb != LW_NULL;
                 plineTempAiocb  = _list_line_get_next(plineTempAiocb)) {
                 
                paioreqTemp = _LIST_ENTRY(plineTempAiocb, struct aioreq, aioreq_line);
                paiocbTemp  = _LIST_ENTRY(paioreqTemp, struct aiocb, aio_req);
                
                if (paiocbTemp == paiocb) {
                    if (paiocbTemp->aio_pwait) {                        /*  不允许重复保存              */
                        API_SemaphoreMPost(paiorc->aiorc_mutex);
                        return  (PX_ERROR);
                    }
                    paiocbTemp->aio_pwait  = paiowait;
                    paiowait->aiowt_paiocb = paiocbTemp;
                    bIsOk = LW_TRUE;
                    break;
                }
            }
            API_SemaphoreMPost(paiorc->aiorc_mutex);
            break;
        }
    }
Beispiel #5
0
/*********************************************************************************************************
** 函数名称: __aioDeleteFd
** 功能描述: 从指定的 AIO_REQ_CHAIN 中删除一个 AIO_REQ_CHAIN 节点 (这里必须锁定 _G_aioqueue)
** 输 入  : paiorc            AIO_REQ_CHAIN 节点
**           pplineHeader      创建后加入的链表表头地址
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID  __aioDeleteFd (AIO_REQ_CHAIN  *paiorc, LW_LIST_LINE_HEADER  *pplineHeader)
{
    API_SemaphoreMPend(paiorc->aiorc_mutex, LW_OPTION_WAIT_INFINITE);
    __aioRemoveAllAiocb(paiorc, PX_ERROR, ECANCELED);                   /*  删除所有同文件描述符节点    */
    API_SemaphoreMPost(paiorc->aiorc_mutex);
    
    _List_Line_Del(&paiorc->aiorc_line, pplineHeader);

    API_SemaphoreMDelete(&paiorc->aiorc_mutex);
    API_ThreadCondDestroy(&paiorc->aiorc_cond);
    
    __SHEAP_FREE(paiorc);
}
Beispiel #6
0
/*********************************************************************************************************
** 函数名称: aio_suspend
** 功能描述: 等待指定的一个或多个异步 I/O 请求操作完成
** 输 入  : list              aio 请求控制块数组 (如果其中有 NULL, 程序将忽略)
**           nent              数组元素个数
**           timeout           超时时间
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  aio_suspend (const struct aiocb * const list[], int nent, const struct timespec *timeout)
{
    AIO_WAIT_CHAIN     *paiowc;
    struct aiowait     *paiowait;
    ULONG               ulTimeout;
    
    BOOL                bNeedWait = LW_FALSE;
    
    int                 iWait = 0;                                      /*  paiowait 下标               */
    int                 iCnt;                                           /*  list 下标                   */
    int                 iRet = ERROR_NONE;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */

    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */

    if ((nent <= 0) || (list == LW_NULL)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if (timeout == LW_NULL) {                                           /*  永久等待                    */
        ulTimeout = LW_OPTION_WAIT_INFINITE;
    } else {
        ulTimeout = __timespecToTick(timeout);
    }
    
    paiowc = __aioCreateWaitChain(nent, LW_TRUE);                       /*  创建等待队列                */
    if (paiowc == LW_NULL) {
        errno = ENOMEM;                                                 /*  should be EAGAIN ?          */
        return  (PX_ERROR);
    }
    
    paiowait = paiowc->aiowc_paiowait;
    
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    
    for (iCnt = 0; iCnt < nent; iCnt++) {
        if (list[iCnt]) {
            if (list[iCnt]->aio_req.aioreq_error == EINPROGRESS) {      /*  必须为正在处理状态          */
                
                paiowait[iWait].aiowt_pcond     = &paiowc->aiowc_cond;
                paiowait[iWait].aiowt_pcnt      = LW_NULL;
                paiowait[iWait].aiowt_psigevent = LW_NULL;
                paiowait[iWait].aiowt_paiowc    = LW_NULL;              /*  不需要代理线程释放          */
                
                iRet = __aioAttachWait(list[iCnt], &paiowait[iWait]);
                if (iRet != ERROR_NONE) {
                    errno = EINVAL;
                    break;
                }
                
                _List_Line_Add_Tail(&paiowait[iWait].aiowt_line, 
                                    &paiowc->aiowc_pline);              /*  加入 wait 链表              */
                iWait++;
                
                bNeedWait = LW_TRUE;                                    /*  有 wait 链表节点连接,       */
            } else {
                break;
            }
        }
    }
    
    if (iRet != ERROR_NONE) {                                           /*  __aioAttachWait 失败        */
        __aioDeleteWaitChain(paiowc);
        API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if ((iCnt == nent) && bNeedWait) {                                  /*  是否需要等待                */
        API_ThreadCleanupPush(__aioWaitCleanup, paiowc);
        
        iRet = (INT)API_ThreadCondWait(&paiowc->aiowc_cond, _G_aioqueue.aioq_mutex, ulTimeout);
        
        API_ThreadCleanupPop(LW_FALSE);                                 /*  这里已经锁定 _G_aioqueue    */
                                                                        /*  不能运行 __aioWaitCleanup   */
        __aioDeleteWaitChain(paiowc);
        
        if (iRet != ERROR_NONE) {
            API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
            errno = EAGAIN;
            return  (PX_ERROR);
        }
    
    } else {                                                            /*  不需要等待                  */
        __aioDeleteWaitChain(paiowc);
    }
    
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
    
    return  (iRet);
}
Beispiel #7
0
/*********************************************************************************************************
** 函数名称: __aioWaitCleanup
** 功能描述: 清理 wait 队列
** 输 入  : paiowt            paiowait 链表头
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID  __aioWaitCleanup (AIO_WAIT_CHAIN  *paiowt)
{
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    __aioDeleteWaitChain(paiowt);
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
}
Beispiel #8
0
/*********************************************************************************************************
** 函数名称: aio_cancel
** 功能描述: 取消一个 aio 请求
** 输 入  : fildes            文件描述符
**           paiocb            aio 请求控制块 (可以为 NULL)
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  aio_cancel (int fildes, struct aiocb *paiocb)
{
    AIO_REQ_CHAIN          *paiorc;
    INT                     iRet;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */

    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    
    if (paiocb == LW_NULL) {
        /*
         *  如果是 cancel 整个文件描述符, 那么这里调用 __aioCancelFd() 进行, __aioCancelFd() 内部将所有
         *  等待操作的节点释放, 然后通知代理线程删除 paiorc 结构, 这样是最安全的操作方式, 如果这里直接删除
         *  那么正在操作的 paiorc 可能会有危险, 
         *  从应用层角度是看不到这个过程的! 我们保证在函数返回前, 将所有的 aiocb 处理完毕!
         */
        paiorc = __aioSearchFd(_G_aioqueue.aioq_plinework, 
                               fildes);                                 /*  搜索工作队列中有没有相同的  */
        if (paiorc == LW_NULL) {
            if (_G_aioqueue.aioq_plineidle) {
                paiorc = __aioSearchFd(_G_aioqueue.aioq_plineidle, 
                                       fildes);                         /*  搜索空闲队列                */
                if (paiorc == LW_NULL) {
                    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                    return  (AIO_ALLDONE);
                
                } else {
                    __aioCancelFd(paiorc);                              /*  删除所有节点后通知任务删除  */
                    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                    return  (AIO_CANCELED);
                }
            
            } else {
                API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                return  (AIO_ALLDONE);
            }
        
        } else {
            __aioCancelFd(paiorc);                                      /*  删除所有节点后通知任务删除  */
            API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
            return  (AIO_CANCELED);
        }
    } else {
        if (paiocb->aio_fildes != fildes) {
            API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
            errno = EINVAL;
            return  (PX_ERROR);
        }
        
        paiorc = __aioSearchFd(_G_aioqueue.aioq_plinework, 
                               fildes);                                 /*  搜索工作队列中有没有相同的  */
        if (paiorc == LW_NULL) {
            if (_G_aioqueue.aioq_plineidle) {
                paiorc = __aioSearchFd(_G_aioqueue.aioq_plineidle, 
                                       fildes);                         /*  搜索空闲队列                */
                if (paiorc == LW_NULL) {
                    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                    return  (AIO_ALLDONE);
                
                } else {
                    API_SemaphoreMPend(paiorc->aiorc_mutex, LW_OPTION_WAIT_INFINITE);
                    iRet = __aioRemoveAiocb(paiorc, paiocb, 
                                            PX_ERROR, ECANCELED);       /*  移除 aiocb                  */
                    API_SemaphoreMPost(paiorc->aiorc_mutex);
                    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                    return  (iRet);
                }
            
            } else {
                API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                return  (AIO_ALLDONE);
            }
        
        } else {
            API_SemaphoreMPend(paiorc->aiorc_mutex, LW_OPTION_WAIT_INFINITE);
            iRet = __aioRemoveAiocb(paiorc, paiocb,
                                    PX_ERROR, ECANCELED);               /*  移除 aiocb                  */
            API_SemaphoreMPost(paiorc->aiorc_mutex);
            API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
            return  (iRet);
        }
    }
    
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
    return  (AIO_ALLDONE);
}
Beispiel #9
0
/*********************************************************************************************************
** 函数名称: lio_listio
** 功能描述: 同时发起多个传输 mode 参数可以是 LIO_WAIT 或 LIO_NOWAIT。LIO_WAIT 会阻塞这个调用,
             直到所有的 I/O 都完成为止. 在操作进行排队之后,LIO_NOWAIT 就会返回. 
             sigevent 引用定义了在所有 I/O 操作都完成时产生信号的方法。
** 输 入  : mode              LIO_WAIT or LIO_NOWAIT。LIO_WAIT
**           list              aio 请求控制块数组 (如果其中有 NULL, 程序将忽略)
**           nent              数组元素个数
**           sig               所有 I/O 操作都完成时产生信号的方法
                               LIO_WAIT 将会忽略此参数!
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  lio_listio (int mode, struct aiocb * const list[], int nent, struct sigevent *sig)
{
    AIO_WAIT_CHAIN     *paiowc;
    struct aiowait     *paiowait;
    
    int                 iWait = 0;                                      /*  paiowait 下标               */
    int                 iCnt;                                           /*  list 下标                   */
    int                 iRet = ERROR_NONE;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */
    
    if ((mode != LIO_WAIT) && (mode != LIO_NOWAIT)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if ((nent <= 0) || (list == LW_NULL)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if (mode == LIO_WAIT) {
        paiowc = __aioCreateWaitChain(nent, LW_TRUE);                   /*  创建等待队列                */
    } else {
        paiowc = __aioCreateWaitChain(nent, LW_FALSE);
    }
    if (paiowc == LW_NULL) {
        errno = ENOMEM;                                                 /*  should be EAGAIN ?          */
        return  (PX_ERROR);
    }
    
    if (sig) {
        paiowc->aiowc_sigevent = *sig;
    } else {
        paiowc->aiowc_sigevent.sigev_signo = 0;                         /*  无效信号不投递              */
    }
    
    paiowait = paiowc->aiowc_paiowait;
    
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    
    for (iCnt = 0; iCnt < nent; iCnt++) {
        if (list[iCnt]) {
            if ((list[iCnt]->aio_lio_opcode != LIO_NOP) &&
                (list[iCnt]->aio_req.aioreq_error != EINPROGRESS)) {
                
                list[iCnt]->aio_sigevent.sigev_notify = SIGEV_NONE;     /*  不使用 aiocb 的 sigevent    */
                list[iCnt]->aio_req.aioreq_thread     = API_ThreadIdSelf();
                
                if (mode == LIO_WAIT) {
                    paiowait[iWait].aiowt_pcond     = &paiowc->aiowc_cond;
                    paiowait[iWait].aiowt_pcnt      = LW_NULL;
                    paiowait[iWait].aiowt_psigevent = LW_NULL;
                    paiowait[iWait].aiowt_paiowc    = LW_NULL;          /*  不需要代理线程释放          */
                
                } else {
                    paiowait[iWait].aiowt_pcond     = LW_NULL;
                    paiowait[iWait].aiowt_pcnt      = LW_NULL;
                    paiowait[iWait].aiowt_psigevent = &paiowc->aiowc_sigevent;
                    paiowait[iWait].aiowt_paiowc    = (void *)paiowc;
                }
                
                __aioAttachWaitNoCheck(list[iCnt], &paiowait[iWait]);   /*  aiocb and aiowait attach    */
                
                if (__aioEnqueue(list[iCnt]) == ERROR_NONE) {
                
                    _List_Line_Add_Tail(&paiowait[iWait].aiowt_line, 
                                        &paiowc->aiowc_pline);          /*  加入 wait 链表              */
                    iWait++;
                
                } else {
                    __aioDetachWait(LW_NULL, &paiowait[iWait]);         /*  删除关联关系                */
                    
                    iRet = PX_ERROR;
                }
            }
        }
    }
    
    if (iWait == 0) {                                                   /*  没有一个节点加入队列        */
        __aioDeleteWaitChain(paiowc);
        API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
        
        if (mode == LIO_NOWAIT) {
            if (sig && __issig(sig->sigev_signo)) {
                _doSigEvent(API_ThreadIdSelf(), sig, SI_ASYNCIO);
            }
        }
        return  (ERROR_NONE);
    
    } else if (mode == LIO_WAIT) {                                      /*  需要等待                    */
        
        __aioWaitChainSetCnt(paiowc, &iWait);                           /*  设置计数变量                */
        
        while (iWait > 0) {
            if (API_ThreadCondWait(&paiowc->aiowc_cond, 
                                   _G_aioqueue.aioq_mutex, 
                                   LW_OPTION_WAIT_INFINITE)) {          /*  等待所有请求执行完毕        */
                break;
            }
        }
        
        __aioDeleteWaitChain(paiowc);                                   /*  清除 wait 队列              */
        
    } else {                                                            /*  LIO_NOWAIT                  */
        paiowc->aiowc_icnt = iWait;                                     /*  必须使用全局变量            */
        
        __aioWaitChainSetCnt(paiowc, &paiowc->aiowc_icnt);              /*  设置计数变量                */
    }
    
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
                
    return  (iRet);
}