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 11 #ifndef RTC_BASE_PLATFORM_THREAD_H_ 12 #define RTC_BASE_PLATFORM_THREAD_H_ 13 14 #include <functional> 15 #include <string> 16 17 #include "absl/strings/string_view.h" 18 #include "absl/types/optional.h" 19 #include "rtc_base/platform_thread_types.h" 20 21 namespace rtc { 22 23 enum class ThreadPriority { 24 kLow = 1, 25 kNormal, 26 kHigh, 27 kRealtime, 28 }; 29 30 struct ThreadAttributes { 31 ThreadPriority priority = ThreadPriority::kNormal; SetPriorityThreadAttributes32 ThreadAttributes& SetPriority(ThreadPriority priority_param) { 33 priority = priority_param; 34 return *this; 35 } 36 }; 37 38 // Represents a simple worker thread. 39 class PlatformThread final { 40 public: 41 // 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 53 // Moves `rhs` into this, storing an empty state in `rhs`. 54 // TODO(bugs.webrtc.org/12727) Look into if default and move support can be 55 // removed. 56 PlatformThread(PlatformThread&& rhs); 57 58 // Copies won't work since we'd have problems with joinable threads. 59 PlatformThread(const PlatformThread&) = delete; 60 PlatformThread& operator=(const PlatformThread&) = delete; 61 62 // Moves `rhs` into this, storing an empty state in `rhs`. 63 // 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. 70 virtual ~PlatformThread(); 71 72 // 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(); 78 79 // Returns true if default constructed, moved from, or Finalize()ed. empty()80 bool empty() const { return !handle_.has_value(); } 81 82 // 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()); 88 89 // 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()); 95 96 // Returns the base platform thread handle of this thread. 97 absl::optional<Handle> GetHandle() const; 98 99 #if defined(WEBRTC_WIN) 100 // Queue a Windows APC function that runs when the thread is alertable. 101 bool QueueAPC(PAPCFUNC apc_function, ULONG_PTR data); 102 #endif 103 104 private: 105 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; 113 }; 114 115 } // namespace rtc 116 117 #endif // RTC_BASE_PLATFORM_THREAD_H_ 118