コード例 #1
0
ファイル: hotplugDev.c プロジェクト: Ryanxjl/libsylixos-mips
/*********************************************************************************************************
** 函数名称: _hotplugOpen
** 功能描述: 打开热插拔消息设备
** 输 入  : photplugdev      热插拔消息设备
**           pcName           名称
**           iFlags           方式
**           iMode            方法
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static LONG  _hotplugOpen (PLW_HOTPLUG_DEV photplugdev, 
                           PCHAR           pcName,
                           INT             iFlags, 
                           INT             iMode)
{
    PLW_HOTPLUG_FILE  photplugfil;

    if (pcName == LW_NULL) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "device name invalidate.\r\n");
        _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);
        return  (PX_ERROR);
    
    } else {
        if (iFlags & O_CREAT) {
            _ErrorHandle(ERROR_IO_FILE_EXIST);                          /*  不能重复创建                */
            return  (PX_ERROR);
        }
        
        photplugfil = (PLW_HOTPLUG_FILE)__SHEAP_ALLOC(sizeof(LW_HOTPLUG_FILE));
        if (!photplugfil) {
__nomem:
            _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n");
            _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY);
            return  (PX_ERROR);
        }
        
        photplugfil->HOTPFIL_iFlag = iFlags;
        photplugfil->HOTPFIL_iMsg  = LW_HOTPLUG_MSG_ALL;
        photplugfil->HOTPFIL_pbmsg = _bmsgCreate(LW_CFG_HOTPLUG_DEV_DEFAULT_BUFSIZE);
        if (photplugfil->HOTPFIL_pbmsg == LW_NULL) {
            __SHEAP_FREE(photplugfil);
            goto    __nomem;
        }
        
        photplugfil->HOTPFIL_ulReadSync = API_SemaphoreBCreate("hotplug_rsync", LW_FALSE,
                                                               LW_OPTION_OBJECT_GLOBAL,
                                                               LW_NULL);
        if (photplugfil->HOTPFIL_ulReadSync == LW_OBJECT_HANDLE_INVALID) {
            _bmsgDelete(photplugfil->HOTPFIL_pbmsg);
            __SHEAP_FREE(photplugfil);
            return  (PX_ERROR);
        }
        
        HOTPLUG_DEV_LOCK();
        _List_Line_Add_Tail(&photplugfil->HOTPFIL_lineManage,
                            &_G_hotplugdev.HOTPDEV_plineFile);
        HOTPLUG_DEV_UNLOCK();
        
        LW_DEV_INC_USE_COUNT(&_G_hotplugdev.HOTPDEV_devhdrHdr);
        
        return  ((LONG)photplugfil);
    }
}
コード例 #2
0
ファイル: aio.c プロジェクト: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: 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);
}
コード例 #3
0
ファイル: aio.c プロジェクト: Ga-vin/libsylixos
/*********************************************************************************************************
** 函数名称: 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);
}