diff --git a/core/adapter/syscall/include/hdf_syscall_adapter.h b/core/adapter/syscall/include/hdf_syscall_adapter.h index cb83b3f98ad98c3bfe1f2c1e93e31523984ccb36..6ee33c9353ce5e7faa48f15d455d72e49b8b2fcb 100644 --- a/core/adapter/syscall/include/hdf_syscall_adapter.h +++ b/core/adapter/syscall/include/hdf_syscall_adapter.h @@ -22,6 +22,7 @@ enum HdfDevListenerThreadStatus { LISTENER_UNINITED = 0, LISTENER_INITED, LISTENER_EXITED, + LISTENER_STARTED, LISTENER_RUNNING, LISTENER_WAITING, }; diff --git a/core/adapter/syscall/src/hdf_syscall_adapter.c b/core/adapter/syscall/src/hdf_syscall_adapter.c index 8bbdb01269d0872291e025ce97eaf9f338f4b8c9..d84ea86342590e0c474221b3f6c5b06e64ba0307 100644 --- a/core/adapter/syscall/src/hdf_syscall_adapter.c +++ b/core/adapter/syscall/src/hdf_syscall_adapter.c @@ -162,7 +162,7 @@ static int32_t HdfDevEventReadAndDispatch(struct HdfDevListenerThread *thread, i if (ret == -HDF_DEV_ERR_NODATA) { ret = HDF_SUCCESS; } else { - HDF_LOGE("%s:ioctl failed, errno=%d\n", __func__, ret); + HDF_LOGE("%s:ioctl failed, errno=%d", __func__, ret); } goto finish; @@ -217,6 +217,7 @@ static int32_t HdfDevEventListenTask(void *para) uint16_t pfdSize = 0; int32_t pollCount = 0; + thread->status = LISTENER_RUNNING; while (!thread->shouldStop) { if (thread->pollChanged) { pollCount = AssignPfds(thread, &pfds, &pfdSize); @@ -239,7 +240,6 @@ static int32_t HdfDevEventListenTask(void *para) goto exit; } else if (((uint32_t)pfds[i].revents) & POLLHUP) { HDF_LOGI("event listener task received exit event"); - thread->shouldStop = true; goto exit; } else if (((uint32_t)pfds[i].revents) & POLLNVAL) { OsalMSleep(1); // polled closed fd, yield to sync @@ -268,7 +268,7 @@ static int32_t HdfAdapterStartListenIoctl(int fd) { int32_t ret = ioctl(fd, HDF_LISTEN_EVENT_START, 0); if (ret) { - HDF_LOGE("%s: failed to notify drv(%d) of start %d %s", __func__, fd, errno, strerror(errno)); + HDF_LOGE("%s: failed to notify drv(%d) of start %d %{public}s", __func__, fd, errno, strerror(errno)); return HDF_ERR_IO; } @@ -279,7 +279,7 @@ static int32_t HdfAdapterStopListenIoctl(int fd) { int32_t ret = ioctl(fd, HDF_LISTEN_EVENT_STOP, 0); if (ret) { - HDF_LOGE("%s: failed to notify drv(%d) of stop %d %s", __func__, fd, errno, strerror(errno)); + HDF_LOGE("%s: failed to notify drv(%d) of stop %d %{public}s", __func__, fd, errno, strerror(errno)); return HDF_ERR_IO; } @@ -290,10 +290,10 @@ static int32_t HdfAdapterExitListenIoctl(int fd) { int32_t ret = ioctl(fd, HDF_LISTEN_EVENT_EXIT, 0); if (ret) { - HDF_LOGE("%s: failed to notify drv(%d) of exit %d %s", __func__, fd, errno, strerror(errno)); + HDF_LOGE("%s: failed to notify drv(%d) of exit %d %{public}s", __func__, fd, errno, strerror(errno)); return HDF_ERR_IO; } - + HDF_LOGD("ioctl send poll thread(%d) exit event, ret=%d", fd, ret); return HDF_SUCCESS; } @@ -322,6 +322,7 @@ static int32_t HdfDevListenerThreadDoInit(struct HdfDevListenerThread *thread) static int32_t HdfDevListenerThreadInit(struct HdfDevListenerThread *thread) { switch (thread->status) { + case LISTENER_STARTED: // fall-through case LISTENER_RUNNING: // fall-through case LISTENER_INITED: // fall-through case LISTENER_WAITING: @@ -410,7 +411,7 @@ static int32_t HdfListenThreadInitPollFds(struct HdfDevListenerThread *thread) static int32_t HdfDevListenerThreadStart(struct HdfDevListenerThread *thread) { - if (thread->status == LISTENER_RUNNING) { + if (thread->status >= LISTENER_STARTED) { return HDF_SUCCESS; } @@ -445,7 +446,7 @@ static int32_t HdfDevListenerThreadStart(struct HdfDevListenerThread *thread) ret = HDF_FAILURE; break; } - thread->status = LISTENER_RUNNING; + thread->status = LISTENER_STARTED; return HDF_SUCCESS; } while (0); @@ -505,7 +506,7 @@ static int32_t HdfListenThreadPollAdd(struct HdfDevListenerThread *thread, struc DListInsertTail(&adapter->listNode, thread->adapterListPtr); - if (thread->status != LISTENER_RUNNING) { + if (thread->status < LISTENER_STARTED) { OsalMutexUnlock(&thread->mutex); return HDF_SUCCESS; } @@ -524,7 +525,7 @@ static int32_t HdfListenThreadPollAdd(struct HdfDevListenerThread *thread, struc if (headAdapter != NULL) { if (ioctl(headAdapter->fd, HDF_LISTEN_EVENT_WAKEUP, 0) != 0) { - HDF_LOGE("%s: failed to wakeup drv to add poll %d %s", __func__, errno, strerror(errno)); + HDF_LOGE("%s: failed to wakeup drv to add poll %d %{public}s", __func__, errno, strerror(errno)); thread->pfds[index].fd = SYSCALL_INVALID_FD; ret = HDF_ERR_IO; break; @@ -562,10 +563,7 @@ static void HdfListenThreadPollDel(struct HdfDevListenerThread *thread, struct } } - if (HdfAdapterStopListenIoctl(adapter->fd)) { - HDF_LOGE("%s: failed to stop device report %d %s", __func__, errno, strerror(errno)); - } - + HdfAdapterStopListenIoctl(adapter->fd); if (ioctl(adapter->fd, HDF_LISTEN_EVENT_WAKEUP, 0) != 0) { HDF_LOGE("%s: failed to wakeup drv to del poll %d %s", __func__, errno, strerror(errno)); } @@ -598,21 +596,28 @@ static void HdfDevListenerThreadDestroy(struct HdfDevListenerThread *thread) thread->listenerListPtr = NULL; OsalMutexUnlock(&thread->mutex); for (int i = 0; i < thread->pfdSize; i++) { - if (thread->pfds[i].fd == SYSCALL_INVALID_FD) { - continue; - } - if (HdfAdapterExitListenIoctl(thread->pfds[i].fd) == HDF_SUCCESS) { + if (thread->pfds[i].fd != SYSCALL_INVALID_FD && + HdfAdapterExitListenIoctl(thread->pfds[i].fd) == HDF_SUCCESS) { stopCount++; } + thread->pfds[i].fd = SYSCALL_INVALID_FD; } if (stopCount == 0) { thread->shouldStop = true; HDF_LOGE("%s:failed to exit listener thread with ioctl, will go async way", __func__); + return; } - + while (thread->status != LISTENER_EXITED) { + OsalUSleep(1); + } + HDF_LOGI("poll thread exited"); + HdfDevListenerThreadFree(thread); return; } + case LISTENER_STARTED: + thread->shouldStop = true; + break; case LISTENER_EXITED: // fall-through case LISTENER_INITED: HdfDevListenerThreadFree(thread); @@ -685,11 +690,11 @@ struct HdfIoService *HdfIoServiceAdapterObtain(const char *serviceName) if (realpath(devNodePath, realPath) == NULL) { if (HdfLoadDriverByServiceName(serviceName) != HDF_SUCCESS) { - HDF_LOGE("%s: load %s driver failed", __func__, serviceName); + HDF_LOGE("%s: load %{public}s driver failed", __func__, serviceName); goto out; } if (realpath(devNodePath, realPath) == NULL) { - HDF_LOGE("%s: file name %s is invalid", __func__, devNodePath); + HDF_LOGE("%s: file name %{public}s is invalid", __func__, devNodePath); goto out; } } @@ -709,7 +714,7 @@ struct HdfIoService *HdfIoServiceAdapterObtain(const char *serviceName) adapter->fd = open(realPath, O_RDWR); if (adapter->fd < 0) { - HDF_LOGE("Open file node %s failed, (%d)%s", realPath, errno, strerror(errno)); + HDF_LOGE("Open file node %{public}s failed, (%d)%{public}s", realPath, errno, strerror(errno)); OsalMutexDestroy(&adapter->mutex); OsalMemFree(adapter); goto out; @@ -910,7 +915,7 @@ int32_t HdfIoServiceGroupRegisterListener(struct HdfIoServiceGroup *group, struc } } DListInsertTail(&listener->listNode, &adapterGroup->listenerList); - if (!DListIsEmpty(&adapterGroup->adapterList) && listenerThread->status != LISTENER_RUNNING) { + if (!DListIsEmpty(&adapterGroup->adapterList) && listenerThread->status < LISTENER_STARTED) { ret = HdfDevListenerThreadStart(listenerThread); if (ret != HDF_SUCCESS) { DListRemove(&listener->listNode); @@ -1011,7 +1016,7 @@ int32_t HdfIoServiceGroupAddService(struct HdfIoServiceGroup *group, struct HdfI OsalMutexLock(&listenerThread->mutex); if ((!DListIsEmpty(&adapterGroup->listenerList) || !DListIsEmpty(&adapter->listenerList)) && - listenerThread->status != LISTENER_RUNNING) { + listenerThread->status < LISTENER_STARTED) { ret = HdfDevListenerThreadStart(adapterGroup->thread); if (ret != HDF_SUCCESS) { HdfListenThreadPollDel(adapterGroup->thread, adapter); diff --git a/core/adapter/vnode/src/hdf_vnode_adapter.c b/core/adapter/vnode/src/hdf_vnode_adapter.c index 4694f1c5cef8b6865e67a962031d298f194f743e..dab5a350ee3c6535b231d291604c205f5a650603 100644 --- a/core/adapter/vnode/src/hdf_vnode_adapter.c +++ b/core/adapter/vnode/src/hdf_vnode_adapter.c @@ -524,7 +524,10 @@ static unsigned int HdfVNodeAdapterPoll(struct file *filep, poll_table *wait) { unsigned int mask = 0; struct HdfVNodeAdapterClient *client = (struct HdfVNodeAdapterClient *)OsalGetFilePriv(filep); - + if (client == NULL) { + mask |= POLLERR; + return mask; + } poll_wait(filep, &client->pollWait, wait); OsalMutexLock(&client->mutex); if (client->status == VNODE_CLIENT_EXITED) { @@ -536,6 +539,7 @@ static unsigned int HdfVNodeAdapterPoll(struct file *filep, poll_table *wait) client->wakeup--; } OsalMutexUnlock(&client->mutex); + return mask; } @@ -548,6 +552,7 @@ static int HdfVNodeAdapterClose(struct OsalCdev *cdev, struct file *filep) client->ioServiceClient.device->service->Release(&client->ioServiceClient); } HdfDestoryVNodeAdapterClient(client); + OsalSetFilePriv(filep, NULL); return HDF_SUCCESS; } diff --git a/include/osal/osal_time.h b/include/osal/osal_time.h index b7496227116eb8e4ca88623a4b96b1f67300a1c7..37290924dffa53119e7a7eb817bae0b361c7244e 100644 --- a/include/osal/osal_time.h +++ b/include/osal/osal_time.h @@ -67,6 +67,17 @@ void OsalSleep(uint32_t sec); */ void OsalMSleep(uint32_t ms); +/** + * @brief Describes thread sleep, in microsecond. + * + * When a thread invokes this function, the CPU is released and the thread enters the sleep state. + * + * @param us Indicates the sleep time, in microsecond. + * @since 1.0 + * @version 1.0 + */ +void OsalUSleep(uint32_t us); + /** * @brief Obtains the second and microsecond time. * diff --git a/support/posix/src/osal_time.c b/support/posix/src/osal_time.c index dbd65d0f95853015ef7d8b460288ff938527f715..841dcd9eaf39a6e29e6c48adc61198a930685853 100644 --- a/support/posix/src/osal_time.c +++ b/support/posix/src/osal_time.c @@ -75,6 +75,19 @@ void OsalMSleep(uint32_t ms) } } +void OsalUSleep(uint32_t us) +{ + int result; + struct timespec ts; + + ts.tv_sec = us / ((long)HDF_KILO_UNIT * HDF_KILO_UNIT); + ts.tv_nsec = HDF_KILO_UNIT * ((long)(us % HDF_KILO_UNIT)); + result = nanosleep(&ts, &ts); + if (result != 0) { + HDF_LOGE("%s OsalUSleep failed %d", __func__, errno); + } +} + void OsalUDelay(uint32_t us) { (void)us;