1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "epoll_manager.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <unistd.h> 19c29fa5a6Sopenharmony_ci 20c29fa5a6Sopenharmony_ci#include "devicestatus_define.h" 21c29fa5a6Sopenharmony_ci 22c29fa5a6Sopenharmony_ci#undef LOG_TAG 23c29fa5a6Sopenharmony_ci#define LOG_TAG "EpollManager" 24c29fa5a6Sopenharmony_ci 25c29fa5a6Sopenharmony_cinamespace OHOS { 26c29fa5a6Sopenharmony_cinamespace Msdp { 27c29fa5a6Sopenharmony_cinamespace DeviceStatus { 28c29fa5a6Sopenharmony_cinamespace { 29c29fa5a6Sopenharmony_ciconstexpr int32_t MAX_N_EVENTS { 64 }; 30c29fa5a6Sopenharmony_ci} // namespace 31c29fa5a6Sopenharmony_ci 32c29fa5a6Sopenharmony_ciEpollManager::~EpollManager() 33c29fa5a6Sopenharmony_ci{ 34c29fa5a6Sopenharmony_ci Close(); 35c29fa5a6Sopenharmony_ci} 36c29fa5a6Sopenharmony_ci 37c29fa5a6Sopenharmony_ciint32_t EpollManager::Open() 38c29fa5a6Sopenharmony_ci{ 39c29fa5a6Sopenharmony_ci if (epollFd_ != -1) { 40c29fa5a6Sopenharmony_ci return RET_OK; 41c29fa5a6Sopenharmony_ci } 42c29fa5a6Sopenharmony_ci epollFd_ = ::epoll_create1(EPOLL_CLOEXEC); 43c29fa5a6Sopenharmony_ci if (epollFd_ == -1) { 44c29fa5a6Sopenharmony_ci FI_HILOGE("epoll_create1 failed:%{public}s", ::strerror(errno)); 45c29fa5a6Sopenharmony_ci return RET_ERR; 46c29fa5a6Sopenharmony_ci } 47c29fa5a6Sopenharmony_ci return RET_OK; 48c29fa5a6Sopenharmony_ci} 49c29fa5a6Sopenharmony_ci 50c29fa5a6Sopenharmony_civoid EpollManager::Close() 51c29fa5a6Sopenharmony_ci{ 52c29fa5a6Sopenharmony_ci if (epollFd_ != -1) { 53c29fa5a6Sopenharmony_ci if (::close(epollFd_) != 0) { 54c29fa5a6Sopenharmony_ci FI_HILOGE("close(%{public}d) failed:%{public}s", epollFd_, ::strerror(errno)); 55c29fa5a6Sopenharmony_ci } 56c29fa5a6Sopenharmony_ci epollFd_ = -1; 57c29fa5a6Sopenharmony_ci } 58c29fa5a6Sopenharmony_ci} 59c29fa5a6Sopenharmony_ci 60c29fa5a6Sopenharmony_ciint32_t EpollManager::Add(IEpollEventSource &source) 61c29fa5a6Sopenharmony_ci{ 62c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 63c29fa5a6Sopenharmony_ci struct epoll_event ev {}; 64c29fa5a6Sopenharmony_ci ev.events = source.GetEvents(); 65c29fa5a6Sopenharmony_ci ev.data.ptr = &source; 66c29fa5a6Sopenharmony_ci 67c29fa5a6Sopenharmony_ci int32_t ret = ::epoll_ctl(epollFd_, EPOLL_CTL_ADD, source.GetFd(), &ev); 68c29fa5a6Sopenharmony_ci if (ret != 0) { 69c29fa5a6Sopenharmony_ci FI_HILOGE("epoll_ctl failed:%{public}s", ::strerror(errno)); 70c29fa5a6Sopenharmony_ci return RET_ERR; 71c29fa5a6Sopenharmony_ci } 72c29fa5a6Sopenharmony_ci return RET_OK; 73c29fa5a6Sopenharmony_ci} 74c29fa5a6Sopenharmony_ci 75c29fa5a6Sopenharmony_civoid EpollManager::Remove(IEpollEventSource &source) 76c29fa5a6Sopenharmony_ci{ 77c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 78c29fa5a6Sopenharmony_ci int32_t ret = ::epoll_ctl(epollFd_, EPOLL_CTL_DEL, source.GetFd(), nullptr); 79c29fa5a6Sopenharmony_ci if (ret != 0) { 80c29fa5a6Sopenharmony_ci FI_HILOGE("epoll_ctl failed:%{public}s", ::strerror(errno)); 81c29fa5a6Sopenharmony_ci } 82c29fa5a6Sopenharmony_ci} 83c29fa5a6Sopenharmony_ci 84c29fa5a6Sopenharmony_ciint32_t EpollManager::Update(IEpollEventSource &source) 85c29fa5a6Sopenharmony_ci{ 86c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 87c29fa5a6Sopenharmony_ci struct epoll_event ev {}; 88c29fa5a6Sopenharmony_ci ev.events = source.GetEvents(); 89c29fa5a6Sopenharmony_ci ev.data.ptr = &source; 90c29fa5a6Sopenharmony_ci 91c29fa5a6Sopenharmony_ci int32_t ret = ::epoll_ctl(epollFd_, EPOLL_CTL_MOD, source.GetFd(), &ev); 92c29fa5a6Sopenharmony_ci if (ret != 0) { 93c29fa5a6Sopenharmony_ci FI_HILOGE("epoll_ctl failed:%{public}s", ::strerror(errno)); 94c29fa5a6Sopenharmony_ci return RET_ERR; 95c29fa5a6Sopenharmony_ci } 96c29fa5a6Sopenharmony_ci return RET_OK; 97c29fa5a6Sopenharmony_ci} 98c29fa5a6Sopenharmony_ci 99c29fa5a6Sopenharmony_ciint32_t EpollManager::Wait(struct epoll_event *events, int32_t maxevents) 100c29fa5a6Sopenharmony_ci{ 101c29fa5a6Sopenharmony_ci return WaitTimeout(events, maxevents, -1); 102c29fa5a6Sopenharmony_ci} 103c29fa5a6Sopenharmony_ci 104c29fa5a6Sopenharmony_ciint32_t EpollManager::WaitTimeout(struct epoll_event *events, int32_t maxevents, int32_t timeout) 105c29fa5a6Sopenharmony_ci{ 106c29fa5a6Sopenharmony_ci int32_t ret = ::epoll_wait(epollFd_, events, maxevents, timeout); 107c29fa5a6Sopenharmony_ci if (ret < 0) { 108c29fa5a6Sopenharmony_ci FI_HILOGE("epoll_wait failed:%{public}s", ::strerror(errno)); 109c29fa5a6Sopenharmony_ci } else if (ret == 0) { 110c29fa5a6Sopenharmony_ci FI_HILOGE("epoll_wait timeout"); 111c29fa5a6Sopenharmony_ci } 112c29fa5a6Sopenharmony_ci return ret; 113c29fa5a6Sopenharmony_ci} 114c29fa5a6Sopenharmony_ci 115c29fa5a6Sopenharmony_civoid EpollManager::Dispatch(const struct epoll_event &ev) 116c29fa5a6Sopenharmony_ci{ 117c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 118c29fa5a6Sopenharmony_ci if ((ev.events & EPOLLIN) == EPOLLIN) { 119c29fa5a6Sopenharmony_ci DispatchOne(ev); 120c29fa5a6Sopenharmony_ci } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) { 121c29fa5a6Sopenharmony_ci FI_HILOGE("Epoll hangup:%{public}s", ::strerror(errno)); 122c29fa5a6Sopenharmony_ci } 123c29fa5a6Sopenharmony_ci} 124c29fa5a6Sopenharmony_ci 125c29fa5a6Sopenharmony_civoid EpollManager::DispatchOne(const struct epoll_event &ev) 126c29fa5a6Sopenharmony_ci{ 127c29fa5a6Sopenharmony_ci struct epoll_event evs[MAX_N_EVENTS]; 128c29fa5a6Sopenharmony_ci int32_t cnt = WaitTimeout(evs, MAX_N_EVENTS, 0); 129c29fa5a6Sopenharmony_ci 130c29fa5a6Sopenharmony_ci for (int32_t index = 0; index < cnt; ++index) { 131c29fa5a6Sopenharmony_ci IEpollEventSource *source = reinterpret_cast<IEpollEventSource *>(evs[index].data.ptr); 132c29fa5a6Sopenharmony_ci CHKPC(source); 133c29fa5a6Sopenharmony_ci if ((evs[index].events & EPOLLIN) == EPOLLIN) { 134c29fa5a6Sopenharmony_ci source->Dispatch(evs[index]); 135c29fa5a6Sopenharmony_ci } else if ((evs[index].events & (EPOLLHUP | EPOLLERR)) != 0) { 136c29fa5a6Sopenharmony_ci FI_HILOGE("Epoll hangup:%{public}s", ::strerror(errno)); 137c29fa5a6Sopenharmony_ci } 138c29fa5a6Sopenharmony_ci } 139c29fa5a6Sopenharmony_ci} 140c29fa5a6Sopenharmony_ci} // namespace DeviceStatus 141c29fa5a6Sopenharmony_ci} // namespace Msdp 142c29fa5a6Sopenharmony_ci} // namespace OHOS