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#include "le_task.h"
16d9f0492fSopenharmony_ci#include "le_loop.h"
17d9f0492fSopenharmony_ci
18d9f0492fSopenharmony_cistatic void HandleWatcherTaskClose_(const LoopHandle loopHandle, const TaskHandle taskHandle)
19d9f0492fSopenharmony_ci{
20d9f0492fSopenharmony_ci    LE_LOGV("HandleWatcherTaskClose_ fd: %d ", GetSocketFd(taskHandle));
21d9f0492fSopenharmony_ci    DelTask((EventLoop *)loopHandle, (BaseTask *)taskHandle);
22d9f0492fSopenharmony_ci    CloseTask(loopHandle, (BaseTask *)taskHandle);
23d9f0492fSopenharmony_ci}
24d9f0492fSopenharmony_ci
25d9f0492fSopenharmony_cistatic LE_STATUS HandleWatcherEvent_(const LoopHandle loopHandle, const TaskHandle taskHandle, uint32_t oper)
26d9f0492fSopenharmony_ci{
27d9f0492fSopenharmony_ci    LE_LOGV("HandleWatcherEvent_ fd: %d oper 0x%x", GetSocketFd(taskHandle), oper);
28d9f0492fSopenharmony_ci    EventLoop *loop = (EventLoop *)loopHandle;
29d9f0492fSopenharmony_ci    WatcherTask *watcher = (WatcherTask *)taskHandle;
30d9f0492fSopenharmony_ci    int fd = GetSocketFd(taskHandle);
31d9f0492fSopenharmony_ci    uint32_t events = oper;
32d9f0492fSopenharmony_ci    uint64_t userData = *(uint64_t *)LE_GetUserData(taskHandle);
33d9f0492fSopenharmony_ci    if (watcher->processEvent != NULL) {
34d9f0492fSopenharmony_ci        watcher->processEvent(taskHandle, fd, &events, (void *)userData);
35d9f0492fSopenharmony_ci    }
36d9f0492fSopenharmony_ci    watcher = (WatcherTask *)GetTaskByFd((EventLoop *)loopHandle, fd);
37d9f0492fSopenharmony_ci    LE_ONLY_CHECK(watcher != NULL, return 0);
38d9f0492fSopenharmony_ci    if (watcher->base.flags & WATCHER_ONCE) {
39d9f0492fSopenharmony_ci        HandleWatcherTaskClose_((LoopHandle)loop, (TaskHandle)watcher);
40d9f0492fSopenharmony_ci        return 0;
41d9f0492fSopenharmony_ci    }
42d9f0492fSopenharmony_ci    if (events == 0) {
43d9f0492fSopenharmony_ci        HandleWatcherTaskClose_((LoopHandle)loop, (TaskHandle)watcher);
44d9f0492fSopenharmony_ci        return 0;
45d9f0492fSopenharmony_ci    }
46d9f0492fSopenharmony_ci    if (events != watcher->events) {
47d9f0492fSopenharmony_ci        watcher->events = events;
48d9f0492fSopenharmony_ci        loop->modEvent(loop, (const BaseTask *)taskHandle, watcher->events);
49d9f0492fSopenharmony_ci    }
50d9f0492fSopenharmony_ci    return LE_SUCCESS;
51d9f0492fSopenharmony_ci}
52d9f0492fSopenharmony_ci
53d9f0492fSopenharmony_cistatic void DumpWatcherTaskInfo_(const TaskHandle task)
54d9f0492fSopenharmony_ci{
55d9f0492fSopenharmony_ci    INIT_CHECK(task != NULL, return);
56d9f0492fSopenharmony_ci    BaseTask *baseTask = (BaseTask *)task;
57d9f0492fSopenharmony_ci
58d9f0492fSopenharmony_ci    WatcherTask *watcherTask = (WatcherTask *)baseTask;
59d9f0492fSopenharmony_ci    printf("\tfd: %d \n", watcherTask->base.taskId.fd);
60d9f0492fSopenharmony_ci    printf("\t  TaskType: %s \n", "WatcherTask");
61d9f0492fSopenharmony_ci}
62d9f0492fSopenharmony_ci
63d9f0492fSopenharmony_ciLE_STATUS LE_StartWatcher(const LoopHandle loopHandle,
64d9f0492fSopenharmony_ci    WatcherHandle *watcherHandle, const LE_WatchInfo *info, const void *context)
65d9f0492fSopenharmony_ci{
66d9f0492fSopenharmony_ci    LE_CHECK(loopHandle != NULL && watcherHandle != NULL, return LE_INVALID_PARAM, "Invalid parameters");
67d9f0492fSopenharmony_ci    LE_CHECK(info != NULL && info->processEvent != NULL, return LE_INVALID_PARAM, "Invuint64_talid processEvent");
68d9f0492fSopenharmony_ci
69d9f0492fSopenharmony_ci    LE_BaseInfo baseInfo = {TASK_WATCHER | (info->flags & WATCHER_ONCE), info->close, sizeof(uint64_t)};
70d9f0492fSopenharmony_ci    WatcherTask *task = (WatcherTask *)CreateTask(loopHandle, info->fd, &baseInfo, sizeof(WatcherTask));
71d9f0492fSopenharmony_ci    LE_CHECK(task != NULL, return LE_NO_MEMORY, "Failed to create task");
72d9f0492fSopenharmony_ci    task->base.handleEvent = HandleWatcherEvent_;
73d9f0492fSopenharmony_ci    task->base.innerClose = HandleWatcherTaskClose_;
74d9f0492fSopenharmony_ci    task->base.dumpTaskInfo = DumpWatcherTaskInfo_;
75d9f0492fSopenharmony_ci    task->processEvent = info->processEvent;
76d9f0492fSopenharmony_ci    task->events = info->events;
77d9f0492fSopenharmony_ci    *(uint64_t *)(task + 1) = (uint64_t)context;
78d9f0492fSopenharmony_ci
79d9f0492fSopenharmony_ci    EventLoop *loop = (EventLoop *)loopHandle;
80d9f0492fSopenharmony_ci    loop->addEvent(loop, (const BaseTask *)task, info->events);
81d9f0492fSopenharmony_ci    *watcherHandle = (WatcherHandle)task;
82d9f0492fSopenharmony_ci    return LE_SUCCESS;
83d9f0492fSopenharmony_ci}
84d9f0492fSopenharmony_ci
85d9f0492fSopenharmony_civoid LE_RemoveWatcher(const LoopHandle loopHandle, const WatcherHandle watcherHandle)
86d9f0492fSopenharmony_ci{
87d9f0492fSopenharmony_ci    LE_CHECK(loopHandle != NULL && watcherHandle != NULL, return, "Invalid parameters");
88d9f0492fSopenharmony_ci    LE_CloseTask(loopHandle, watcherHandle);
89d9f0492fSopenharmony_ci}