• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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