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