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
19namespace fml {
20
21#if FML_THREAD_LOCAL_PTHREADS
22
23#define FML_THREAD_LOCAL static
24
25namespace internal {
26
27class 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
43template <typename T>
44class ThreadLocalUniquePtr {
45 public:
46 ThreadLocalUniquePtr() : ptr_(destroy) {}
47
48 T* get() const { return reinterpret_cast<T*>(ptr_.get()); }
49 void reset(T* ptr) { destroy(ptr_.swap(ptr)); }
50
51 private:
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
63template <typename T>
64class 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