1 /* 2 * Copyright 2019 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 #include "api/task_queue/task_queue_base.h" 11 12 #include "absl/base/attributes.h" 13 #include "absl/base/config.h" 14 #include "absl/functional/any_invocable.h" 15 #include "api/units/time_delta.h" 16 #include "rtc_base/checks.h" 17 18 #if defined(ABSL_HAVE_THREAD_LOCAL) 19 20 namespace webrtc { 21 namespace { 22 23 ABSL_CONST_INIT thread_local TaskQueueBase* current = nullptr; 24 25 } // namespace 26 Current()27TaskQueueBase* TaskQueueBase::Current() { 28 return current; 29 } 30 CurrentTaskQueueSetter(TaskQueueBase * task_queue)31TaskQueueBase::CurrentTaskQueueSetter::CurrentTaskQueueSetter( 32 TaskQueueBase* task_queue) 33 : previous_(current) { 34 current = task_queue; 35 } 36 ~CurrentTaskQueueSetter()37TaskQueueBase::CurrentTaskQueueSetter::~CurrentTaskQueueSetter() { 38 current = previous_; 39 } 40 } // namespace webrtc 41 42 #elif defined(WEBRTC_POSIX) 43 44 #include <pthread.h> 45 46 namespace webrtc { 47 namespace { 48 49 ABSL_CONST_INIT pthread_key_t g_queue_ptr_tls = 0; 50 InitializeTls()51void InitializeTls() { 52 RTC_CHECK(pthread_key_create(&g_queue_ptr_tls, nullptr) == 0); 53 } 54 GetQueuePtrTls()55pthread_key_t GetQueuePtrTls() { 56 static pthread_once_t init_once = PTHREAD_ONCE_INIT; 57 RTC_CHECK(pthread_once(&init_once, &InitializeTls) == 0); 58 return g_queue_ptr_tls; 59 } 60 61 } // namespace 62 Current()63TaskQueueBase* TaskQueueBase::Current() { 64 return static_cast<TaskQueueBase*>(pthread_getspecific(GetQueuePtrTls())); 65 } 66 CurrentTaskQueueSetter(TaskQueueBase * task_queue)67TaskQueueBase::CurrentTaskQueueSetter::CurrentTaskQueueSetter( 68 TaskQueueBase* task_queue) 69 : previous_(TaskQueueBase::Current()) { 70 pthread_setspecific(GetQueuePtrTls(), task_queue); 71 } 72 ~CurrentTaskQueueSetter()73TaskQueueBase::CurrentTaskQueueSetter::~CurrentTaskQueueSetter() { 74 pthread_setspecific(GetQueuePtrTls(), previous_); 75 } 76 77 } // namespace webrtc 78 79 #else 80 #error Unsupported platform 81 #endif 82