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 "hgm_log.h"
17 #include "hgm_task_handle_thread.h"
18 #include "xcollie/watchdog.h"
19 #include <unistd.h>
20 
21 namespace OHOS::Rosen {
22 namespace {
23 constexpr uint32_t WATCHDOG_TIMEVAL = 5000;
24 }
25 
Instance()26 HgmTaskHandleThread& HgmTaskHandleThread::Instance()
27 {
28     static HgmTaskHandleThread instance;
29     return instance;
30 }
31 
HgmTaskHandleThread()32 HgmTaskHandleThread::HgmTaskHandleThread() : runner_(AppExecFwk::EventRunner::Create("HgmTaskHandleThread"))
33 {
34     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
35     int ret = HiviewDFX::Watchdog::GetInstance().AddThread("HgmTaskHandle", handler_, WATCHDOG_TIMEVAL);
36     if (ret != 0) {
37         HGM_LOGW("Add watchdog thread failed");
38     }
39 }
40 
CreateHandler()41 std::shared_ptr<AppExecFwk::EventHandler> HgmTaskHandleThread::CreateHandler()
42 {
43     return std::make_shared<AppExecFwk::EventHandler>(runner_);
44 }
45 
PostTask(const std::function<void ()> & task,int64_t delayTime)46 void HgmTaskHandleThread::PostTask(const std::function<void()>& task, int64_t delayTime)
47 {
48     if (handler_) {
49         handler_->PostTask(task, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
50     }
51 }
52 
PostSyncTask(const std::function<void ()> & task)53 bool HgmTaskHandleThread::PostSyncTask(const std::function<void()>& task)
54 {
55     if (handler_) {
56         return handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
57     }
58     return false;
59 }
60 
PostEvent(std::string eventId,const std::function<void ()> & task,int64_t delayTime)61 void HgmTaskHandleThread::PostEvent(std::string eventId, const std::function<void()>& task, int64_t delayTime)
62 {
63     if (handler_) {
64         handler_->PostTask(task, eventId, delayTime);
65     }
66 }
67 
RemoveEvent(std::string eventId)68 void HgmTaskHandleThread::RemoveEvent(std::string eventId)
69 {
70     if (handler_) {
71         handler_->RemoveTask(eventId);
72     }
73 }
74 
DetectMultiThreadingCalls()75 void HgmTaskHandleThread::DetectMultiThreadingCalls()
76 {
77     if (auto newTid = gettid(); curThreadId_ != newTid) {
78         // -1 means default curThreadId
79         if (curThreadId_ != -1) {
80             HGM_LOGE("Concurrent access tid1: %{public}d tid2: %{public}d", curThreadId_, newTid);
81         }
82         curThreadId_ = newTid;
83     }
84 }
85 }
86