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 "softbus_base_listener.h"
17
18 #include <securec.h>
19 #include <unistd.h>
20
21 #include "common_list.h"
22 #include "softbus_adapter_errcode.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_adapter_socket.h"
25 #include "softbus_conn_interface.h"
26 #include "softbus_errcode.h"
27 #include "softbus_feature_config.h"
28 #include "softbus_log.h"
29 #include "softbus_socket.h"
30 #include "softbus_thread_pool.h"
31 #include "softbus_utils.h"
32
33 #define MAX_LISTEN_EVENTS 1024
34 #define TIMEOUT 10000
35 #define DEFAULT_BACKLOG 4
36 #define FDARR_START_SIZE 16
37 #define FDARR_EXPAND_BASE 2
38
39 #define THREADPOOL_THREADNUM 1
40 #define THREADPOOL_QUEUE_NUM 10
41
42 typedef struct {
43 ListNode node;
44 int32_t fd;
45 } FdNode;
46
47 enum BaseListenerStatus {
48 LISTENER_IDLE = 0,
49 LISTENER_RUNNING,
50 LISTENER_CLOSEING,
51 };
52
53 typedef struct {
54 ListNode node;
55 LocalListenerInfo listenerInfo;
56 int32_t listenFd;
57 int32_t listenPort;
58 int32_t fdCount;
59 ModeType modeType;
60 enum BaseListenerStatus status;
61 } SoftbusBaseListenerInfo;
62
63 typedef struct {
64 ListenerModule module;
65 SoftbusBaseListener *listener;
66 const SocketInterface *socketIf;
67 SoftbusBaseListenerInfo info;
68 uint32_t ref;
69 SoftBusMutex lock;
70 } SoftbusListenerNode;
71
72 static SoftbusListenerNode *g_listenerList[UNUSE_BUTT] = {0};
73 static SoftBusMutex g_listenerListLock;
74
75
76 static SoftBusMutex g_threadLock;
77 static int32_t g_threadRefCount = 0;
78
79 static ThreadPool *g_threadPool = NULL;
80 static SoftBusFdSet g_readSet;
81 static SoftBusFdSet g_writeSet;
82 static SoftBusFdSet g_exceptSet;
83 static int32_t g_maxFd;
84 static SoftBusMutex g_fdSetLock;
85
86 static void ReleaseListenerSockets(SoftbusListenerNode* node);
87 static void UpdateMaxFd(void);
88 static void ClearListenerFdList(const ListNode *cfdList);
89 static void InitListenerInfo(SoftbusBaseListenerInfo *listenerInfo);
90 static int32_t ShutdownBaseListener(SoftbusListenerNode *node);
91 static int32_t StopListenerThread(SoftbusListenerNode *node);
92
RequestListenerNode(ListenerModule module)93 static SoftbusListenerNode *RequestListenerNode(ListenerModule module)
94 {
95 if (module >= UNUSE_BUTT) {
96 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:Invalid listener module.", __func__);
97 return NULL;
98 }
99 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
100 if (ret != SOFTBUS_OK) {
101 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: lock g_listenerListLock failed!.", __func__);
102 return NULL;
103 }
104
105 SoftbusListenerNode *node = g_listenerList[module];
106 do {
107 if (node == NULL) {
108 break;
109 }
110 if (node->info.status == LISTENER_CLOSEING) {
111 node = NULL;
112 break;
113 }
114 ret = SoftBusMutexLock(&node->lock);
115 if (ret != SOFTBUS_OK) {
116 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: lock node failed!.", __func__);
117 node = NULL;
118 break;
119 }
120 node->ref++;
121 SoftBusMutexUnlock(&node->lock);
122 } while (false);
123
124 (void)SoftBusMutexUnlock(&g_listenerListLock);
125 return node;
126 }
127
ReleaseListenerSockets(SoftbusListenerNode * node)128 static void ReleaseListenerSockets(SoftbusListenerNode *node)
129 {
130 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
131 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
132 return;
133 }
134 if (node->info.listenFd >= 0) {
135 ConnShutdownSocket(node->info.listenFd);
136 }
137 node->info.listenFd = -1;
138 node->info.listenPort = -1;
139 node->info.modeType = UNSET_MODE;
140 node->info.fdCount = 0;
141 ClearListenerFdList(&(node->info.node));
142 SoftBusMutexUnlock(&node->lock);
143 UpdateMaxFd();
144 }
145
146 // Node: get g_listenerListLock first
ReleaseListenerRef(ListenerModule module)147 static int32_t ReleaseListenerRef(ListenerModule module)
148 {
149 SoftbusListenerNode *node = g_listenerList[module];
150 if (node == NULL) {
151 return SOFTBUS_NOT_FIND;
152 }
153 int32_t ret = SoftBusMutexLock(&node->lock);
154 if (ret != SOFTBUS_OK) {
155 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
156 return ret;
157 }
158 node->ref--;
159
160 if (node->ref == 0) {
161 g_listenerList[module] = NULL;
162
163 if (node->listener != NULL) {
164 SoftBusFree(node->listener);
165 node->listener = NULL;
166 }
167 ReleaseListenerSockets(node);
168 (void)StopListenerThread(node);
169 (void)SoftBusMutexUnlock(&node->lock);
170 (void)SoftBusMutexDestroy(&node->lock);
171 SoftBusFree(node);
172 } else {
173 (void)SoftBusMutexUnlock(&node->lock);
174 }
175
176 return SOFTBUS_OK;
177 }
178
ReleaseListenerNode(SoftbusListenerNode * node)179 static void ReleaseListenerNode(SoftbusListenerNode *node)
180 {
181 if (node == NULL || node->module >= UNUSE_BUTT) {
182 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid listener module.");
183 return;
184 }
185 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
186 if (ret != SOFTBUS_OK) {
187 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: lock g_listenerListLock failed!.", __func__);
188 return;
189 }
190
191 ret = ReleaseListenerRef(node->module);
192 if (ret != SOFTBUS_OK) {
193 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: release node failed!.", __func__);
194 }
195 (void)SoftBusMutexUnlock(&g_listenerListLock);
196 }
197
198 // Node: get g_listenerListLock first
CreateSpecifiedListenerModule(ListenerModule module)199 static int32_t CreateSpecifiedListenerModule(ListenerModule module)
200 {
201 SoftbusListenerNode *node = (SoftbusListenerNode *)SoftBusCalloc(sizeof(SoftbusListenerNode));
202 if (node == NULL) {
203 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:oom!", __func__);
204 return SOFTBUS_MALLOC_ERR;
205 }
206
207 // init lock
208 SoftBusMutexAttr mutexAttr;
209 mutexAttr.type = SOFTBUS_MUTEX_RECURSIVE;
210 if (SoftBusMutexInit(&node->lock, &mutexAttr) != SOFTBUS_OK) {
211 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:init lock failed!", __func__);
212 SoftBusFree(node);
213 return SOFTBUS_LOCK_ERR;
214 }
215 InitListenerInfo(&node->info);
216
217 node->module = module;
218 node->ref = 1;
219
220 g_listenerList[module] = node;
221 return SOFTBUS_OK;
222 }
223
CreateStaticModules(void)224 static int32_t CreateStaticModules(void)
225 {
226 for (uint32_t i = 0; i < LISTENER_MODULE_DYNAMIC_START; i++) {
227 int32_t ret = CreateSpecifiedListenerModule((ListenerModule)i);
228 if (ret != SOFTBUS_OK) {
229 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: create module %" PRIu32 " failed!ret=" PRId32,
230 __func__, i, ret);
231 return ret;
232 }
233 }
234 return SOFTBUS_OK;
235 }
236
CreateListenerModule(void)237 uint32_t CreateListenerModule(void)
238 {
239 uint32_t moduleId = UNUSE_BUTT;
240 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
241 if (ret != SOFTBUS_OK) {
242 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: lock g_listenerListLock failed!.", __func__);
243 return moduleId;
244 }
245
246 for (uint32_t i = LISTENER_MODULE_DYNAMIC_START; i <= LISTENER_MODULE_DYNAMIC_END; i++) {
247 if (g_listenerList[i] != NULL) {
248 continue;
249 }
250 ret = CreateSpecifiedListenerModule((ListenerModule)i);
251 if (ret != SOFTBUS_OK) {
252 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: create module %" PRIu32 " failed!ret=" PRId32,
253 __func__, i, ret);
254 break;
255 }
256 moduleId = i;
257 break;
258 }
259
260 (void)SoftBusMutexUnlock(&g_listenerListLock);
261 return moduleId;
262 }
263
InitBaseListener(void)264 int32_t InitBaseListener(void)
265 {
266 int32_t ret = SoftBusMutexInit(&g_fdSetLock, NULL);
267 if (ret != SOFTBUS_OK) {
268 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "g_fdSetLock init failed.ret=%" PRId32, ret);
269 return ret;
270 }
271
272 ret = SoftBusMutexInit(&g_listenerListLock, NULL);
273 if (ret != SOFTBUS_OK) {
274 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "g_listenerListLock init failed.ret=%" PRId32, ret);
275 (void)SoftBusMutexDestroy(&g_fdSetLock);
276 return ret;
277 }
278
279 ret = SoftBusMutexInit(&g_threadLock, NULL);
280 if (ret != SOFTBUS_OK) {
281 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "g_threadLock init failed.ret=%" PRId32, ret);
282 (void)SoftBusMutexDestroy(&g_listenerListLock);
283 (void)SoftBusMutexDestroy(&g_fdSetLock);
284 return ret;
285 }
286
287 g_threadPool = ThreadPoolInit(THREADPOOL_THREADNUM, THREADPOOL_QUEUE_NUM);
288 if (g_threadPool == NULL) {
289 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Init thread pool failed.");
290 (void)SoftBusMutexDestroy(&g_fdSetLock);
291 (void)SoftBusMutexDestroy(&g_listenerListLock);
292 return SOFTBUS_MALLOC_ERR;
293 }
294
295 (void)memset_s(g_listenerList, sizeof(g_listenerList), 0, sizeof(g_listenerList));
296
297 SoftBusSocketFdZero(&g_readSet);
298 SoftBusSocketFdZero(&g_writeSet);
299 SoftBusSocketFdZero(&g_exceptSet);
300
301 ret = CreateStaticModules();
302 if (ret != SOFTBUS_OK) {
303 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Create static listener module failed! ret=%" PRId32, ret);
304 (void)ThreadPoolDestroy(g_threadPool);
305 (void)SoftBusMutexDestroy(&g_fdSetLock);
306 (void)SoftBusMutexDestroy(&g_listenerListLock);
307 return ret;
308 }
309 return SOFTBUS_OK;
310 }
311
DeinitBaseListener(void)312 void DeinitBaseListener(void)
313 {
314 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
315 if (ret != SOFTBUS_OK) {
316 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:get lock failed!ret=%" PRId32, __func__, ret);
317 return;
318 }
319
320 for (uint32_t i = 0; i < UNUSE_BUTT; i++) {
321 (void)ShutdownBaseListener(g_listenerList[i]);
322 (void)ReleaseListenerRef((ListenerModule)i);
323 g_listenerList[i] = NULL;
324 }
325
326 if (g_threadPool != NULL) {
327 ret = ThreadPoolDestroy(g_threadPool);
328 if (ret != SOFTBUS_OK) {
329 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Destroy thread pool failed.ret=%" PRId32, ret);
330 }
331 }
332
333 (void)SoftBusMutexUnlock(&g_listenerListLock);
334 (void)SoftBusMutexDestroy(&g_listenerListLock);
335 (void)SoftBusMutexDestroy(&g_fdSetLock);
336 (void)SoftBusMutexDestroy(&g_threadLock);
337 }
338
FdCopy(const SoftBusFdSet * dest,const SoftBusFdSet * src)339 static int32_t FdCopy(const SoftBusFdSet *dest, const SoftBusFdSet *src)
340 {
341 return memcpy_s((void *)dest, sizeof(SoftBusFdSet), (void *)src, sizeof(SoftBusFdSet));
342 }
343
MaxFd(int32_t fd1,int32_t fd2)344 static int32_t MaxFd(int32_t fd1, int32_t fd2)
345 {
346 return (fd1 > fd2) ? fd1 : fd2;
347 }
348
UpdateMaxFd(void)349 static void UpdateMaxFd(void)
350 {
351 int32_t tmpMax = -1;
352 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
353 if (ret != SOFTBUS_OK) {
354 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: lock g_listenerListLock failed!.", __func__);
355 return;
356 }
357
358 for (int i = 0; i < UNUSE_BUTT; i++) {
359 if (g_listenerList[i] == NULL) {
360 continue;
361 }
362 if (SoftBusMutexLock(&g_listenerList[i]->lock) != SOFTBUS_OK) {
363 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
364 continue;
365 }
366
367 if (g_listenerList[i]->info.status == LISTENER_RUNNING) {
368 tmpMax = MaxFd(g_listenerList[i]->info.listenFd, tmpMax);
369 FdNode *item = NULL;
370 FdNode *nextItem = NULL;
371 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_listenerList[i]->info.node, FdNode, node)
372 {
373 tmpMax = MaxFd(item->fd, tmpMax);
374 }
375 }
376 (void)SoftBusMutexUnlock(&g_listenerList[i]->lock);
377 }
378 (void)SoftBusMutexUnlock(&g_listenerListLock);
379
380 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
381 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
382 return;
383 }
384 g_maxFd = tmpMax;
385 SoftBusMutexUnlock(&g_fdSetLock);
386 }
387
CheckTrigger(TriggerType triggerType)388 static int32_t CheckTrigger(TriggerType triggerType)
389 {
390 if (triggerType < READ_TRIGGER || triggerType > RW_TRIGGER) {
391 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid listener trigger type.");
392 return SOFTBUS_INVALID_PARAM;
393 }
394 return SOFTBUS_OK;
395 }
396
ClearListenerFdList(const ListNode * cfdList)397 static void ClearListenerFdList(const ListNode *cfdList)
398 {
399 FdNode *item = NULL;
400
401 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
402 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
403 return;
404 }
405 while (!IsListEmpty(cfdList)) {
406 item = LIST_ENTRY(cfdList->next, FdNode, node);
407 ListDelete(&item->node);
408 SoftBusSocketFdClr(item->fd, &g_readSet);
409 SoftBusSocketFdClr(item->fd, &g_writeSet);
410 SoftBusSocketFdClr(item->fd, &g_exceptSet);
411 SoftBusFree(item);
412 }
413 SoftBusMutexUnlock(&g_fdSetLock);
414 }
415
InitListenFd(SoftbusListenerNode * node,const LocalListenerInfo * info)416 static int32_t InitListenFd(SoftbusListenerNode* node, const LocalListenerInfo *info)
417 {
418 if (node == NULL || info == NULL || info->socketOption.port < 0) {
419 return SOFTBUS_INVALID_PARAM;
420 }
421
422 if (node->socketIf == NULL) {
423 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "no protocol inited!");
424 return SOFTBUS_INVALID_PARAM;
425 }
426
427 int32_t ret = SOFTBUS_OK;
428 do {
429 int32_t rc = node->socketIf->OpenServerSocket(info);
430 if (rc < 0) {
431 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "OpenTcpServer failed, rc=%d", rc);
432 return SOFTBUS_TCP_SOCKET_ERR;
433 }
434 node->info.listenFd = rc;
435 rc = SoftBusSocketListen(node->info.listenFd, DEFAULT_BACKLOG);
436 if (rc != 0) {
437 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "listen failed, rc=%d", rc);
438 ReleaseListenerSockets(node);
439 ret = SOFTBUS_TCP_SOCKET_ERR;
440 break;
441 }
442 node->info.fdCount = 1;
443 node->info.listenPort = node->socketIf->GetSockPort(node->info.listenFd);
444 if (node->info.listenPort < 0) {
445 SoftBusLog(
446 SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "GetSockPort failed, listenPort_=%d", node->info.listenPort);
447 ReleaseListenerSockets(node);
448 ret = SOFTBUS_ERR;
449 break;
450 }
451 if (memcpy_s(&node->info.listenerInfo, sizeof(node->info.listenerInfo), info, sizeof(*info)) != EOK) {
452 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Copy server option failed!");
453 ReleaseListenerSockets(node);
454 ret = SOFTBUS_MEM_ERR;
455 break;
456 }
457 } while (false);
458
459 if (node->info.listenFd > 0) {
460 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
461 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
462 ReleaseListenerSockets(node);
463 return SOFTBUS_ERR;
464 }
465 SoftBusSocketFdSet(node->info.listenFd, &g_readSet);
466 g_maxFd = MaxFd(node->info.listenFd, g_maxFd);
467 SoftBusMutexUnlock(&g_fdSetLock);
468 }
469 return ret;
470 }
471
OnEvent(SoftbusListenerNode * node,int32_t fd,uint32_t events)472 static int32_t OnEvent(SoftbusListenerNode *node, int32_t fd, uint32_t events)
473 {
474 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
475 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "event lock failed");
476 return SOFTBUS_LOCK_ERR;
477 }
478 if (node->listener == NULL) {
479 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "info or listener is null");
480 SoftBusMutexUnlock(&node->lock);
481 return SOFTBUS_ERR;
482 }
483 int32_t listenFd = node->info.listenFd;
484 SoftbusBaseListener listener = {0};
485 listener.onConnectEvent = node->listener->onConnectEvent;
486 listener.onDataEvent = node->listener->onDataEvent;
487 const SocketInterface *socketIf = node->socketIf;
488 ListenerModule module = node->module;
489 ConnectType connectType = node->info.listenerInfo.type;
490 SoftBusMutexUnlock(&node->lock);
491
492 if (fd == listenFd) {
493 while (true) {
494 if (socketIf == NULL || socketIf->AcceptClient == NULL) {
495 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "accept func not found! module=%d", module);
496 break;
497 }
498 int32_t cfd;
499 ConnectOption clientAddr = {
500 .type = connectType,
501 .socketOption = {.addr = {0}, .port = 0, .protocol = 0, .moduleId = module}
502 };
503 int32_t ret = SOFTBUS_TEMP_FAILURE_RETRY(socketIf->AcceptClient(fd, &clientAddr, &cfd));
504 if (ret != SOFTBUS_OK) {
505 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "accept failed, cfd=%d, module=%d, fd=%d", cfd,
506 module, fd);
507 break;
508 }
509 if (listener.onConnectEvent != NULL) {
510 listener.onConnectEvent(module, events, cfd, &clientAddr);
511 } else {
512 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Please set onConnectEvent callback");
513 SoftBusSocketClose(cfd);
514 }
515 }
516 } else {
517 if (listener.onDataEvent != NULL) {
518 listener.onDataEvent(module, events, fd);
519 } else {
520 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Please set onDataEvent callback");
521 }
522 }
523 return SOFTBUS_OK;
524 }
525
CreateFdArr(int32_t ** fdArr,int32_t * fdArrLen,const ListNode * list)526 static int CreateFdArr(int32_t **fdArr, int32_t *fdArrLen, const ListNode *list)
527 {
528 if (list == NULL || list->next == list) {
529 *fdArrLen = 0;
530 return SOFTBUS_OK;
531 }
532
533 int32_t fdArrSize = FDARR_START_SIZE;
534 int32_t *tmpFdArr = NULL;
535
536 tmpFdArr = (int32_t *)SoftBusCalloc(sizeof(int32_t) * fdArrSize);
537 if (tmpFdArr == NULL) {
538 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "SoftBusCalloc failed, out of memory");
539 return SOFTBUS_MALLOC_ERR;
540 }
541 *fdArrLen = 0;
542
543 FdNode *item = NULL;
544 LIST_FOR_EACH_ENTRY(item, list, FdNode, node)
545 {
546 if (*fdArrLen == fdArrSize) {
547 int32_t *tmp = NULL;
548
549 tmp = (int32_t *)SoftBusCalloc((int32_t)sizeof(int32_t) * fdArrSize * FDARR_EXPAND_BASE);
550 if (tmp == NULL) {
551 SoftBusFree(tmpFdArr);
552 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "SoftBusCalloc failed, out of memory");
553 return SOFTBUS_MALLOC_ERR;
554 }
555 for (int i = 0; i < *fdArrLen; i++) {
556 tmp[i] = tmpFdArr[i];
557 }
558 SoftBusFree(tmpFdArr);
559 tmpFdArr = tmp;
560 fdArrSize *= FDARR_EXPAND_BASE;
561 }
562 tmpFdArr[*fdArrLen] = item->fd;
563 *fdArrLen = *fdArrLen + 1;
564 }
565 *fdArr = tmpFdArr;
566 return SOFTBUS_OK;
567 }
568
ProcessNodeData(SoftbusListenerNode * node,SoftBusFdSet * readSet,SoftBusFdSet * writeSet,SoftBusFdSet * exceptSet)569 static void ProcessNodeData(
570 SoftbusListenerNode *node, SoftBusFdSet *readSet, SoftBusFdSet *writeSet, SoftBusFdSet *exceptSet)
571 {
572 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
573 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
574 return;
575 }
576
577 if (node->info.status != LISTENER_RUNNING) {
578 SoftBusLog(
579 SOFTBUS_LOG_CONN, SOFTBUS_LOG_DBG, "module %d is not running!status = %d", node->module, node->info.status);
580 SoftBusMutexUnlock(&node->lock);
581 return;
582 }
583 int32_t listenFd = node->info.listenFd;
584 int32_t *fdArr = NULL;
585 int32_t fdArrLen = 0;
586
587 if (CreateFdArr(&fdArr, &fdArrLen, &node->info.node) != SOFTBUS_OK) {
588 SoftBusMutexUnlock(&node->lock);
589 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "CreateFdArr failed, module:%d", node->module);
590 return;
591 }
592 SoftBusMutexUnlock(&node->lock);
593
594 if ((listenFd > 0) && SoftBusSocketFdIsset(listenFd, readSet)) {
595 OnEvent(node, listenFd, SOFTBUS_SOCKET_IN);
596 }
597 for (int j = 0; j < fdArrLen; j++) {
598 if (SoftBusSocketFdIsset(fdArr[j], readSet)) {
599 OnEvent(node, fdArr[j], SOFTBUS_SOCKET_IN);
600 }
601 if (SoftBusSocketFdIsset(fdArr[j], writeSet)) {
602 OnEvent(node, fdArr[j], SOFTBUS_SOCKET_OUT);
603 }
604 if (SoftBusSocketFdIsset(fdArr[j], exceptSet)) {
605 OnEvent(node, fdArr[j], SOFTBUS_SOCKET_EXCEPTION);
606 }
607 }
608 SoftBusFree(fdArr);
609 }
610
ProcessData(SoftBusFdSet * readSet,SoftBusFdSet * writeSet,SoftBusFdSet * exceptSet)611 static void ProcessData(SoftBusFdSet *readSet, SoftBusFdSet *writeSet, SoftBusFdSet *exceptSet)
612 {
613 for (int i = 0; i < UNUSE_BUTT; i++) {
614 SoftbusListenerNode *node = RequestListenerNode((ListenerModule)i);
615 if (node == NULL) {
616 continue;
617 }
618 ProcessNodeData(node, readSet, writeSet, exceptSet);
619 ReleaseListenerNode(node);
620 }
621 }
622
SetSelect(SoftBusFdSet * readSet,SoftBusFdSet * writeSet,SoftBusFdSet * exceptSet)623 static int32_t SetSelect(SoftBusFdSet *readSet, SoftBusFdSet *writeSet, SoftBusFdSet *exceptSet)
624 {
625 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
626 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
627 return SOFTBUS_ERR;
628 }
629 if (FdCopy(readSet, &g_readSet) != EOK) {
630 goto EXIT;
631 }
632 if (FdCopy(writeSet, &g_writeSet) != EOK) {
633 goto EXIT;
634 }
635 if (FdCopy(exceptSet, &g_exceptSet) != EOK) {
636 goto EXIT;
637 }
638 SoftBusMutexUnlock(&g_fdSetLock);
639
640 return SOFTBUS_OK;
641 EXIT:
642 SoftBusMutexUnlock(&g_fdSetLock);
643 SoftBusSocketFdZero(readSet);
644 SoftBusSocketFdZero(writeSet);
645 SoftBusSocketFdZero(exceptSet);
646 return SOFTBUS_MEM_ERR;
647 }
648
SelectThread(void * data)649 static int32_t SelectThread(void *data)
650 {
651 (void)data;
652 SoftBusSockTimeOut tv = {0};
653 tv.sec = 0;
654 tv.usec = TIMEOUT;
655 int32_t timeOut = 0;
656 if (SoftbusGetConfig(SOFTBUS_INT_SUPPORT_SELECT_INTERVAL, (unsigned char *)&timeOut, sizeof(timeOut)) ==
657 SOFTBUS_OK) {
658 tv.usec = (long)timeOut;
659 }
660 SoftBusFdSet readSet;
661 SoftBusFdSet writeSet;
662 SoftBusFdSet exceptSet;
663 SoftBusSocketFdZero(&readSet);
664 SoftBusSocketFdZero(&writeSet);
665 SoftBusSocketFdZero(&exceptSet);
666 if (SetSelect(&readSet, &writeSet, &exceptSet) != SOFTBUS_OK) {
667 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "select failed with invalid listener");
668 return SOFTBUS_ERR;
669 }
670 int32_t maxFd = g_maxFd;
671 if (maxFd < 0) {
672 SoftBusSocketSelect(0, NULL, NULL, NULL, &tv);
673 return SOFTBUS_OK;
674 }
675
676 int32_t nEvents = SoftBusSocketSelect(maxFd + 1, &readSet, &writeSet, &exceptSet, &tv);
677 if (nEvents < 0) {
678 return SOFTBUS_TCP_SOCKET_ERR;
679 } else if (nEvents == 0) {
680 return SOFTBUS_OK;
681 } else {
682 ProcessData(&readSet, &writeSet, &exceptSet);
683 return SOFTBUS_OK;
684 }
685 }
686
StopListenerThread(SoftbusListenerNode * node)687 static int32_t StopListenerThread(SoftbusListenerNode *node)
688 {
689 int32_t ret = SoftBusMutexLock(&node->lock);
690 if (ret != SOFTBUS_OK) {
691 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed!ret=%" PRId32, __func__, ret);
692 return ret;
693 }
694
695 do {
696 if (node->info.status != LISTENER_RUNNING) {
697 SoftBusLog(
698 SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "%s:node not running.status=%d", __func__, node->info.status);
699 break;
700 }
701
702 ret = SoftBusMutexLock(&g_threadLock);
703 if (ret != SOFTBUS_OK) {
704 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock g_threadLock failed!ret=%" PRId32, __func__, ret);
705 break;
706 }
707
708 --g_threadRefCount;
709
710 if (g_threadRefCount <= 0) {
711 ret = ThreadPoolRemoveJob(g_threadPool, (uintptr_t)0);
712 if (ret != SOFTBUS_OK) {
713 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:remove job failed!ret=%" PRId32, __func__, ret);
714 (void)SoftBusMutexUnlock(&g_threadLock);
715 break;
716 }
717 }
718
719 (void)SoftBusMutexUnlock(&g_threadLock);
720
721 node->info.status = LISTENER_IDLE;
722 node->info.modeType = UNSET_MODE;
723 } while (false);
724 (void)SoftBusMutexUnlock(&node->lock);
725 return ret;
726 }
727
StartListenerThread(SoftbusListenerNode * node,ModeType modeType)728 static int32_t StartListenerThread(SoftbusListenerNode *node, ModeType modeType)
729 {
730 int32_t ret = SoftBusMutexLock(&node->lock);
731 if (ret != SOFTBUS_OK) {
732 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed!ret=%" PRId32, __func__, ret);
733 return ret;
734 }
735
736 do {
737 if (node->info.status != LISTENER_IDLE) {
738 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:bad status(%d)", __func__, node->info.status);
739 ret = SOFTBUS_ERR;
740 break;
741 }
742
743 ret = SoftBusMutexLock(&g_threadLock);
744 if (ret != SOFTBUS_OK) {
745 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock g_threadLock failed!ret=%" PRId32, __func__, ret);
746 break;
747 }
748
749 if (g_threadRefCount > 0) {
750 g_threadRefCount++;
751 (void)SoftBusMutexUnlock(&g_threadLock);
752 break;
753 }
754
755 ret = ThreadPoolAddJob(g_threadPool, (int32_t(*)(void *))SelectThread, NULL, PERSISTENT, (uintptr_t)0);
756 if (ret != SOFTBUS_OK) {
757 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:start thread failed!ret=%" PRId32, __func__, ret);
758 (void)SoftBusMutexUnlock(&g_threadLock);
759 break;
760 }
761
762 g_threadRefCount++;
763 (void)SoftBusMutexUnlock(&g_threadLock);
764 } while (false);
765
766 if (ret == SOFTBUS_OK) {
767 node->info.modeType = modeType;
768 node->info.status = LISTENER_RUNNING;
769 }
770
771 (void)SoftBusMutexUnlock(&node->lock);
772 return ret;
773 }
774
ShutdownBaseListener(SoftbusListenerNode * node)775 static int32_t ShutdownBaseListener(SoftbusListenerNode *node)
776 {
777 if (node == NULL) {
778 return SOFTBUS_NOT_FIND;
779 }
780
781 int32_t ret = SoftBusMutexLock(&node->lock);
782 if (ret != SOFTBUS_OK) {
783 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
784 return ret;
785 }
786
787 ret = StopListenerThread(node);
788 if (ret != SOFTBUS_OK) {
789 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: stop listener failed!ret=%" PRId32, __func__, ret);
790 }
791 node->info.status = LISTENER_CLOSEING;
792 SoftBusMutexUnlock(&node->lock);
793 return SOFTBUS_OK;
794 }
795
InitListenerInfo(SoftbusBaseListenerInfo * listenerInfo)796 static void InitListenerInfo(SoftbusBaseListenerInfo *listenerInfo)
797 {
798 listenerInfo->modeType = UNSET_MODE;
799 listenerInfo->fdCount = 0;
800 listenerInfo->listenFd = -1;
801 listenerInfo->listenPort = -1;
802 listenerInfo->status = LISTENER_IDLE;
803 ListInit(&listenerInfo->node);
804 }
805
806
AddTriggerToSet(int32_t fd,TriggerType triggerType)807 static int32_t AddTriggerToSet(int32_t fd, TriggerType triggerType)
808 {
809 int32_t ret = SOFTBUS_OK;
810 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
811 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
812 return SOFTBUS_ERR;
813 }
814 switch (triggerType) {
815 case READ_TRIGGER:
816 SoftBusSocketFdSet(fd, &g_readSet);
817 break;
818 case WRITE_TRIGGER:
819 SoftBusSocketFdSet(fd, &g_writeSet);
820 break;
821 case EXCEPT_TRIGGER:
822 SoftBusSocketFdSet(fd, &g_exceptSet);
823 break;
824 case RW_TRIGGER:
825 SoftBusSocketFdSet(fd, &g_readSet);
826 SoftBusSocketFdSet(fd, &g_writeSet);
827 break;
828 default:
829 ret = SOFTBUS_INVALID_PARAM;
830 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid trigger type");
831 break;
832 }
833 SoftBusMutexUnlock(&g_fdSetLock);
834
835 return ret;
836 }
837
DelTriggerFromSet(int32_t fd,TriggerType triggerType)838 static int32_t DelTriggerFromSet(int32_t fd, TriggerType triggerType)
839 {
840 int32_t ret = SOFTBUS_OK;
841 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
842 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
843 return SOFTBUS_ERR;
844 }
845 switch (triggerType) {
846 case READ_TRIGGER:
847 SoftBusSocketFdClr(fd, &g_readSet);
848 break;
849 case WRITE_TRIGGER:
850 SoftBusSocketFdClr(fd, &g_writeSet);
851 break;
852 case EXCEPT_TRIGGER:
853 SoftBusSocketFdClr(fd, &g_exceptSet);
854 break;
855 case RW_TRIGGER:
856 SoftBusSocketFdClr(fd, &g_readSet);
857 SoftBusSocketFdClr(fd, &g_writeSet);
858 break;
859 default:
860 ret = SOFTBUS_INVALID_PARAM;
861 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid trigger type");
862 break;
863 }
864 SoftBusMutexUnlock(&g_fdSetLock);
865
866 return ret;
867 }
868
StartBaseClient(ListenerModule module)869 int32_t StartBaseClient(ListenerModule module)
870 {
871 SoftbusListenerNode *node = RequestListenerNode(module);
872 if (node == NULL) {
873 return SOFTBUS_INVALID_PARAM;
874 }
875 int32_t ret;
876
877 do {
878 if (node->listener == NULL) {
879 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BaseListener not set, start failed.");
880 ret = SOFTBUS_ERR;
881 break;
882 }
883 if (node->info.status != LISTENER_IDLE) {
884 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "listener is not in idle status.");
885 ret = SOFTBUS_ERR;
886 break;
887 }
888 ret = StartListenerThread(node, CLIENT_MODE);
889 SoftBusLog(
890 SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "StartBaseClient %s", (ret == SOFTBUS_OK) ? "SUCCESS" : "FAILED");
891 } while (false);
892
893 ReleaseListenerNode(node);
894
895 return ret;
896 }
897
StartBaseListener(const LocalListenerInfo * info)898 int32_t StartBaseListener(const LocalListenerInfo *info)
899 {
900 if (info == NULL || (info->type != CONNECT_TCP && info->type != CONNECT_P2P) || info->socketOption.port < 0) {
901 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: bad input", __func__);
902 return SOFTBUS_INVALID_PARAM;
903 }
904 ListenerModule module = info->socketOption.moduleId;
905 SoftbusListenerNode *node = RequestListenerNode(module);
906 if (node == NULL) {
907 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: no listner with module %" PRIu32, __func__, module);
908 return SOFTBUS_NOT_FIND;
909 }
910 int32_t ret;
911 do {
912 if (node->listener == NULL) {
913 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BaseListener not set, start failed.");
914 ret = SOFTBUS_ERR;
915 break;
916 }
917 if (node->info.status != LISTENER_IDLE) {
918 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:listener is not in idle status.status=%d", __func__,
919 node->info.status);
920 ret = SOFTBUS_ERR;
921 break;
922 }
923 node->socketIf = GetSocketInterface(info->socketOption.protocol);
924 if (node->socketIf == NULL) {
925 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:no such protocol.protocol=%d", __func__,
926 info->socketOption.protocol);
927 ret = SOFTBUS_ERR;
928 break;
929 }
930 ret = InitListenFd(node, info);
931 if (ret != SOFTBUS_OK) {
932 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:InitListenFd failed!ret=%" PRId32, __func__, ret);
933 break;
934 }
935 ret = StartListenerThread(node, SERVER_MODE);
936 if (ret != SOFTBUS_OK) {
937 SoftBusLog(
938 SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:Start listener thread failed!ret=%" PRId32, __func__, ret);
939 ReleaseListenerSockets(node);
940 break;
941 }
942 } while (false);
943 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "StartBaseListener success, fd = %d, module = %d",
944 node->info.listenPort, module);
945 int32_t port = node->info.listenPort;
946 ReleaseListenerNode(node);
947 if (ret != SOFTBUS_OK) {
948 return ret;
949 }
950 return port;
951 }
952
GetSoftbusBaseListener(ListenerModule module,SoftbusBaseListener * listener)953 int32_t GetSoftbusBaseListener(ListenerModule module, SoftbusBaseListener *listener)
954 {
955 if (listener == NULL) {
956 return SOFTBUS_INVALID_PARAM;
957 }
958 SoftbusListenerNode *node = RequestListenerNode(module);
959 if (node == NULL) {
960 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: no listner with module %" PRIu32, __func__, module);
961 return SOFTBUS_NOT_FIND;
962 }
963
964 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
965 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
966 ReleaseListenerNode(node);
967 return SOFTBUS_LOCK_ERR;
968 }
969 int32_t ret = SOFTBUS_OK;
970 do {
971 if (node->listener == NULL) {
972 ret = SOFTBUS_NOT_FIND;
973 break;
974 }
975 if (memcpy_s(listener, sizeof(SoftbusBaseListener), node->listener, sizeof(SoftbusBaseListener)) != EOK) {
976 ret = SOFTBUS_MEM_ERR;
977 break;
978 }
979 } while (false);
980 (void)SoftBusMutexUnlock(&node->lock);
981 (void)ReleaseListenerNode(node);
982 return ret;
983 }
984
SetSoftbusBaseListener(ListenerModule module,const SoftbusBaseListener * listener)985 int32_t SetSoftbusBaseListener(ListenerModule module, const SoftbusBaseListener *listener)
986 {
987 if (listener == NULL || listener->onConnectEvent == NULL || listener->onDataEvent == NULL) {
988 return SOFTBUS_INVALID_PARAM;
989 }
990 SoftbusListenerNode *node = RequestListenerNode(module);
991 if (node == NULL) {
992 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: no listner with module %" PRIu32, __func__, module);
993 return SOFTBUS_NOT_FIND;
994 }
995
996 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
997 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "set listener lock failed");
998 (void)ReleaseListenerNode(node);
999 return SOFTBUS_LOCK_ERR;
1000 }
1001
1002 int32_t ret = SOFTBUS_OK;
1003 do {
1004 if (node->listener == NULL) {
1005 node->listener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener));
1006 if (node->listener == NULL) {
1007 ret = SOFTBUS_MALLOC_ERR;
1008 break;
1009 }
1010 }
1011 if (memcpy_s(node->listener, sizeof(SoftbusBaseListener), listener, sizeof(SoftbusBaseListener)) != EOK) {
1012 ret = SOFTBUS_MEM_ERR;
1013 break;
1014 }
1015 } while (false);
1016 (void)SoftBusMutexUnlock(&node->lock);
1017 (void)ReleaseListenerNode(node);
1018 return ret;
1019 }
1020
StopBaseListener(ListenerModule module)1021 int32_t StopBaseListener(ListenerModule module)
1022 {
1023 SoftbusListenerNode *node = RequestListenerNode(module);
1024 if (node == NULL) {
1025 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: no listner with module %" PRIu32, __func__, module);
1026 return SOFTBUS_NOT_FIND;
1027 }
1028 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
1029 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
1030 ReleaseListenerNode(node);
1031 return SOFTBUS_LOCK_ERR;
1032 }
1033
1034 int32_t listenFd = node->info.listenFd;
1035 node->info.listenFd = -1;
1036 int32_t ret = StopListenerThread(node);
1037 if (ret != SOFTBUS_OK) {
1038 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "stop listen thread failed!ret = %" PRId32 ", module = %d.",
1039 ret, module);
1040 }
1041 SoftBusMutexUnlock(&node->lock);
1042 ReleaseListenerNode(node);
1043
1044 if (listenFd > 0) {
1045 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "del listen fd from readSet, fd = %d, module = %d.",
1046 listenFd, module);
1047 DelTriggerFromSet(listenFd, READ_TRIGGER);
1048 ConnShutdownSocket(listenFd);
1049 UpdateMaxFd();
1050 }
1051 return ret;
1052 }
1053
WaitBaseListenerDestroy(ListenerModule module,int32_t waitTimeOut)1054 static int32_t WaitBaseListenerDestroy(ListenerModule module, int32_t waitTimeOut)
1055 {
1056 const int32_t waitInterval = 100;
1057 while (waitTimeOut > 0) {
1058 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
1059 if (ret != SOFTBUS_OK) {
1060 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
1061 return SOFTBUS_LOCK_ERR;
1062 }
1063
1064 if (g_listenerList[module] != NULL) {
1065 SoftBusMutexUnlock(&g_listenerListLock);
1066 SoftBusSleepMs(waitInterval);
1067 waitTimeOut -= waitInterval;
1068 continue;
1069 }
1070 (void)SoftBusMutexUnlock(&g_listenerListLock);
1071 return SOFTBUS_OK;
1072 }
1073 return SOFTBUS_TIMOUT;
1074 }
1075
DestroyBaseListener(ListenerModule module)1076 void DestroyBaseListener(ListenerModule module)
1077 {
1078 if (module >= UNUSE_BUTT) {
1079 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid listener module.");
1080 return;
1081 }
1082 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "%s:Destory listener module %" PRIu32, __func__, module);
1083 int32_t ret = SoftBusMutexLock(&g_listenerListLock);
1084 if (ret != SOFTBUS_OK) {
1085 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:get lock failed!ret=%" PRId32, __func__, ret);
1086 return;
1087 }
1088
1089 ret = ShutdownBaseListener(g_listenerList[module]);
1090 if (ret != SOFTBUS_OK) {
1091 (void)SoftBusMutexUnlock(&g_listenerListLock);
1092 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:shutdown listener failed!ret=%" PRId32, __func__, ret);
1093 g_listenerList[module] = NULL;
1094 return;
1095 }
1096
1097 ret = ReleaseListenerRef(module);
1098 if (ret != SOFTBUS_OK) {
1099 (void)SoftBusMutexUnlock(&g_listenerListLock);
1100 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:release listener failed!ret=%" PRId32, __func__, ret);
1101 g_listenerList[module] = NULL;
1102 return;
1103 }
1104 (void)SoftBusMutexUnlock(&g_listenerListLock);
1105 #define LISTENER_MODULE_DESTROY_TIMEOUT (30 * 1000)
1106 ret = WaitBaseListenerDestroy(module, LISTENER_MODULE_DESTROY_TIMEOUT);
1107 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "%s:Destory listener module %" PRIu32 " finished. ret=%" PRId32,
1108 __func__, module, ret);
1109 }
1110
CheckFdIsExist(const SoftbusBaseListenerInfo * info,int32_t fd)1111 static bool CheckFdIsExist(const SoftbusBaseListenerInfo *info, int32_t fd)
1112 {
1113 FdNode *item = NULL;
1114 FdNode *nextItem = NULL;
1115 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &info->node, FdNode, node)
1116 {
1117 if (item->fd == fd) {
1118 return true;
1119 }
1120 }
1121 return false;
1122 }
1123
AddNewFdNode(SoftbusBaseListenerInfo * info,int32_t fd)1124 static int32_t AddNewFdNode(SoftbusBaseListenerInfo *info, int32_t fd)
1125 {
1126 FdNode *newNode = (FdNode *)SoftBusCalloc(sizeof(FdNode));
1127 if (newNode == NULL) {
1128 return SOFTBUS_MALLOC_ERR;
1129 }
1130 newNode->fd = fd;
1131 ListInit(&newNode->node);
1132 ListNodeInsert(&info->node, &newNode->node);
1133 info->fdCount++;
1134 return SOFTBUS_OK;
1135 }
1136
DelFdNode(SoftbusBaseListenerInfo * info,int32_t fd)1137 static void DelFdNode(SoftbusBaseListenerInfo *info, int32_t fd)
1138 {
1139 FdNode *item = NULL;
1140 FdNode *nextItem = NULL;
1141
1142 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &info->node, FdNode, node)
1143 {
1144 if (item->fd == fd) {
1145 ListDelete(&item->node);
1146 SoftBusFree(item);
1147 info->fdCount--;
1148 return;
1149 }
1150 }
1151 }
1152
AddTrigger(ListenerModule module,int32_t fd,TriggerType triggerType)1153 int32_t AddTrigger(ListenerModule module, int32_t fd, TriggerType triggerType)
1154 {
1155 if (fd < 0 || CheckTrigger(triggerType) != SOFTBUS_OK) {
1156 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid AddTrigger Param");
1157 return SOFTBUS_INVALID_PARAM;
1158 }
1159
1160 SoftbusListenerNode *node = RequestListenerNode(module);
1161 if (node == NULL) {
1162 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: no listner with module %" PRIu32, __func__, module);
1163 return SOFTBUS_NOT_FIND;
1164 }
1165
1166 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
1167 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
1168 ReleaseListenerNode(node);
1169 return SOFTBUS_LOCK_ERR;
1170 }
1171 int32_t ret = SOFTBUS_OK;
1172
1173 do {
1174 if (node->info.fdCount > MAX_LISTEN_EVENTS) {
1175 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Cannot AddTrigger any more");
1176 break;
1177 }
1178
1179 ret = AddTriggerToSet(fd, triggerType);
1180 if (ret != SOFTBUS_OK) {
1181 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR,
1182 "AddTrigger failed!ret=%" PRId32 " Module=%" PRIu32 "TriggerType=%d", ret, module, triggerType);
1183 break;
1184 }
1185
1186 if (CheckFdIsExist(&node->info, fd)) {
1187 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "fd exist");
1188 break;
1189 }
1190
1191 if (AddNewFdNode(&node->info, fd) != SOFTBUS_OK) {
1192 (void)DelTriggerFromSet(fd, triggerType);
1193 break;
1194 }
1195 } while (false);
1196
1197 SoftBusMutexUnlock(&node->lock);
1198 ReleaseListenerNode(node);
1199
1200 if (SoftBusMutexLock(&g_fdSetLock) != 0) {
1201 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
1202 return SOFTBUS_OK;
1203 }
1204 g_maxFd = MaxFd(fd, g_maxFd);
1205 SoftBusMutexUnlock(&g_fdSetLock);
1206
1207 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO,
1208 "AddTrigger fd:%d success, current fdcount:%d, module:%d, triggerType:%d", fd, node->info.fdCount, module,
1209 triggerType);
1210 return SOFTBUS_OK;
1211 }
1212
DelTrigger(ListenerModule module,int32_t fd,TriggerType triggerType)1213 int32_t DelTrigger(ListenerModule module, int32_t fd, TriggerType triggerType)
1214 {
1215 if (fd < 0 || CheckTrigger(triggerType)) {
1216 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid AddTrigger Param");
1217 return SOFTBUS_INVALID_PARAM;
1218 }
1219
1220 SoftbusListenerNode *node = RequestListenerNode(module);
1221 if (node == NULL) {
1222 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s: no listner with module %" PRIu32, __func__, module);
1223 return SOFTBUS_NOT_FIND;
1224 }
1225
1226 if (SoftBusMutexLock(&node->lock) != SOFTBUS_OK) {
1227 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "%s:lock failed", __func__);
1228 ReleaseListenerNode(node);
1229 return SOFTBUS_LOCK_ERR;
1230 }
1231
1232 do {
1233 if (DelTriggerFromSet(fd, triggerType) != SOFTBUS_OK) {
1234 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "del trigger fail: fd = %d, trigger = %d", fd, triggerType);
1235 }
1236
1237 if (SoftBusSocketFdIsset(fd, &g_writeSet) || SoftBusSocketFdIsset(fd, &g_readSet) ||
1238 SoftBusSocketFdIsset(fd, &g_exceptSet)) {
1239 break;
1240 }
1241
1242 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "%s:[fd:%d] removed from all fdSet. del fdnode", __func__, fd);
1243 DelFdNode(&node->info, fd);
1244 } while (false);
1245
1246 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "%s:[fd:%d] success, current fdcount:%d, module:%d, triggerType:%d",
1247 __func__, fd, node->info.fdCount, module, triggerType);
1248
1249 SoftBusMutexUnlock(&node->lock);
1250 ReleaseListenerNode(node);
1251 UpdateMaxFd();
1252
1253 return SOFTBUS_OK;
1254 }
1255