/********************************************************************************************************* ** 函数名称: _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); } }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: 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); }