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