1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
18 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
19 
20 #include <functional>
21 #include <thread>
22 
23 #include "perfetto/ext/base/unix_task_runner.h"
24 
25 namespace perfetto {
26 namespace base {
27 
28 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
29 // joins the thread upon destruction. Can be moved to transfer ownership.
30 //
31 // Guarantees that:
32 // * the UnixTaskRunner will be constructed and destructed on the task thread.
33 // * the task thread will live for the lifetime of the UnixTaskRunner.
34 //
35 class PERFETTO_EXPORT ThreadTaskRunner : public TaskRunner {
36  public:
37   static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
38     return ThreadTaskRunner(name);
39   }
40 
41   ThreadTaskRunner(const ThreadTaskRunner&) = delete;
42   ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
43 
44   ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
45   ThreadTaskRunner& operator=(ThreadTaskRunner&&);
46   ~ThreadTaskRunner() override;
47 
48   // Executes the given function on the task runner thread and blocks the caller
49   // thread until the function has run.
50   void PostTaskAndWaitForTesting(std::function<void()>);
51 
52   // Can be called from another thread to get the CPU time of the thread the
53   // task-runner is executing on.
54   uint64_t GetThreadCPUTimeNsForTesting();
55 
56   // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
57   // this ThreadTaskRunner object (unless this object is moved-from, in which
58   // case the pointer remains valid for the lifetime of the new owning
59   // ThreadTaskRunner).
60   //
61   // Warning: do not call Quit() on the returned runner pointer, the termination
62   // should be handled exclusively by this class' destructor.
get()63   UnixTaskRunner* get() const { return task_runner_; }
64 
65   // TaskRunner implementation.
66   // These methods just proxy to the underlying task_runner_.
67   void PostTask(std::function<void()>) override;
68   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
69   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
70   void RemoveFileDescriptorWatch(PlatformHandle) override;
71   bool RunsTasksOnCurrentThread() const override;
72 
73  private:
74   explicit ThreadTaskRunner(const std::string& name);
75   void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
76 
77   std::thread thread_;
78   std::string name_;
79   UnixTaskRunner* task_runner_ = nullptr;
80 };
81 
82 }  // namespace base
83 }  // namespace perfetto
84 
85 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
86