• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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