1f1549183Sopenharmony_ci/*
2f1549183Sopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3f1549183Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f1549183Sopenharmony_ci * you may not use this file except in compliance with the License.
5f1549183Sopenharmony_ci * You may obtain a copy of the License at
6f1549183Sopenharmony_ci *
7f1549183Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f1549183Sopenharmony_ci *
9f1549183Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f1549183Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f1549183Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f1549183Sopenharmony_ci * See the License for the specific language governing permissions and
13f1549183Sopenharmony_ci * limitations under the License.
14f1549183Sopenharmony_ci */
15f1549183Sopenharmony_ci
16f1549183Sopenharmony_ci#include "server.h"
17f1549183Sopenharmony_ci#include <fcntl.h>
18f1549183Sopenharmony_ci#include <pthread.h>
19f1549183Sopenharmony_ci#include <unistd.h>
20f1549183Sopenharmony_ci#include <stdlib.h>
21f1549183Sopenharmony_ci#include <sys/epoll.h>
22f1549183Sopenharmony_ci#include <sys/socket.h>
23f1549183Sopenharmony_ci#include <sys/un.h>
24f1549183Sopenharmony_ci#include "common.h"
25f1549183Sopenharmony_ci#include "log.h"
26f1549183Sopenharmony_ci#include "net.h"
27f1549183Sopenharmony_ci
28f1549183Sopenharmony_ci#undef LOG_TAG
29f1549183Sopenharmony_ci#define LOG_TAG "WifiRpcServer"
30f1549183Sopenharmony_ci
31f1549183Sopenharmony_ciconst int DEFAULT_LISTEN_QUEUE_SIZE = 10;
32f1549183Sopenharmony_ciconst int MAX_SUPPORT_CLIENT_FD_SIZE = 256; /* support max clients online */
33f1549183Sopenharmony_ciconst int DEFAULT_HASHTABLE_SLOTS = 7;
34f1549183Sopenharmony_ciconst int SERIAL_DATA_HEAD_SIZE = 2; /* RPC message head size: N| / C| just 2 */
35f1549183Sopenharmony_ci
36f1549183Sopenharmony_cistatic int BeforeLoop(RpcServer *server);
37f1549183Sopenharmony_cistatic int RemoveCallback(RpcServer *server, const Context *context);
38f1549183Sopenharmony_ci
39f1549183Sopenharmony_cistatic int OnAccept(RpcServer *server, unsigned int mask)
40f1549183Sopenharmony_ci{
41f1549183Sopenharmony_ci    if (server == NULL) {
42f1549183Sopenharmony_ci        return -1;
43f1549183Sopenharmony_ci    }
44f1549183Sopenharmony_ci
45f1549183Sopenharmony_ci    if ((mask & READ_EVENT) == 0) {
46f1549183Sopenharmony_ci        return 0;
47f1549183Sopenharmony_ci    }
48f1549183Sopenharmony_ci    int fd = accept(server->listenFd, NULL, NULL);
49f1549183Sopenharmony_ci    if (fd < 0) {
50f1549183Sopenharmony_ci        return -1;
51f1549183Sopenharmony_ci    }
52f1549183Sopenharmony_ci    if (SetNonBlock(fd, 1) != 0) {
53f1549183Sopenharmony_ci        LOGE("OnAccept  SetNonBlock failed!");
54f1549183Sopenharmony_ci        close(fd);
55f1549183Sopenharmony_ci        return -1;
56f1549183Sopenharmony_ci    }
57f1549183Sopenharmony_ci    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
58f1549183Sopenharmony_ci        LOGE("OnAccept  fcntl failed!");
59f1549183Sopenharmony_ci        close(fd);
60f1549183Sopenharmony_ci        return -1;
61f1549183Sopenharmony_ci    }
62f1549183Sopenharmony_ci    Context *context = CreateContext(CONTEXT_BUFFER_MIN_SIZE);
63f1549183Sopenharmony_ci    if (context != NULL) {
64f1549183Sopenharmony_ci        context->fd = fd;
65f1549183Sopenharmony_ci        InsertHashTable(server->clients, context);
66f1549183Sopenharmony_ci        AddFdEvent(server->loop, fd, READ_EVENT | WRIT_EVENT);
67f1549183Sopenharmony_ci    } else {
68f1549183Sopenharmony_ci        close(fd);
69f1549183Sopenharmony_ci        LOGE("Init Client context failed!");
70f1549183Sopenharmony_ci        return -1;
71f1549183Sopenharmony_ci    }
72f1549183Sopenharmony_ci    return 0;
73f1549183Sopenharmony_ci}
74f1549183Sopenharmony_ci
75f1549183Sopenharmony_ciRpcServer *CreateRpcServer(const char *path)
76f1549183Sopenharmony_ci{
77f1549183Sopenharmony_ci    if (path == NULL) {
78f1549183Sopenharmony_ci        return NULL;
79f1549183Sopenharmony_ci    }
80f1549183Sopenharmony_ci    RpcServer *server = (RpcServer *)calloc(1, sizeof(RpcServer));
81f1549183Sopenharmony_ci    if (server == NULL) {
82f1549183Sopenharmony_ci        return NULL;
83f1549183Sopenharmony_ci    }
84f1549183Sopenharmony_ci    int flag = 1;
85f1549183Sopenharmony_ci    do {
86f1549183Sopenharmony_ci        int ret = CreateUnixServer(path, DEFAULT_LISTEN_QUEUE_SIZE);
87f1549183Sopenharmony_ci        if (ret < 0) {
88f1549183Sopenharmony_ci            break;
89f1549183Sopenharmony_ci        }
90f1549183Sopenharmony_ci        server->listenFd = ret;
91f1549183Sopenharmony_ci        server->isHandlingMsg = false;
92f1549183Sopenharmony_ci        server->loop = CreateEventLoop(MAX_SUPPORT_CLIENT_FD_SIZE);
93f1549183Sopenharmony_ci        if (server->loop == NULL) {
94f1549183Sopenharmony_ci            break;
95f1549183Sopenharmony_ci        }
96f1549183Sopenharmony_ci        server->clients = InitHashTable(DEFAULT_HASHTABLE_SLOTS);
97f1549183Sopenharmony_ci        if (server->clients == NULL) {
98f1549183Sopenharmony_ci            break;
99f1549183Sopenharmony_ci        }
100f1549183Sopenharmony_ci        if (AddFdEvent(server->loop, server->listenFd, READ_EVENT) < 0) {
101f1549183Sopenharmony_ci            break;
102f1549183Sopenharmony_ci        }
103f1549183Sopenharmony_ci        pthread_mutex_init(&server->mutex, NULL);
104f1549183Sopenharmony_ci        flag = 0;
105f1549183Sopenharmony_ci    } while (0);
106f1549183Sopenharmony_ci    if (flag) {
107f1549183Sopenharmony_ci        ReleaseRpcServer(server);
108f1549183Sopenharmony_ci        return NULL;
109f1549183Sopenharmony_ci    }
110f1549183Sopenharmony_ci    return server;
111f1549183Sopenharmony_ci}
112f1549183Sopenharmony_ci
113f1549183Sopenharmony_cistatic int DealReadMessage(RpcServer *server, Context *client)
114f1549183Sopenharmony_ci{
115f1549183Sopenharmony_ci    if ((server == NULL) || (client == NULL)) {
116f1549183Sopenharmony_ci        return 0;
117f1549183Sopenharmony_ci    }
118f1549183Sopenharmony_ci    char *buf = ContextGetReadRecord(client);
119f1549183Sopenharmony_ci    if (buf == NULL) {
120f1549183Sopenharmony_ci        return 0;
121f1549183Sopenharmony_ci    }
122f1549183Sopenharmony_ci    client->oneProcess = buf;
123f1549183Sopenharmony_ci    client->nPos = SERIAL_DATA_HEAD_SIZE; /* N| */
124f1549183Sopenharmony_ci    client->nSize = strlen(buf);
125f1549183Sopenharmony_ci    OnTransact(server, client);
126f1549183Sopenharmony_ci    free(buf);
127f1549183Sopenharmony_ci    buf = NULL;
128f1549183Sopenharmony_ci    AddFdEvent(server->loop, client->fd, WRIT_EVENT);
129f1549183Sopenharmony_ci    return 1;
130f1549183Sopenharmony_ci}
131f1549183Sopenharmony_ci
132f1549183Sopenharmony_cistatic unsigned int CheckEventMask(const struct epoll_event *e)
133f1549183Sopenharmony_ci{
134f1549183Sopenharmony_ci    if (e == NULL) {
135f1549183Sopenharmony_ci        return 0;
136f1549183Sopenharmony_ci    }
137f1549183Sopenharmony_ci    unsigned int mask = NONE_EVENT;
138f1549183Sopenharmony_ci    if ((e->events & EPOLLERR) || (e->events & EPOLLHUP)) {
139f1549183Sopenharmony_ci        mask |= READ_EVENT | WRIT_EVENT | EXCP_EVENT;
140f1549183Sopenharmony_ci    } else {
141f1549183Sopenharmony_ci        if (e->events & EPOLLIN) {
142f1549183Sopenharmony_ci            mask |= READ_EVENT;
143f1549183Sopenharmony_ci        }
144f1549183Sopenharmony_ci        if (e->events & EPOLLOUT) {
145f1549183Sopenharmony_ci            mask |= WRIT_EVENT;
146f1549183Sopenharmony_ci        }
147f1549183Sopenharmony_ci    }
148f1549183Sopenharmony_ci    return mask;
149f1549183Sopenharmony_ci}
150f1549183Sopenharmony_ci
151f1549183Sopenharmony_cistatic void DealFdReadEvent(RpcServer *server, Context *client, unsigned int mask)
152f1549183Sopenharmony_ci{
153f1549183Sopenharmony_ci    if ((server == NULL) || (client == NULL)) {
154f1549183Sopenharmony_ci        return;
155f1549183Sopenharmony_ci    }
156f1549183Sopenharmony_ci    DealReadMessage(server, client);
157f1549183Sopenharmony_ci    int ret = ContextReadNet(client);
158f1549183Sopenharmony_ci    if ((ret == SOCK_ERR) || ((ret == SOCK_CLOSE) && (mask & EXCP_EVENT))) {
159f1549183Sopenharmony_ci        LOGE("ContextReadNet failed: %{public}d", ret);
160f1549183Sopenharmony_ci        DelFdEvent(server->loop, client->fd, READ_EVENT | WRIT_EVENT);
161f1549183Sopenharmony_ci    } else if (ret == SOCK_CLOSE) {
162f1549183Sopenharmony_ci        LOGE("Socket close.");
163f1549183Sopenharmony_ci        DelFdEvent(server->loop, client->fd, READ_EVENT);
164f1549183Sopenharmony_ci    } else if (ret > 0) {
165f1549183Sopenharmony_ci        int haveMsg;
166f1549183Sopenharmony_ci        do {
167f1549183Sopenharmony_ci            haveMsg = DealReadMessage(server, client);
168f1549183Sopenharmony_ci        } while (haveMsg);
169f1549183Sopenharmony_ci    }
170f1549183Sopenharmony_ci    return;
171f1549183Sopenharmony_ci}
172f1549183Sopenharmony_ci
173f1549183Sopenharmony_cistatic void DealFdWriteEvent(RpcServer *server, Context *client)
174f1549183Sopenharmony_ci{
175f1549183Sopenharmony_ci    if ((server == NULL) || (client == NULL)) {
176f1549183Sopenharmony_ci        return;
177f1549183Sopenharmony_ci    }
178f1549183Sopenharmony_ci
179f1549183Sopenharmony_ci    if (client->wBegin != client->wEnd) {
180f1549183Sopenharmony_ci        int tmp = ContextWriteNet(client);
181f1549183Sopenharmony_ci        if (tmp < 0) {
182f1549183Sopenharmony_ci            LOGE("ContextWriteNet failed: %{public}d", tmp);
183f1549183Sopenharmony_ci            DelFdEvent(server->loop, client->fd, READ_EVENT | WRIT_EVENT);
184f1549183Sopenharmony_ci        }
185f1549183Sopenharmony_ci    } else {
186f1549183Sopenharmony_ci        LOGE("Del write event.");
187f1549183Sopenharmony_ci        DelFdEvent(server->loop, client->fd, WRIT_EVENT);
188f1549183Sopenharmony_ci    }
189f1549183Sopenharmony_ci    return;
190f1549183Sopenharmony_ci}
191f1549183Sopenharmony_ci
192f1549183Sopenharmony_cistatic void DealFdEvents(RpcServer *server, int fd, unsigned int mask)
193f1549183Sopenharmony_ci{
194f1549183Sopenharmony_ci    if (server == NULL) {
195f1549183Sopenharmony_ci        return;
196f1549183Sopenharmony_ci    }
197f1549183Sopenharmony_ci    Context *client = FindContext(server->clients, fd);
198f1549183Sopenharmony_ci    if (client == NULL) {
199f1549183Sopenharmony_ci        LOGD("not find %{public}d clients!", fd);
200f1549183Sopenharmony_ci        return;
201f1549183Sopenharmony_ci    }
202f1549183Sopenharmony_ci    if (mask & READ_EVENT) {
203f1549183Sopenharmony_ci        DealFdReadEvent(server, client, mask);
204f1549183Sopenharmony_ci    }
205f1549183Sopenharmony_ci    if (mask & WRIT_EVENT) {
206f1549183Sopenharmony_ci        DealFdWriteEvent(server, client);
207f1549183Sopenharmony_ci    }
208f1549183Sopenharmony_ci    if (server->loop->fdMasks[fd].mask == NONE_EVENT) {
209f1549183Sopenharmony_ci        close(fd);
210f1549183Sopenharmony_ci        DeleteHashTable(server->clients, client);
211f1549183Sopenharmony_ci        RemoveCallback(server, client);
212f1549183Sopenharmony_ci        ReleaseContext(client);
213f1549183Sopenharmony_ci    }
214f1549183Sopenharmony_ci    return;
215f1549183Sopenharmony_ci}
216f1549183Sopenharmony_ci
217f1549183Sopenharmony_ciint RunRpcLoop(RpcServer *server)
218f1549183Sopenharmony_ci{
219f1549183Sopenharmony_ci    if (server == NULL) {
220f1549183Sopenharmony_ci        return -1;
221f1549183Sopenharmony_ci    }
222f1549183Sopenharmony_ci
223f1549183Sopenharmony_ci    EventLoop *loop = server->loop;
224f1549183Sopenharmony_ci    while (!loop->stop) {
225f1549183Sopenharmony_ci        BeforeLoop(server);
226f1549183Sopenharmony_ci        server->isHandlingMsg = false;
227f1549183Sopenharmony_ci        int retval = epoll_wait(loop->epfd, loop->epEvents, loop->setSize, -1);
228f1549183Sopenharmony_ci        server->isHandlingMsg = true;
229f1549183Sopenharmony_ci        for (int i = 0; i < retval; ++i) {
230f1549183Sopenharmony_ci            struct epoll_event *e = loop->epEvents + i;
231f1549183Sopenharmony_ci            int fd = e->data.fd;
232f1549183Sopenharmony_ci            unsigned int mask = CheckEventMask(e);
233f1549183Sopenharmony_ci            if (fd == server->listenFd) {
234f1549183Sopenharmony_ci                OnAccept(server, mask);
235f1549183Sopenharmony_ci            } else {
236f1549183Sopenharmony_ci                DealFdEvents(server, fd, mask);
237f1549183Sopenharmony_ci            }
238f1549183Sopenharmony_ci        }
239f1549183Sopenharmony_ci    }
240f1549183Sopenharmony_ci    return 0;
241f1549183Sopenharmony_ci}
242f1549183Sopenharmony_ci
243f1549183Sopenharmony_civoid ReleaseRpcServer(RpcServer *server)
244f1549183Sopenharmony_ci{
245f1549183Sopenharmony_ci    if (server != NULL) {
246f1549183Sopenharmony_ci        if (server->clients != NULL) {
247f1549183Sopenharmony_ci            DestroyHashTable(server->clients);
248f1549183Sopenharmony_ci        }
249f1549183Sopenharmony_ci        if (server->loop != NULL) {
250f1549183Sopenharmony_ci            DestroyEventLoop(server->loop);
251f1549183Sopenharmony_ci        }
252f1549183Sopenharmony_ci        if (server->listenFd > 0) {
253f1549183Sopenharmony_ci            close(server->listenFd);
254f1549183Sopenharmony_ci        }
255f1549183Sopenharmony_ci        pthread_mutex_destroy(&server->mutex);
256f1549183Sopenharmony_ci        free(server);
257f1549183Sopenharmony_ci        server = NULL;
258f1549183Sopenharmony_ci    }
259f1549183Sopenharmony_ci}
260f1549183Sopenharmony_ci
261f1549183Sopenharmony_cistatic int BeforeLoop(RpcServer *server)
262f1549183Sopenharmony_ci{
263f1549183Sopenharmony_ci    if (server == NULL) {
264f1549183Sopenharmony_ci        return -1;
265f1549183Sopenharmony_ci    }
266f1549183Sopenharmony_ci    pthread_mutex_lock(&server->mutex);
267f1549183Sopenharmony_ci    for (int i = 0; i < server->nEvents; ++i) {
268f1549183Sopenharmony_ci        int event = server->events[i];
269f1549183Sopenharmony_ci        uint32_t num = sizeof(server->eventNode) / sizeof(server->eventNode[0]);
270f1549183Sopenharmony_ci        int pos = event % num;
271f1549183Sopenharmony_ci        struct Node *p = server->eventNode[pos].head;
272f1549183Sopenharmony_ci        while (p != NULL) {
273f1549183Sopenharmony_ci            Context *context = p->context;
274f1549183Sopenharmony_ci            OnCallbackTransact(server, event, context);
275f1549183Sopenharmony_ci            AddFdEvent(server->loop, context->fd, WRIT_EVENT);
276f1549183Sopenharmony_ci            p = p->next;
277f1549183Sopenharmony_ci        }
278f1549183Sopenharmony_ci        EndCallbackTransact(server, event);
279f1549183Sopenharmony_ci    }
280f1549183Sopenharmony_ci    server->nEvents = 0;
281f1549183Sopenharmony_ci    pthread_mutex_unlock(&server->mutex);
282f1549183Sopenharmony_ci    return 0;
283f1549183Sopenharmony_ci}
284f1549183Sopenharmony_ci
285f1549183Sopenharmony_ciint EmitEvent(RpcServer *server, int event)
286f1549183Sopenharmony_ci{
287f1549183Sopenharmony_ci    if (server == NULL) {
288f1549183Sopenharmony_ci        return -1;
289f1549183Sopenharmony_ci    }
290f1549183Sopenharmony_ci    int num = sizeof(server->events) / sizeof(server->events[0]);
291f1549183Sopenharmony_ci    pthread_mutex_lock(&server->mutex);
292f1549183Sopenharmony_ci    if (server->nEvents >= num) {
293f1549183Sopenharmony_ci        pthread_mutex_unlock(&server->mutex);
294f1549183Sopenharmony_ci        return -1;
295f1549183Sopenharmony_ci    }
296f1549183Sopenharmony_ci    server->events[server->nEvents] = event;
297f1549183Sopenharmony_ci    ++server->nEvents;
298f1549183Sopenharmony_ci    pthread_mutex_unlock(&server->mutex);
299f1549183Sopenharmony_ci    /* Triger write to socket */
300f1549183Sopenharmony_ci    if (server->isHandlingMsg == false) {
301f1549183Sopenharmony_ci        BeforeLoop(server);
302f1549183Sopenharmony_ci    }
303f1549183Sopenharmony_ci    return 0;
304f1549183Sopenharmony_ci}
305f1549183Sopenharmony_ci
306f1549183Sopenharmony_ciint RegisterCallback(RpcServer *server, int event, Context *context)
307f1549183Sopenharmony_ci{
308f1549183Sopenharmony_ci    if ((server == NULL) || (context == NULL)) {
309f1549183Sopenharmony_ci        return -1;
310f1549183Sopenharmony_ci    }
311f1549183Sopenharmony_ci
312f1549183Sopenharmony_ci    uint32_t num = sizeof(server->eventNode) / sizeof(server->eventNode[0]);
313f1549183Sopenharmony_ci    int pos = event % num;
314f1549183Sopenharmony_ci    if (pos >= MAX_EVENT_NODE_COUNT) {
315f1549183Sopenharmony_ci        return -1;
316f1549183Sopenharmony_ci    }
317f1549183Sopenharmony_ci    server->eventNode[pos].event = event;
318f1549183Sopenharmony_ci    struct Node *p = server->eventNode[pos].head;
319f1549183Sopenharmony_ci    while (p != NULL && p->context->fd != context->fd) {
320f1549183Sopenharmony_ci        p = p->next;
321f1549183Sopenharmony_ci    }
322f1549183Sopenharmony_ci    if (p == NULL) {
323f1549183Sopenharmony_ci        p = (struct Node *)calloc(1, sizeof(struct Node));
324f1549183Sopenharmony_ci        if (p != NULL) {
325f1549183Sopenharmony_ci            p->next = server->eventNode[pos].head;
326f1549183Sopenharmony_ci            p->context = context;
327f1549183Sopenharmony_ci            server->eventNode[pos].head = p;
328f1549183Sopenharmony_ci        }
329f1549183Sopenharmony_ci    }
330f1549183Sopenharmony_ci    return 0;
331f1549183Sopenharmony_ci}
332f1549183Sopenharmony_ci
333f1549183Sopenharmony_ciint UnRegisterCallback(RpcServer *server, int event, const Context *context)
334f1549183Sopenharmony_ci{
335f1549183Sopenharmony_ci    if ((server == NULL) || (context == NULL)) {
336f1549183Sopenharmony_ci        return -1;
337f1549183Sopenharmony_ci    }
338f1549183Sopenharmony_ci
339f1549183Sopenharmony_ci    uint32_t num = sizeof(server->eventNode) / sizeof(server->eventNode[0]);
340f1549183Sopenharmony_ci    int pos = event % num;
341f1549183Sopenharmony_ci    if (pos >= MAX_EVENT_NODE_COUNT) {
342f1549183Sopenharmony_ci        return -1;
343f1549183Sopenharmony_ci    }
344f1549183Sopenharmony_ci    server->eventNode[pos].event = event;
345f1549183Sopenharmony_ci    struct Node *p = server->eventNode[pos].head;
346f1549183Sopenharmony_ci    struct Node *q = p;
347f1549183Sopenharmony_ci    while (p != NULL && p->context->fd != context->fd) {
348f1549183Sopenharmony_ci        q = p;
349f1549183Sopenharmony_ci        p = p->next;
350f1549183Sopenharmony_ci    }
351f1549183Sopenharmony_ci    if (p != NULL) {
352f1549183Sopenharmony_ci        if (p == server->eventNode[pos].head) {
353f1549183Sopenharmony_ci            server->eventNode[pos].head = p->next;
354f1549183Sopenharmony_ci        } else {
355f1549183Sopenharmony_ci            q->next = p->next;
356f1549183Sopenharmony_ci        }
357f1549183Sopenharmony_ci        free(p);
358f1549183Sopenharmony_ci        p = NULL;
359f1549183Sopenharmony_ci    }
360f1549183Sopenharmony_ci    return 0;
361f1549183Sopenharmony_ci}
362f1549183Sopenharmony_ci
363f1549183Sopenharmony_cistatic int RemoveCallback(RpcServer *server, const Context *context)
364f1549183Sopenharmony_ci{
365f1549183Sopenharmony_ci    if ((server == NULL) || (context == NULL)) {
366f1549183Sopenharmony_ci        return -1;
367f1549183Sopenharmony_ci    }
368f1549183Sopenharmony_ci
369f1549183Sopenharmony_ci    uint32_t num = sizeof(server->eventNode) / sizeof(server->eventNode[0]);
370f1549183Sopenharmony_ci    for (int i = 0; i < num; ++i) {
371f1549183Sopenharmony_ci        struct Node *p = server->eventNode[i].head;
372f1549183Sopenharmony_ci        if (p == NULL) {
373f1549183Sopenharmony_ci            continue;
374f1549183Sopenharmony_ci        }
375f1549183Sopenharmony_ci        struct Node *q = p;
376f1549183Sopenharmony_ci        while (p != NULL && p->context->fd != context->fd) {
377f1549183Sopenharmony_ci            q = p;
378f1549183Sopenharmony_ci            p = p->next;
379f1549183Sopenharmony_ci        }
380f1549183Sopenharmony_ci        if (p != NULL) {
381f1549183Sopenharmony_ci            if (p == server->eventNode[i].head) {
382f1549183Sopenharmony_ci                server->eventNode[i].head = p->next;
383f1549183Sopenharmony_ci            } else {
384f1549183Sopenharmony_ci                q->next = p->next;
385f1549183Sopenharmony_ci            }
386f1549183Sopenharmony_ci            free(p);
387f1549183Sopenharmony_ci            p = NULL;
388f1549183Sopenharmony_ci        }
389f1549183Sopenharmony_ci    }
390f1549183Sopenharmony_ci    return 0;
391f1549183Sopenharmony_ci}
392