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