/Users/deen/code/yugabyte-db/src/yb/util/background_task.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #include "yb/util/background_task.h" |
15 | | |
16 | | #include "yb/util/status.h" |
17 | | #include "yb/util/status_log.h" |
18 | | #include "yb/util/thread.h" |
19 | | |
20 | | namespace yb { |
21 | | |
22 | | BackgroundTask::BackgroundTask( |
23 | | std::function<void()> task, std::string category, const std::string& name, |
24 | | std::chrono::milliseconds interval_msec) |
25 | | : task_(std::move(task)), |
26 | | category_(category), |
27 | | name_(std::move(name)), |
28 | 11.4k | interval_(interval_msec) {} |
29 | | |
30 | 191 | BackgroundTask::~BackgroundTask() { |
31 | 191 | } |
32 | | |
33 | 11.1k | Status BackgroundTask::Init() { |
34 | 11.1k | RETURN_NOT_OK(Thread::Create(category_, name_, &BackgroundTask::Run, this, &thread_)); |
35 | 11.1k | return Status::OK(); |
36 | 11.1k | } |
37 | | |
38 | | // Wait for pending tasks and shut down |
39 | 184 | void BackgroundTask::Shutdown() { |
40 | 184 | { |
41 | 184 | std::unique_lock<std::mutex> lock(mutex_); |
42 | 184 | if (closing_) { |
43 | 0 | VLOG(2) << "BackgroundTask already shut down"; |
44 | 0 | return; |
45 | 0 | } |
46 | 184 | closing_ = true; |
47 | 184 | } |
48 | 184 | cond_.notify_one(); |
49 | 184 | CHECK_OK(ThreadJoiner(thread_.get()).Join()); |
50 | 184 | } |
51 | | |
52 | 54.3k | Status BackgroundTask::Wake() { |
53 | 54.3k | { |
54 | 54.3k | std::lock_guard<std::mutex> lock(mutex_); |
55 | 54.3k | if (closing_) { |
56 | 0 | return STATUS(ShutdownInProgress, "Task is shutting down."); |
57 | 0 | } |
58 | 54.3k | have_job_ = true; |
59 | 54.3k | } |
60 | 54.3k | cond_.notify_one(); |
61 | 54.3k | return Status::OK(); |
62 | 54.3k | } |
63 | | |
64 | 11.1k | void BackgroundTask::Run() { |
65 | 13.3k | while (WaitForJob()) { |
66 | 2.21k | task_(); |
67 | 2.21k | } |
68 | 10.9k | VLOG(1) << "BackgroundTask thread shutting down"; |
69 | 11.1k | } |
70 | | |
71 | 13.3k | bool BackgroundTask::WaitForJob() { |
72 | 13.3k | std::unique_lock<std::mutex> lock(mutex_); |
73 | 26.6k | while(true) { |
74 | 15.7k | if (closing_) { |
75 | 184 | return false; |
76 | 184 | } |
77 | 15.5k | if (have_job_) { |
78 | 2.21k | have_job_ = false; |
79 | 2.21k | return true; |
80 | 2.21k | } |
81 | | |
82 | | // Wait |
83 | 13.3k | if (interval_ != std::chrono::milliseconds::zero()) { |
84 | 1.05k | cond_.wait_for(lock, interval_); |
85 | | // If we wake here from the interval_ timeout, then we should behave as if we have a job. If |
86 | | // we wake from an explicit notify from a Wake() call, we should still behave as if we have |
87 | | // a job. |
88 | 1.05k | have_job_ = true; |
89 | 12.2k | } else { |
90 | 12.2k | cond_.wait(lock); |
91 | 12.2k | } |
92 | 13.3k | } |
93 | 13.3k | } |
94 | | |
95 | | } // namespace yb |