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 evLoop->fdMasks = NULL;
66 }
67 if (evLoop->epEvents != NULL) {
68 free(evLoop->epEvents);
69 evLoop->epEvents = NULL;
70 }
71 free(evLoop);
72 evLoop = NULL;
73 return NULL;
74 }
75
DestroyEventLoop(EventLoop * loop)76 void DestroyEventLoop(EventLoop *loop)
77 {
78 if (loop == NULL) {
79 return;
80 }
81
82 if (loop->epfd != -1) {
83 close(loop->epfd);
84 }
85 if (loop->fdMasks != NULL) {
86 free(loop->fdMasks);
87 }
88 if (loop->epEvents != NULL) {
89 free(loop->epEvents);
90 }
91 free(loop);
92 loop = NULL;
93 return;
94 }
95
StopEventLoop(EventLoop * loop)96 void StopEventLoop(EventLoop *loop)
97 {
98 if (loop == NULL) {
99 return;
100 }
101
102 loop->stop = 1;
103 return;
104 }
105
AddFdEvent(EventLoop * loop,int fd,unsigned int addMask)106 int AddFdEvent(EventLoop *loop, int fd, unsigned int addMask)
107 {
108 if (loop == NULL) {
109 return -1;
110 }
111
112 if (fd >= loop->setSize) {
113 return -1;
114 }
115 if (loop->fdMasks[fd].mask & addMask) {
116 return 0;
117 }
118 int op = (loop->fdMasks[fd].mask == NONE_EVENT) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
119 addMask |= loop->fdMasks[fd].mask;
120 struct epoll_event pollEvent = {0};
121 if (addMask & READ_EVENT) {
122 pollEvent.events |= EPOLLIN;
123 }
124 if (addMask & WRIT_EVENT) {
125 pollEvent.events |= EPOLLOUT;
126 }
127 pollEvent.data.fd = fd;
128 if (epoll_ctl(loop->epfd, op, fd, &pollEvent) == -1) {
129 return -1;
130 }
131 loop->fdMasks[fd].fd = fd;
132 loop->fdMasks[fd].mask |= addMask;
133 if (fd > loop->maxFd) {
134 loop->maxFd = fd;
135 }
136 return 0;
137 }
138
DelFdEvent(EventLoop * loop,int fd,unsigned int delMask)139 int DelFdEvent(EventLoop *loop, int fd, unsigned int delMask)
140 {
141 if (loop == NULL) {
142 return -1;
143 }
144
145 if (fd >= loop->setSize) {
146 return 0;
147 }
148 if (loop->fdMasks[fd].mask == NONE_EVENT) {
149 return 0;
150 }
151 if ((loop->fdMasks[fd].mask & delMask) == 0) {
152 return 0;
153 }
154 unsigned int mask = loop->fdMasks[fd].mask & (~delMask);
155 struct epoll_event pollEvent = {0};
156 pollEvent.events = 0;
157 if (mask & READ_EVENT) {
158 pollEvent.events |= EPOLLIN;
159 }
160 if (mask & WRIT_EVENT) {
161 pollEvent.events |= EPOLLOUT;
162 }
163 pollEvent.data.fd = fd;
164 int op = (mask == NONE_EVENT) ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
165 if (epoll_ctl(loop->epfd, op, fd, &pollEvent) == -1) {
166 return -1;
167 }
168 loop->fdMasks[fd].mask &= ~delMask;
169 if (fd == loop->maxFd && loop->fdMasks[fd].mask == NONE_EVENT) {
170 int j = loop->maxFd - 1;
171 for (; j >= 0; --j) {
172 if (loop->fdMasks[j].mask != NONE_EVENT) {
173 break;
174 }
175 }
176 loop->maxFd = j;
177 }
178
179 return 0;
180 }
181