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 "loop.h"
17 #include "tm/queue_task.h"
18 #include "util/event_handler_adapter.h"
19 
20 namespace ffrt {
Loop(QueueHandler * handler)21 Loop::Loop(QueueHandler* handler) : handler_(handler) {}
22 
~Loop()23 Loop::~Loop()
24 {
25     Stop();
26     handler_->ClearLoop();
27 }
28 
Run()29 void Loop::Run()
30 {
31     if (this->GetQueueType() == ffrt_queue_eventhandler_interactive) {
32         FFRT_LOGE("main loop no need to run\n");
33         return;
34     }
35 
36     while (!stopFlag_.load()) {
37         auto task = handler_->PickUpTask();
38         if (task) {
39             task->Execute();
40 
41             if (!stopFlag_.load() && poller_.DeterminePollerReady()) {
42                 poller_.PollOnce(0);
43             }
44             continue;
45         }
46 
47         poller_.PollOnce(-1);
48     }
49 }
50 
Stop()51 void Loop::Stop()
52 {
53     if (this->GetQueueType() != ffrt_queue_eventhandler_interactive) {
54         stopFlag_.store(true);
55         WakeUp();
56     }
57 }
58 
WakeUp()59 void Loop::WakeUp()
60 {
61     poller_.WakeUp();
62 }
63 
GetQueueType()64 int Loop::GetQueueType()
65 {
66     return handler_->GetQueue()->GetQueueType();
67 }
68 
EpollCtl(int op,int fd,uint32_t events,void * data,ffrt_poller_cb cb)69 int Loop::EpollCtl(int op, int fd, uint32_t events, void *data, ffrt_poller_cb cb)
70 {
71     if (op == EPOLL_CTL_ADD) {
72         if (this->GetQueueType() == ffrt_queue_eventhandler_interactive) {
73             return EventHandlerAdapter::Instance()->AddFdListener(handler_->GetEventHandler(), fd, events, data, cb);
74         } else {
75             return poller_.AddFdEvent(op, events, fd, data, cb);
76         }
77     } else if (op == EPOLL_CTL_DEL) {
78         if (this->GetQueueType() == ffrt_queue_eventhandler_interactive) {
79             return EventHandlerAdapter::Instance()->RemoveFdListener(handler_->GetEventHandler(), fd);
80         } else {
81             return poller_.DelFdEvent(fd);
82         }
83     } else if (op == EPOLL_CTL_MOD) {
84         FFRT_LOGE("EPOLL_CTL_MOD not supported yet");
85         return -1;
86     } else {
87         FFRT_LOGE("EPOLL_CTL op invalid");
88         return -1;
89     }
90 }
91 
TimerStart(uint64_t timeout,void * data,ffrt_timer_cb cb,bool repeat)92 ffrt_timer_t Loop::TimerStart(uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat)
93 {
94     return poller_.RegisterTimer(timeout, data, cb, repeat);
95 }
96 
TimerStop(ffrt_timer_t handle)97 int Loop::TimerStop(ffrt_timer_t handle)
98 {
99     return poller_.UnregisterTimer(handle);
100 }
101 } // ffrt