Migrate gcd task queue implementation to TaskQueueBase interface

Bug: webrtc:10191
Change-Id: If15138f97445484668d3e42f3a35875521c38545
Reviewed-on: https://webrtc-review.googlesource.com/c/122501
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26782}
diff --git a/api/task_queue/task_queue_base.cc b/api/task_queue/task_queue_base.cc
index 409eb49..7d3539a 100644
--- a/api/task_queue/task_queue_base.cc
+++ b/api/task_queue/task_queue_base.cc
@@ -10,6 +10,10 @@
 #include "api/task_queue/task_queue_base.h"
 
 #include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "rtc_base/checks.h"
+
+#if defined(ABSL_HAVE_THREAD_LOCAL)
 
 namespace webrtc {
 namespace {
@@ -31,5 +35,45 @@
 TaskQueueBase::CurrentTaskQueueSetter::~CurrentTaskQueueSetter() {
   current = previous_;
 }
+}  // namespace webrtc
+
+#elif defined(WEBRTC_POSIX)
+
+#include <pthread.h>
+
+namespace webrtc {
+namespace {
+
+ABSL_CONST_INIT pthread_key_t g_queue_ptr_tls = 0;
+
+void InitializeTls() {
+  RTC_CHECK(pthread_key_create(&g_queue_ptr_tls, nullptr) == 0);
+}
+
+pthread_key_t GetQueuePtrTls() {
+  static pthread_once_t init_once = PTHREAD_ONCE_INIT;
+  RTC_CHECK(pthread_once(&init_once, &InitializeTls) == 0);
+  return g_queue_ptr_tls;
+}
+
+}  // namespace
+
+TaskQueueBase* TaskQueueBase::Current() {
+  return static_cast<TaskQueueBase*>(pthread_getspecific(GetQueuePtrTls()));
+}
+
+TaskQueueBase::CurrentTaskQueueSetter::CurrentTaskQueueSetter(
+    TaskQueueBase* task_queue)
+    : previous_(TaskQueueBase::Current()) {
+  pthread_setspecific(GetQueuePtrTls(), task_queue);
+}
+
+TaskQueueBase::CurrentTaskQueueSetter::~CurrentTaskQueueSetter() {
+  pthread_setspecific(GetQueuePtrTls(), previous_);
+}
 
 }  // namespace webrtc
+
+#else
+#error Unsupported platform
+#endif