Revert "Refactor the PlatformThread API."
This reverts commit c89fdd716c4c8af608017c76f75bf27e4c3d602e.
Reason for revert: Causes rare compilation error on win-libfuzzer-asan trybot.
See https://ci.chromium.org/p/chromium/builders/try/win-libfuzzer-asan-rel/713745?
Original change's description:
> Refactor the PlatformThread API.
>
> PlatformThread's API is using old style function pointers, causes
> casting, is unintuitive and forces artificial call sequences, and
> is additionally possible to misuse in release mode.
>
> Fix this by an API face lift:
> 1. The class is turned into a handle, which can be empty.
> 2. The only way of getting a non-empty PlatformThread is by calling
> SpawnJoinable or SpawnDetached, clearly conveying the semantics to the
> code reader.
> 3. Handles can be Finalized, which works differently for joinable and
> detached threads:
> a) Handles for detached threads are simply closed where applicable.
> b) Joinable threads are joined before handles are closed.
> 4. The destructor finalizes handles. No explicit call is needed.
>
> Fixed: webrtc:12727
> Change-Id: Id00a0464edf4fc9e552b6a1fbb5d2e1280e88811
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215075
> Commit-Queue: Markus Handell <handellm@webrtc.org>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> Reviewed-by: Tommi <tommi@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#33923}
# Not skipping CQ checks because original CL landed > 1 day ago.
TBR=handellm@webrtc.org
Bug: webrtc:12727
Change-Id: Ic0146be8866f6dd3ad9c364fb8646650b8e07419
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217583
Reviewed-by: Guido Urdaneta <guidou@webrtc.org>
Reviewed-by: Markus Handell <handellm@webrtc.org>
Commit-Queue: Guido Urdaneta <guidou@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33936}
diff --git a/rtc_base/platform_thread.h b/rtc_base/platform_thread.h
index 11ccfae..35c0e27 100644
--- a/rtc_base/platform_thread.h
+++ b/rtc_base/platform_thread.h
@@ -11,101 +11,103 @@
#ifndef RTC_BASE_PLATFORM_THREAD_H_
#define RTC_BASE_PLATFORM_THREAD_H_
-#include <functional>
+#ifndef WEBRTC_WIN
+#include <pthread.h>
+#endif
#include <string>
#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
+#include "api/sequence_checker.h"
+#include "rtc_base/constructor_magic.h"
#include "rtc_base/platform_thread_types.h"
namespace rtc {
-enum class ThreadPriority {
- kLow = 1,
- kNormal,
- kHigh,
- kRealtime,
+// Callback function that the spawned thread will enter once spawned.
+typedef void (*ThreadRunFunction)(void*);
+
+enum ThreadPriority {
+#ifdef WEBRTC_WIN
+ kLowPriority = THREAD_PRIORITY_BELOW_NORMAL,
+ kNormalPriority = THREAD_PRIORITY_NORMAL,
+ kHighPriority = THREAD_PRIORITY_ABOVE_NORMAL,
+ kHighestPriority = THREAD_PRIORITY_HIGHEST,
+ kRealtimePriority = THREAD_PRIORITY_TIME_CRITICAL
+#else
+ kLowPriority = 1,
+ kNormalPriority = 2,
+ kHighPriority = 3,
+ kHighestPriority = 4,
+ kRealtimePriority = 5
+#endif
};
struct ThreadAttributes {
- ThreadPriority priority = ThreadPriority::kNormal;
+ ThreadPriority priority = kNormalPriority;
+ bool joinable = true;
+
ThreadAttributes& SetPriority(ThreadPriority priority_param) {
priority = priority_param;
return *this;
}
+ ThreadAttributes& SetDetached() {
+ joinable = false;
+ return *this;
+ }
};
-// Represents a simple worker thread.
-class PlatformThread final {
+// Represents a simple worker thread. The implementation must be assumed
+// to be single threaded, meaning that all methods of the class, must be
+// called from the same thread, including instantiation.
+class PlatformThread {
public:
- // Handle is the base platform thread handle.
-#if defined(WEBRTC_WIN)
- using Handle = HANDLE;
-#else
- using Handle = pthread_t;
-#endif // defined(WEBRTC_WIN)
- // This ctor creates the PlatformThread with an unset handle (returning true
- // in empty()) and is provided for convenience.
- // TODO(bugs.webrtc.org/12727) Look into if default and move support can be
- // removed.
- PlatformThread() = default;
-
- // Moves |rhs| into this, storing an empty state in |rhs|.
- // TODO(bugs.webrtc.org/12727) Look into if default and move support can be
- // removed.
- PlatformThread(PlatformThread&& rhs);
-
- // Moves |rhs| into this, storing an empty state in |rhs|.
- // TODO(bugs.webrtc.org/12727) Look into if default and move support can be
- // removed.
- PlatformThread& operator=(PlatformThread&& rhs);
-
- // For a PlatformThread that's been spawned joinable, the destructor suspends
- // the calling thread until the created thread exits unless the thread has
- // already exited.
+ PlatformThread(ThreadRunFunction func,
+ void* obj,
+ absl::string_view thread_name,
+ ThreadAttributes attributes = ThreadAttributes());
virtual ~PlatformThread();
- // Finalizes any allocated resources.
- // For a PlatformThread that's been spawned joinable, Finalize() suspends
- // the calling thread until the created thread exits unless the thread has
- // already exited.
- // empty() returns true after completion.
- void Finalize();
+ const std::string& name() const { return name_; }
- // Returns true if default constructed, moved from, or Finalize()ed.
- bool empty() const { return !handle_.has_value(); }
+ // Spawns a thread and tries to set thread priority according to the priority
+ // from when CreateThread was called.
+ // Start can only be called after the constructor or after a call to Stop().
+ void Start();
- // Creates a started joinable thread which will be joined when the returned
- // PlatformThread destructs or Finalize() is called.
- static PlatformThread SpawnJoinable(
- std::function<void()> thread_function,
- absl::string_view name,
- ThreadAttributes attributes = ThreadAttributes());
+ bool IsRunning() const;
- // Creates a started detached thread. The caller has to use external
- // synchronization as nothing is provided by the PlatformThread construct.
- static PlatformThread SpawnDetached(
- std::function<void()> thread_function,
- absl::string_view name,
- ThreadAttributes attributes = ThreadAttributes());
+ // Returns an identifier for the worker thread that can be used to do
+ // thread checks.
+ PlatformThreadRef GetThreadRef() const;
- // Returns the base platform thread handle of this thread.
- absl::optional<Handle> GetHandle() const;
+ // Stop() prepares the PlatformThread for destruction or another call to
+ // Start(). For a PlatformThread that's been created with
+ // ThreadAttributes::joinable true (the default), Stop() suspends the calling
+ // thread until the created thread exits unless the thread has already exited.
+ // Stop() can only be called after calling Start().
+ void Stop();
+ protected:
#if defined(WEBRTC_WIN)
- // Queue a Windows APC function that runs when the thread is alertable.
+ // Exposed to derived classes to allow for special cases specific to Windows.
bool QueueAPC(PAPCFUNC apc_function, ULONG_PTR data);
#endif
private:
- PlatformThread(Handle handle, bool joinable);
- static PlatformThread SpawnThread(std::function<void()> thread_function,
- absl::string_view name,
- ThreadAttributes attributes,
- bool joinable);
-
- absl::optional<Handle> handle_;
- bool joinable_ = false;
+ ThreadRunFunction const run_function_ = nullptr;
+ const ThreadAttributes attributes_;
+ void* const obj_;
+ // TODO(pbos): Make sure call sites use string literals and update to a const
+ // char* instead of a std::string.
+ const std::string name_;
+ webrtc::SequenceChecker thread_checker_;
+#if defined(WEBRTC_WIN)
+ HANDLE thread_ = nullptr;
+ DWORD thread_id_ = 0;
+#else
+ pthread_t thread_ = 0;
+#endif // defined(WEBRTC_WIN)
+ RTC_DISALLOW_COPY_AND_ASSIGN(PlatformThread);
};
} // namespace rtc