1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "nstackx_epoll.h"
17 #include "nstackx_log.h"
18 #include "nstackx_error.h"
19
20 #define TAG "nStackXEpoll"
21 #define MAX_EPOLL_SIZE 128
22
RefreshEpollTask(EpollTask * task,uint32_t events)23 int32_t RefreshEpollTask(EpollTask *task, uint32_t events)
24 {
25 struct epoll_event event;
26 if (task == NULL) {
27 return NSTACKX_EINVAL;
28 }
29 event.data.ptr = task;
30 event.events = events;
31
32 if (epoll_ctl(task->epollfd, EPOLL_CTL_MOD, task->taskfd, &event) < 0) {
33 LOGE(TAG, "Refresh task failed: %d", errno);
34 return NSTACKX_EFAILED;
35 }
36
37 return NSTACKX_EOK;
38 }
39
RegisterEpollTask(EpollTask * task,uint32_t events)40 int32_t RegisterEpollTask(EpollTask *task, uint32_t events)
41 {
42 struct epoll_event event;
43 if (task == NULL) {
44 return NSTACKX_EINVAL;
45 }
46 event.data.ptr = task;
47 event.events = events;
48 if (epoll_ctl(task->epollfd, EPOLL_CTL_ADD, task->taskfd, &event) < 0) {
49 LOGE(TAG, "Register task failed: %d", errno);
50 return NSTACKX_EFAILED;
51 }
52 return NSTACKX_EOK;
53 }
54
DeRegisterEpollTask(EpollTask * task)55 int32_t DeRegisterEpollTask(EpollTask *task)
56 {
57 if (task == NULL) {
58 return NSTACKX_EINVAL;
59 }
60 if (epoll_ctl(task->epollfd, EPOLL_CTL_DEL, task->taskfd, NULL) < 0) {
61 LOGE(TAG, "De-register task failed: %d", errno);
62 return NSTACKX_EFAILED;
63 }
64
65 return NSTACKX_EOK;
66 }
67
CreateEpollDesc(void)68 EpollDesc CreateEpollDesc(void)
69 {
70 return epoll_create(1);
71 }
72
EpollLoop(EpollDesc epollfd,int32_t timeout)73 int32_t EpollLoop(EpollDesc epollfd, int32_t timeout)
74 {
75 int32_t i, nfds;
76 EpollTask *task = NULL;
77 struct epoll_event events[MAX_EPOLL_SIZE];
78
79 nfds = epoll_wait(epollfd, events, MAX_EPOLL_SIZE, timeout);
80 if (nfds < 0) {
81 if (errno == EINTR) {
82 LOGD(TAG, "epoll_wait EINTR");
83 return NSTACKX_EINTR;
84 }
85 LOGE(TAG, "epoll_wait returned n=%d, error: %d", nfds, errno);
86 return NSTACKX_EFAILED;
87 }
88
89 for (i = 0; i < nfds; i++) {
90 task = events[i].data.ptr;
91 if (task == NULL) {
92 continue;
93 }
94
95 if (events[i].events & EPOLLIN) {
96 if (task->readHandle != NULL) {
97 task->readHandle(task);
98 }
99 }
100
101 if (events[i].events & EPOLLOUT) {
102 if (task->writeHandle != NULL) {
103 task->writeHandle(task);
104 }
105 }
106 }
107
108 return ((nfds > 0) ? nfds : NSTACKX_ETIMEOUT);
109 }
110