Tommi | bebc690 | 2015-05-18 07:51:42 | [diff] [blame] | 1 | /* |
| 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 Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 11 | #ifndef RTC_BASE_PLATFORM_THREAD_H_ |
| 12 | #define RTC_BASE_PLATFORM_THREAD_H_ |
Tommi | bebc690 | 2015-05-18 07:51:42 | [diff] [blame] | 13 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 14 | #include <functional> |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 15 | #include <string> |
Hans Wennborg | 1ee02d4 | 2023-03-13 12:04:09 | [diff] [blame] | 16 | #if !defined(WEBRTC_WIN) |
| 17 | #include <pthread.h> |
| 18 | #endif |
pbos | 12411ef | 2015-11-23 22:47:56 | [diff] [blame] | 19 | |
Danil Chapovalov | 5a1a6db | 2019-01-17 18:55:46 | [diff] [blame] | 20 | #include "absl/strings/string_view.h" |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 21 | #include "absl/types/optional.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 22 | #include "rtc_base/platform_thread_types.h" |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 23 | |
| 24 | namespace rtc { |
| 25 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 26 | enum class ThreadPriority { |
| 27 | kLow = 1, |
| 28 | kNormal, |
| 29 | kHigh, |
| 30 | kRealtime, |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 31 | }; |
| 32 | |
Markus Handell | 97c4458 | 2021-04-20 15:41:54 | [diff] [blame] | 33 | struct ThreadAttributes { |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 34 | ThreadPriority priority = ThreadPriority::kNormal; |
Markus Handell | 97c4458 | 2021-04-20 15:41:54 | [diff] [blame] | 35 | ThreadAttributes& SetPriority(ThreadPriority priority_param) { |
| 36 | priority = priority_param; |
| 37 | return *this; |
| 38 | } |
Markus Handell | 97c4458 | 2021-04-20 15:41:54 | [diff] [blame] | 39 | }; |
| 40 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 41 | // Represents a simple worker thread. |
| 42 | class PlatformThread final { |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 43 | public: |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 44 | // Handle is the base platform thread handle. |
| 45 | #if defined(WEBRTC_WIN) |
| 46 | using Handle = HANDLE; |
| 47 | #else |
| 48 | using Handle = pthread_t; |
| 49 | #endif // defined(WEBRTC_WIN) |
| 50 | // This ctor creates the PlatformThread with an unset handle (returning true |
| 51 | // in empty()) and is provided for convenience. |
| 52 | // TODO(bugs.webrtc.org/12727) Look into if default and move support can be |
| 53 | // removed. |
| 54 | PlatformThread() = default; |
| 55 | |
Artem Titov | 96e3b99 | 2021-07-26 14:03:14 | [diff] [blame] | 56 | // Moves `rhs` into this, storing an empty state in `rhs`. |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 57 | // TODO(bugs.webrtc.org/12727) Look into if default and move support can be |
| 58 | // removed. |
| 59 | PlatformThread(PlatformThread&& rhs); |
| 60 | |
Tommi | 145fdbf | 2022-04-08 10:41:25 | [diff] [blame] | 61 | // Copies won't work since we'd have problems with joinable threads. |
| 62 | PlatformThread(const PlatformThread&) = delete; |
| 63 | PlatformThread& operator=(const PlatformThread&) = delete; |
| 64 | |
Artem Titov | 96e3b99 | 2021-07-26 14:03:14 | [diff] [blame] | 65 | // Moves `rhs` into this, storing an empty state in `rhs`. |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 66 | // TODO(bugs.webrtc.org/12727) Look into if default and move support can be |
| 67 | // removed. |
| 68 | PlatformThread& operator=(PlatformThread&& rhs); |
| 69 | |
| 70 | // For a PlatformThread that's been spawned joinable, the destructor suspends |
| 71 | // the calling thread until the created thread exits unless the thread has |
| 72 | // already exited. |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 73 | virtual ~PlatformThread(); |
| 74 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 75 | // Finalizes any allocated resources. |
| 76 | // For a PlatformThread that's been spawned joinable, Finalize() suspends |
| 77 | // the calling thread until the created thread exits unless the thread has |
| 78 | // already exited. |
| 79 | // empty() returns true after completion. |
| 80 | void Finalize(); |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 81 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 82 | // Returns true if default constructed, moved from, or Finalize()ed. |
| 83 | bool empty() const { return !handle_.has_value(); } |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 84 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 85 | // Creates a started joinable thread which will be joined when the returned |
| 86 | // PlatformThread destructs or Finalize() is called. |
| 87 | static PlatformThread SpawnJoinable( |
| 88 | std::function<void()> thread_function, |
| 89 | absl::string_view name, |
| 90 | ThreadAttributes attributes = ThreadAttributes()); |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 91 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 92 | // Creates a started detached thread. The caller has to use external |
| 93 | // synchronization as nothing is provided by the PlatformThread construct. |
| 94 | static PlatformThread SpawnDetached( |
| 95 | std::function<void()> thread_function, |
| 96 | absl::string_view name, |
| 97 | ThreadAttributes attributes = ThreadAttributes()); |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 98 | |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 99 | // Returns the base platform thread handle of this thread. |
| 100 | absl::optional<Handle> GetHandle() const; |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 101 | |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 102 | #if defined(WEBRTC_WIN) |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 103 | // Queue a Windows APC function that runs when the thread is alertable. |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 104 | bool QueueAPC(PAPCFUNC apc_function, ULONG_PTR data); |
| 105 | #endif |
| 106 | |
| 107 | private: |
Markus Handell | ad5037b | 2021-05-07 13:02:36 | [diff] [blame] | 108 | PlatformThread(Handle handle, bool joinable); |
| 109 | static PlatformThread SpawnThread(std::function<void()> thread_function, |
| 110 | absl::string_view name, |
| 111 | ThreadAttributes attributes, |
| 112 | bool joinable); |
| 113 | |
| 114 | absl::optional<Handle> handle_; |
| 115 | bool joinable_ = false; |
Henrik Kjellander | ec78f1c | 2017-06-29 05:52:50 | [diff] [blame] | 116 | }; |
| 117 | |
| 118 | } // namespace rtc |
pbos | 12411ef | 2015-11-23 22:47:56 | [diff] [blame] | 119 | |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 120 | #endif // RTC_BASE_PLATFORM_THREAD_H_ |