1 /*
2 * Copyright (C) 2021-2022 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 "evloop.h"
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <sys/epoll.h>
20 #include "common.h"
21 #include "log.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "WifiRpcEventLoop"
25
26 const int ELOOP_MAX_FD_SIZE = 1024;
27
CreateEventLoop(int size)28 EventLoop *CreateEventLoop(int size)
29 {
30 int flag = 0; /* flag here is used to indicate whether a failure occurs when create event loop struct, 0:success
31 1:failure */
32 EventLoop *evLoop = NULL;
33 do {
34 evLoop = (EventLoop *)calloc(1, sizeof(EventLoop));
35 if (evLoop == NULL) {
36 LOGE("Failed to calloc EventLoop struct!");
37 return NULL;
38 }
39 evLoop->setSize = size;
40 evLoop->epfd = -1;
41 if (size <= 0) {
42 free(evLoop);
43 evLoop = NULL;
44 return NULL;
45 }
46 evLoop->fdMasks = (FdMask *)calloc(size, sizeof(FdMask));
47 evLoop->epEvents = (struct epoll_event *)calloc(size, sizeof(struct epoll_event));
48 if (evLoop->fdMasks == NULL || evLoop->epEvents == NULL) {
49 flag = 1; /* fail */
50 LOGE("Failed to calloc events or epoll_event struct!");
51 break;
52 }
53 evLoop->epfd = epoll_create(ELOOP_MAX_FD_SIZE);
54 if (evLoop->epfd == -1) {
55 flag = 1; /* fail */
56 LOGE("Failed to call epoll_create!");
57 break;
58 }
59 } while (0);
60 if (flag == 0) {
61 return evLoop;
62 }
63 if (evLoop->fdMasks != NULL) {
64 free(evLoop->fdMasks);
65 }
66 if (evLoop->epEvents != NULL) {
67 free(evLoop->epEvents);
68 }
69 free(evLoop);
70 evLoop = NULL;
71 return NULL;
72 }
73
DestroyEventLoop(EventLoop * loop)74 void DestroyEventLoop(EventLoop *loop)
75 {
76 if (loop == NULL) {
77 return;
78 }
79
80 if (loop->epfd != -1) {
81 close(loop->epfd);
82 }
83 if (loop->fdMasks != NULL) {
84 free(loop->fdMasks);
85 }
86 if (loop->epEvents != NULL) {
87 free(loop->epEvents);
88 }
89 free(loop);
90 loop = NULL;
91 return;
92 }
93
StopEventLoop(EventLoop * loop)94 void StopEventLoop(EventLoop *loop)
95 {
96 if (loop == NULL) {
97 return;
98 }
99
100 loop->stop = 1;
101 return;
102 }
103
AddFdEvent(EventLoop * loop,int fd,unsigned int addMask)104 int AddFdEvent(EventLoop *loop, int fd, unsigned int addMask)
105 {
106 if (loop == NULL) {
107 return -1;
108 }
109
110 if (fd >= loop->setSize) {
111 return -1;
112 }
113 if (loop->fdMasks[fd].mask & addMask) {
114 return 0;
115 }
116 int op = (loop->fdMasks[fd].mask == NONE_EVENT) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
117 addMask |= loop->fdMasks[fd].mask;
118 struct epoll_event pollEvent = {0};
119 if (addMask & READ_EVENT) {
120 pollEvent.events |= EPOLLIN;
121 }
122 if (addMask & WRIT_EVENT) {
123 pollEvent.events |= EPOLLOUT;
124 }
125 pollEvent.data.fd = fd;
126 if (epoll_ctl(loop->epfd, op, fd, &pollEvent) == -1) {
127 return -1;
128 }
129 loop->fdMasks[fd].fd = fd;
130 loop->fdMasks[fd].mask |= addMask;
131 if (fd > loop->maxFd) {
132 loop->maxFd = fd;
133 }
134 return 0;
135 }
136
DelFdEvent(EventLoop * loop,int fd,unsigned int delMask)137 int DelFdEvent(EventLoop *loop, int fd, unsigned int delMask)
138 {
139 if (loop == NULL) {
140 return -1;
141 }
142
143 if (fd >= loop->setSize) {
144 return 0;
145 }
146 if (loop->fdMasks[fd].mask == NONE_EVENT) {
147 return 0;
148 }
149 if ((loop->fdMasks[fd].mask & delMask) == 0) {
150 return 0;
151 }
152 unsigned int mask = loop->fdMasks[fd].mask & (~delMask);
153 struct epoll_event pollEvent = {0};
154 pollEvent.events = 0;
155 if (mask & READ_EVENT) {
156 pollEvent.events |= EPOLLIN;
157 }
158 if (mask & WRIT_EVENT) {
159 pollEvent.events |= EPOLLOUT;
160 }
161 pollEvent.data.fd = fd;
162 int op = (mask == NONE_EVENT) ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
163 if (epoll_ctl(loop->epfd, op, fd, &pollEvent) == -1) {
164 return -1;
165 }
166 loop->fdMasks[fd].mask &= ~delMask;
167 if (fd == loop->maxFd && loop->fdMasks[fd].mask == NONE_EVENT) {
168 int j = loop->maxFd - 1;
169 for (; j >= 0; --j) {
170 if (loop->fdMasks[j].mask != NONE_EVENT) {
171 break;
172 }
173 }
174 loop->maxFd = j;
175 }
176
177 return 0;
178 }
179