1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include "le_loop.h" 17d9f0492fSopenharmony_ci#include "le_epoll.h" 18d9f0492fSopenharmony_ci 19d9f0492fSopenharmony_ci 20d9f0492fSopenharmony_cistatic int TaskNodeCompare(const HashNode *node1, const HashNode *node2) 21d9f0492fSopenharmony_ci{ 22d9f0492fSopenharmony_ci BaseTask *task1 = HASHMAP_ENTRY(node1, BaseTask, hashNode); 23d9f0492fSopenharmony_ci BaseTask *task2 = HASHMAP_ENTRY(node2, BaseTask, hashNode); 24d9f0492fSopenharmony_ci return (int)task1->taskId.fd - (int)task2->taskId.fd; 25d9f0492fSopenharmony_ci} 26d9f0492fSopenharmony_ci 27d9f0492fSopenharmony_cistatic int TaskKeyCompare(const HashNode *node, const void *key) 28d9f0492fSopenharmony_ci{ 29d9f0492fSopenharmony_ci BaseTask *task = HASHMAP_ENTRY(node, BaseTask, hashNode); 30d9f0492fSopenharmony_ci TaskId *taskId = (TaskId *)key; 31d9f0492fSopenharmony_ci return (int)task->taskId.fd - taskId->taskId.fd; 32d9f0492fSopenharmony_ci} 33d9f0492fSopenharmony_ci 34d9f0492fSopenharmony_cistatic int TaskGetNodeHasCode(const HashNode *node) 35d9f0492fSopenharmony_ci{ 36d9f0492fSopenharmony_ci BaseTask *task = HASHMAP_ENTRY(node, BaseTask, hashNode); 37d9f0492fSopenharmony_ci return task->taskId.fd; 38d9f0492fSopenharmony_ci} 39d9f0492fSopenharmony_ci 40d9f0492fSopenharmony_cistatic int TaskGetKeyHasCode(const void *key) 41d9f0492fSopenharmony_ci{ 42d9f0492fSopenharmony_ci TaskId *taskId = (TaskId *)key; 43d9f0492fSopenharmony_ci return taskId->taskId.fd; 44d9f0492fSopenharmony_ci} 45d9f0492fSopenharmony_ci 46d9f0492fSopenharmony_cistatic void TaskNodeFree(const HashNode *node, void *context) 47d9f0492fSopenharmony_ci{ 48d9f0492fSopenharmony_ci BaseTask *task = HASHMAP_ENTRY(node, BaseTask, hashNode); 49d9f0492fSopenharmony_ci CloseTask((const LoopHandle)context, task); 50d9f0492fSopenharmony_ci free(task); 51d9f0492fSopenharmony_ci} 52d9f0492fSopenharmony_ci 53d9f0492fSopenharmony_cistatic LE_STATUS CreateLoop_(EventLoop **loop, uint32_t maxevents, uint32_t timeout) 54d9f0492fSopenharmony_ci{ 55d9f0492fSopenharmony_ci#ifdef LOOP_EVENT_USE_EPOLL 56d9f0492fSopenharmony_ci LE_STATUS ret = CreateEpollLoop(loop, maxevents, timeout); 57d9f0492fSopenharmony_ci LE_CHECK(ret == LE_SUCCESS, return ret, "Failed to create epoll loop"); 58d9f0492fSopenharmony_ci#endif 59d9f0492fSopenharmony_ci (*loop)->maxevents = maxevents; 60d9f0492fSopenharmony_ci (*loop)->timeout = timeout; 61d9f0492fSopenharmony_ci (*loop)->stop = 0; 62d9f0492fSopenharmony_ci LoopMutexInit(&(*loop)->mutex); 63d9f0492fSopenharmony_ci 64d9f0492fSopenharmony_ci OH_ListInit(&((*loop)->idleList)); 65d9f0492fSopenharmony_ci 66d9f0492fSopenharmony_ci HashInfo info = { 67d9f0492fSopenharmony_ci TaskNodeCompare, 68d9f0492fSopenharmony_ci TaskKeyCompare, 69d9f0492fSopenharmony_ci TaskGetNodeHasCode, 70d9f0492fSopenharmony_ci TaskGetKeyHasCode, 71d9f0492fSopenharmony_ci TaskNodeFree, 72d9f0492fSopenharmony_ci 128 73d9f0492fSopenharmony_ci }; 74d9f0492fSopenharmony_ci ret = OH_HashMapCreate(&(*loop)->taskMap, &info); 75d9f0492fSopenharmony_ci LE_CHECK(ret == LE_SUCCESS, return ret, "failed to create hash map loop"); 76d9f0492fSopenharmony_ci OH_ListInit(&((*loop)->timerList)); 77d9f0492fSopenharmony_ci return ret; 78d9f0492fSopenharmony_ci} 79d9f0492fSopenharmony_ci 80d9f0492fSopenharmony_ciLE_STATUS CloseLoop(EventLoop *loop) 81d9f0492fSopenharmony_ci{ 82d9f0492fSopenharmony_ci if (!loop->stop) { 83d9f0492fSopenharmony_ci return LE_SUCCESS; 84d9f0492fSopenharmony_ci } 85d9f0492fSopenharmony_ci OH_HashMapDestory(loop->taskMap, loop); 86d9f0492fSopenharmony_ci if (loop->close) { 87d9f0492fSopenharmony_ci loop->close(loop); 88d9f0492fSopenharmony_ci } 89d9f0492fSopenharmony_ci return LE_SUCCESS; 90d9f0492fSopenharmony_ci} 91d9f0492fSopenharmony_ci 92d9f0492fSopenharmony_ciLE_STATUS ProcessEvent(const EventLoop *loop, int fd, uint32_t oper) 93d9f0492fSopenharmony_ci{ 94d9f0492fSopenharmony_ci BaseTask *task = GetTaskByFd((EventLoop *)loop, fd); 95d9f0492fSopenharmony_ci if (task != NULL) { 96d9f0492fSopenharmony_ci task->handleEvent((LoopHandle)loop, (TaskHandle)task, oper); 97d9f0492fSopenharmony_ci } else { 98d9f0492fSopenharmony_ci loop->delEvent(loop, fd, EVENT_READ | EVENT_WRITE); 99d9f0492fSopenharmony_ci } 100d9f0492fSopenharmony_ci return LE_SUCCESS; 101d9f0492fSopenharmony_ci} 102d9f0492fSopenharmony_ci 103d9f0492fSopenharmony_ciLE_STATUS AddTask(EventLoop *loop, BaseTask *task) 104d9f0492fSopenharmony_ci{ 105d9f0492fSopenharmony_ci LoopMutexLock(&loop->mutex); 106d9f0492fSopenharmony_ci int ret = OH_HashMapAdd(loop->taskMap, &task->hashNode); 107d9f0492fSopenharmony_ci LoopMutexUnlock(&loop->mutex); 108d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST 109d9f0492fSopenharmony_ci return ret; 110d9f0492fSopenharmony_ci#else 111d9f0492fSopenharmony_ci ret = 0; 112d9f0492fSopenharmony_ci return ret; 113d9f0492fSopenharmony_ci#endif 114d9f0492fSopenharmony_ci} 115d9f0492fSopenharmony_ci 116d9f0492fSopenharmony_ciBaseTask *GetTaskByFd(EventLoop *loop, int fd) 117d9f0492fSopenharmony_ci{ 118d9f0492fSopenharmony_ci BaseTask *task = NULL; 119d9f0492fSopenharmony_ci LoopMutexLock(&loop->mutex); 120d9f0492fSopenharmony_ci TaskId id = {0, {fd}}; 121d9f0492fSopenharmony_ci HashNode *node = OH_HashMapGet(loop->taskMap, &id); 122d9f0492fSopenharmony_ci if (node != NULL) { 123d9f0492fSopenharmony_ci task = HASHMAP_ENTRY(node, BaseTask, hashNode); 124d9f0492fSopenharmony_ci } 125d9f0492fSopenharmony_ci LoopMutexUnlock(&loop->mutex); 126d9f0492fSopenharmony_ci return task; 127d9f0492fSopenharmony_ci} 128d9f0492fSopenharmony_ci 129d9f0492fSopenharmony_civoid DelTask(EventLoop *loop, BaseTask *task) 130d9f0492fSopenharmony_ci{ 131d9f0492fSopenharmony_ci loop->delEvent(loop, task->taskId.fd, 132d9f0492fSopenharmony_ci EVENT_READ | EVENT_WRITE | EVENT_ERROR | EVENT_FREE | EVENT_TIMEOUT | EVENT_SIGNAL); 133d9f0492fSopenharmony_ci LoopMutexLock(&loop->mutex); 134d9f0492fSopenharmony_ci OH_HashMapRemove(loop->taskMap, (TaskId *)task); 135d9f0492fSopenharmony_ci LoopMutexUnlock(&loop->mutex); 136d9f0492fSopenharmony_ci return; 137d9f0492fSopenharmony_ci} 138d9f0492fSopenharmony_ci 139d9f0492fSopenharmony_cistatic EventLoop *g_defaultLoop = NULL; 140d9f0492fSopenharmony_ciLoopHandle LE_GetDefaultLoop(void) 141d9f0492fSopenharmony_ci{ 142d9f0492fSopenharmony_ci if (g_defaultLoop == NULL) { 143d9f0492fSopenharmony_ci LE_CreateLoop((LoopHandle *)&g_defaultLoop); 144d9f0492fSopenharmony_ci } 145d9f0492fSopenharmony_ci return (LoopHandle)g_defaultLoop; 146d9f0492fSopenharmony_ci} 147d9f0492fSopenharmony_ci 148d9f0492fSopenharmony_ciLE_STATUS LE_CreateLoop(LoopHandle *handle) 149d9f0492fSopenharmony_ci{ 150d9f0492fSopenharmony_ci EventLoop *loop = NULL; 151d9f0492fSopenharmony_ci LE_STATUS ret = CreateLoop_(&loop, LOOP_MAX_SOCKET, DEFAULT_TIMEOUT); 152d9f0492fSopenharmony_ci *handle = (LoopHandle)loop; 153d9f0492fSopenharmony_ci return ret; 154d9f0492fSopenharmony_ci} 155d9f0492fSopenharmony_ci 156d9f0492fSopenharmony_civoid LE_RunLoop(const LoopHandle handle) 157d9f0492fSopenharmony_ci{ 158d9f0492fSopenharmony_ci LE_CHECK(handle != NULL, return, "Invalid handle"); 159d9f0492fSopenharmony_ci EventLoop *loop = (EventLoop *)handle; 160d9f0492fSopenharmony_ci loop->runLoop(loop); 161d9f0492fSopenharmony_ci} 162d9f0492fSopenharmony_ci 163d9f0492fSopenharmony_civoid LE_CloseLoop(const LoopHandle loopHandle) 164d9f0492fSopenharmony_ci{ 165d9f0492fSopenharmony_ci LE_CHECK(loopHandle != NULL, return, "Invalid handle"); 166d9f0492fSopenharmony_ci CloseLoop((EventLoop *)loopHandle); 167d9f0492fSopenharmony_ci if ((LoopHandle)g_defaultLoop == loopHandle) { 168d9f0492fSopenharmony_ci g_defaultLoop = NULL; 169d9f0492fSopenharmony_ci } 170d9f0492fSopenharmony_ci} 171d9f0492fSopenharmony_ci 172d9f0492fSopenharmony_civoid LE_StopLoop(const LoopHandle handle) 173d9f0492fSopenharmony_ci{ 174d9f0492fSopenharmony_ci LE_CHECK(handle != NULL, return, "Invalid handle"); 175d9f0492fSopenharmony_ci EventLoop *loop = (EventLoop *)handle; 176d9f0492fSopenharmony_ci loop->stop = 1; 177d9f0492fSopenharmony_ci}