blob: 3ab2761f438fe427e34c5070b377248d30ac2b54 [file] [log] [blame]
Tommibebc6902015-05-18 09:51:42 +02001/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_PLATFORM_THREAD_H_
12#define RTC_BASE_PLATFORM_THREAD_H_
Tommibebc6902015-05-18 09:51:42 +020013
Markus Handellad5037b2021-05-07 15:02:36 +020014#include <functional>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020015#include <string>
pbos12411ef2015-11-23 14:47:56 -080016
Danil Chapovalov5a1a6db2019-01-17 19:55:46 +010017#include "absl/strings/string_view.h"
Markus Handellad5037b2021-05-07 15:02:36 +020018#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "rtc_base/platform_thread_types.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020020
21namespace rtc {
22
Markus Handellad5037b2021-05-07 15:02:36 +020023enum class ThreadPriority {
24 kLow = 1,
25 kNormal,
26 kHigh,
27 kRealtime,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020028};
29
Markus Handell97c44582021-04-20 17:41:54 +020030struct ThreadAttributes {
Markus Handellad5037b2021-05-07 15:02:36 +020031 ThreadPriority priority = ThreadPriority::kNormal;
Markus Handell97c44582021-04-20 17:41:54 +020032 ThreadAttributes& SetPriority(ThreadPriority priority_param) {
33 priority = priority_param;
34 return *this;
35 }
Markus Handell97c44582021-04-20 17:41:54 +020036};
37
Markus Handellad5037b2021-05-07 15:02:36 +020038// Represents a simple worker thread.
39class PlatformThread final {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020040 public:
Markus Handellad5037b2021-05-07 15:02:36 +020041 // Handle is the base platform thread handle.
42#if defined(WEBRTC_WIN)
43 using Handle = HANDLE;
44#else
45 using Handle = pthread_t;
46#endif // defined(WEBRTC_WIN)
47 // This ctor creates the PlatformThread with an unset handle (returning true
48 // in empty()) and is provided for convenience.
49 // TODO(bugs.webrtc.org/12727) Look into if default and move support can be
50 // removed.
51 PlatformThread() = default;
52
Artem Titov96e3b992021-07-26 16:03:14 +020053 // Moves `rhs` into this, storing an empty state in `rhs`.
Markus Handellad5037b2021-05-07 15:02:36 +020054 // TODO(bugs.webrtc.org/12727) Look into if default and move support can be
55 // removed.
56 PlatformThread(PlatformThread&& rhs);
57
Tommi145fdbf2022-04-08 12:41:25 +020058 // Copies won't work since we'd have problems with joinable threads.
59 PlatformThread(const PlatformThread&) = delete;
60 PlatformThread& operator=(const PlatformThread&) = delete;
61
Artem Titov96e3b992021-07-26 16:03:14 +020062 // Moves `rhs` into this, storing an empty state in `rhs`.
Markus Handellad5037b2021-05-07 15:02:36 +020063 // TODO(bugs.webrtc.org/12727) Look into if default and move support can be
64 // removed.
65 PlatformThread& operator=(PlatformThread&& rhs);
66
67 // For a PlatformThread that's been spawned joinable, the destructor suspends
68 // the calling thread until the created thread exits unless the thread has
69 // already exited.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020070 virtual ~PlatformThread();
71
Markus Handellad5037b2021-05-07 15:02:36 +020072 // Finalizes any allocated resources.
73 // For a PlatformThread that's been spawned joinable, Finalize() suspends
74 // the calling thread until the created thread exits unless the thread has
75 // already exited.
76 // empty() returns true after completion.
77 void Finalize();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020078
Markus Handellad5037b2021-05-07 15:02:36 +020079 // Returns true if default constructed, moved from, or Finalize()ed.
80 bool empty() const { return !handle_.has_value(); }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020081
Markus Handellad5037b2021-05-07 15:02:36 +020082 // Creates a started joinable thread which will be joined when the returned
83 // PlatformThread destructs or Finalize() is called.
84 static PlatformThread SpawnJoinable(
85 std::function<void()> thread_function,
86 absl::string_view name,
87 ThreadAttributes attributes = ThreadAttributes());
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020088
Markus Handellad5037b2021-05-07 15:02:36 +020089 // Creates a started detached thread. The caller has to use external
90 // synchronization as nothing is provided by the PlatformThread construct.
91 static PlatformThread SpawnDetached(
92 std::function<void()> thread_function,
93 absl::string_view name,
94 ThreadAttributes attributes = ThreadAttributes());
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020095
Markus Handellad5037b2021-05-07 15:02:36 +020096 // Returns the base platform thread handle of this thread.
97 absl::optional<Handle> GetHandle() const;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020098
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020099#if defined(WEBRTC_WIN)
Markus Handellad5037b2021-05-07 15:02:36 +0200100 // Queue a Windows APC function that runs when the thread is alertable.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200101 bool QueueAPC(PAPCFUNC apc_function, ULONG_PTR data);
102#endif
103
104 private:
Markus Handellad5037b2021-05-07 15:02:36 +0200105 PlatformThread(Handle handle, bool joinable);
106 static PlatformThread SpawnThread(std::function<void()> thread_function,
107 absl::string_view name,
108 ThreadAttributes attributes,
109 bool joinable);
110
111 absl::optional<Handle> handle_;
112 bool joinable_ = false;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200113};
114
115} // namespace rtc
pbos12411ef2015-11-23 14:47:56 -0800116
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200117#endif // RTC_BASE_PLATFORM_THREAD_H_