• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "timeout_timer.h"
17 #include <chrono>
18 #include <condition_variable>
19 #include <cstdio>
20 #include <cstring>
21 #include <sys/time.h>
22 #include "common/media_log.h"
23 namespace OHOS {
24 namespace Sharing {
25 
26 #define TIMER_TIMEOUT 2
TimeoutTimer(std::string info)27 TimeoutTimer::TimeoutTimer(std::string info)
28 {
29     SHARING_LOGD("trace.");
30     thread_ = std::make_unique<std::thread>(&TimeoutTimer::MainLoop, this);
31     pthread_setname_np(thread_->native_handle(), info.c_str());
32 }
33 
~TimeoutTimer()34 TimeoutTimer::~TimeoutTimer()
35 {
36     SHARING_LOGD("dtor in %{public}d.", state_);
37     {
38         std::unique_lock<std::mutex> taskLock(taskMutex_);
39         if (state_ == State::WAITING) {
40             state_ = State::EXITED;
41             taskSignal_.notify_all();
42         } else if (state_ == State::WORKING) {
43             state_ = State::EXITED;
44             cancelSignal_.notify_all();
45         } else {
46             state_ = State::EXITED;
47         }
48     }
49 
50     SHARING_LOGD("thread join %{public}d.", state_);
51     if (thread_->joinable()) {
52         thread_->join();
53     }
54     SHARING_LOGD("dtor out %{public}d.", state_);
55 }
56 
StartTimer(int timeout,std::string info,std::function<void ()> callback,bool reuse)57 void TimeoutTimer::StartTimer(int timeout, std::string info, std::function<void()> callback, bool reuse)
58 {
59     SHARING_LOGD("add timeout timer (%{public}s).", info.c_str());
60     std::lock_guard<std::mutex> lock(taskMutex_);
61     reuse_ = reuse;
62     timeout_ = timeout;
63     if (state_ == State::WORKING) {
64         SHARING_LOGD("cancel timeout timer (%{public}s).", taskName_.c_str());
65         state_ = State::CANCELLED;
66         cancelSignal_.notify_all();
67 
68         std::unique_lock<std::mutex> waitLock(waitMutex_);
69         waitSignal_.wait_for(waitLock, std::chrono::milliseconds(TIMER_TIMEOUT));
70     }
71     taskName_ = std::move(info);
72     if (callback) {
73         callback_ = std::move(callback);
74     }
75     taskSignal_.notify_all();
76     SHARING_LOGD("start timeout timer (%{public}s) leave.", info.c_str());
77 }
78 
StopTimer()79 void TimeoutTimer::StopTimer()
80 {
81     SHARING_LOGD("cancel timeout timer (%{public}s).", taskName_.c_str());
82     std::lock_guard<std::mutex> lock(taskMutex_);
83 
84     if (state_ == State::WORKING) {
85         state_ = State::CANCELLED;
86         cancelSignal_.notify_all();
87         std::unique_lock<std::mutex> waitLock(waitMutex_);
88         waitSignal_.wait_for(waitLock, std::chrono::milliseconds(TIMER_TIMEOUT));
89     }
90     SHARING_LOGD("cancel timeout timer (%{public}s) leave.", taskName_.c_str());
91 }
92 
MainLoop()93 void TimeoutTimer::MainLoop()
94 {
95     SHARING_LOGD("trace.");
96     while (state_ != State::EXITED) {
97         std::unique_lock<std::mutex> taskLock(taskMutex_);
98         if (state_ == State::EXITED) {
99             break;
100         }
101 
102         state_ = State::WAITING;
103         waitSignal_.notify_all();
104         if (!reuse_) {
105             taskSignal_.wait(taskLock);
106         }
107 
108         if (state_ == State::EXITED) {
109             break;
110         }
111 
112         state_ = State::WORKING;
113         SHARING_LOGI("start timeout timer(%{public}s).", taskName_.c_str());
114         cancelSignal_.wait_for(taskLock, std::chrono::seconds(timeout_));
115         if (state_ == State::WORKING && callback_) {
116             SHARING_LOGI("invoke timeout timer(%{public}s) callback.", taskName_.c_str());
117             callback_();
118         }
119         SHARING_LOGI("end timeout timer(%{public}s).", taskName_.c_str());
120     }
121     SHARING_LOGD("exit.");
122 }
123 
SetTimeoutCallback(std::function<void ()> callback)124 void TimeoutTimer::SetTimeoutCallback(std::function<void()> callback)
125 {
126     callback_ = std::move(callback);
127 }
128 } // namespace Sharing
129 } // namespace OHOS