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