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