1/* 2 * Copyright (c) 2023 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 "le_idle.h" 17 18#include <stdio.h> 19#include <sys/timerfd.h> 20#include <unistd.h> 21 22#include "le_loop.h" 23#include "le_task.h" 24#include "loop_event.h" 25 26/** 27 * @brief Add a new idle handler 28 * 29 * @param loopHandle the running loop this idle will be attached 30 * @param idle optional output parameter for the created idle handler 31 * @param processIdle the idle handler function 32 * @param context optional idle handler context 33 * @param repeat if the idle function will be repeated forevent (non zero) or once (zero) 34 * @return status code, 0 means succeed 35 */ 36LE_STATUS LE_AddIdle(const LoopHandle loopHandle, IdleHandle *idle, 37 LE_ProcessIdle processIdle, void *context, int repeat) 38{ 39 LE_CHECK(loopHandle != NULL && processIdle != NULL, return LE_INVALID_PARAM, "Invalid parameters"); 40 IdleTask *task = (IdleTask *)calloc(1, sizeof(IdleTask)); 41 LE_CHECK(task != NULL, 42 return LE_NO_MEMORY, "Failed to create task"); 43 44 task->loop = (EventLoop *)loopHandle; 45 task->processIdle = processIdle; 46 task->context = context; 47 task->repeat = repeat; 48 if (idle != NULL) { 49 *idle = (IdleHandle)task; 50 } 51 52 // Add to list 53 OH_ListAddTail(&(task->loop->idleList), &(task->node)); 54 return LE_SUCCESS; 55} 56 57/** 58 * @brief Delete an idle handler 59 * 60 * @param idle idle handler 61 * @return None 62 */ 63void LE_DelIdle(IdleHandle idle) 64{ 65 LE_CHECK(idle != NULL, return, "Invalid parameters"); 66 IdleTask *task = (IdleTask *)idle; 67 OH_ListRemove(&(task->node)); 68 free((void *)task); 69} 70 71/** 72 * @brief Execute an function once in the next loop 73 * 74 * @param loopHandle the running loop this idle will be attached 75 * @param idle the function to be executed 76 * @param context optional idle handler context 77 * @return status code, 0 means succeed 78 */ 79int LE_DelayProc(const LoopHandle loopHandle, LE_ProcessIdle idle, void *context) 80{ 81 return LE_AddIdle(loopHandle, NULL, idle, context, 0); 82} 83 84static int IdleListTraversalProc(ListNode *node, void *data) 85{ 86 IdleTask *task = (IdleTask *)node; 87 88 // Do idle proc 89 task->processIdle(task, task->context); 90 91 if (task->repeat) { 92 return 0; 93 } 94 95 // Remove if no need to repeat 96 LE_DelIdle((IdleHandle)task); 97 return 0; 98} 99 100/** 101 * @brief Execute all idle functions 102 * 103 * @param loopHandle the running loop 104 * @return None 105 */ 106void LE_RunIdle(const LoopHandle loopHandle) 107{ 108 if (loopHandle == NULL) { 109 return; 110 } 111 EventLoop *loop = (EventLoop *)loopHandle; 112 113 OH_ListTraversal(&(loop->idleList), NULL, IdleListTraversalProc, 0); 114} 115