1 // Copyright 2013 The Flutter Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef FLUTTER_FML_THREAD_LOCAL_H_ 6 #define FLUTTER_FML_THREAD_LOCAL_H_ 7 8 #include <memory> 9 10 #include "flutter/fml/build_config.h" 11 #include "flutter/fml/macros.h" 12 13 #define FML_THREAD_LOCAL_PTHREADS OS_MACOSX || OS_LINUX || OS_ANDROID 14 15 #if FML_THREAD_LOCAL_PTHREADS 16 #include <pthread.h> 17 #endif 18 19 namespace fml { 20 21 #if FML_THREAD_LOCAL_PTHREADS 22 23 #define FML_THREAD_LOCAL static 24 25 namespace internal { 26 27 class ThreadLocalPointer { 28 public: 29 ThreadLocalPointer(void (*destroy)(void*)); 30 ~ThreadLocalPointer(); 31 32 void* get() const; 33 void* swap(void* ptr); 34 35 private: 36 pthread_key_t key_; 37 38 FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer); 39 }; 40 41 } // namespace internal 42 43 template <typename T> 44 class ThreadLocalUniquePtr { 45 public: ThreadLocalUniquePtr()46 ThreadLocalUniquePtr() : ptr_(destroy) {} 47 get()48 T* get() const { return reinterpret_cast<T*>(ptr_.get()); } reset(T * ptr)49 void reset(T* ptr) { destroy(ptr_.swap(ptr)); } 50 51 private: destroy(void * ptr)52 static void destroy(void* ptr) { delete reinterpret_cast<T*>(ptr); } 53 54 internal::ThreadLocalPointer ptr_; 55 56 FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocalUniquePtr); 57 }; 58 59 #else // FML_THREAD_LOCAL_PTHREADS 60 61 #define FML_THREAD_LOCAL static thread_local 62 63 template <typename T> 64 class ThreadLocalUniquePtr { 65 public: 66 ThreadLocalUniquePtr() = default; 67 68 T* get() const { return ptr_.get(); } 69 void reset(T* ptr) { ptr_.reset(ptr); } 70 71 private: 72 std::unique_ptr<T> ptr_; 73 74 FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocalUniquePtr); 75 }; 76 77 #endif // FML_THREAD_LOCAL_PTHREADS 78 79 #ifndef FML_THREAD_LOCAL 80 81 #error Thread local storage unavailable on the platform. 82 83 #endif // FML_THREAD_LOCAL 84 85 } // namespace fml 86 87 #endif // FLUTTER_FML_THREAD_LOCAL_H_ 88