Main Page
Related Pages
Modules
Namespaces
Namespace List
Namespace Members
All
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Functions
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Variables
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Typedefs
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
r
s
t
u
v
w
y
z
Enumerations
a
b
c
d
e
f
g
h
i
j
l
m
n
o
p
r
s
t
u
v
w
Enumerator
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
r
s
t
u
z
Classes
Class List
Class Hierarchy
Class Members
All
:
[
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
~
Functions
[
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
~
Variables
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Typedefs
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
r
s
t
u
v
w
y
Enumerations
a
b
c
d
e
f
h
i
k
l
m
n
o
p
r
s
t
u
v
w
Enumerator
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
z
Properties
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
r
s
t
u
v
w
Related Functions
:
a
b
c
d
e
f
g
h
i
j
l
m
n
o
p
q
r
s
t
u
v
w
z
Files
File List
File Members
All
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Functions
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
Variables
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Typedefs
_
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
Enumerations
_
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
r
s
t
u
v
w
x
Enumerator
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
r
s
t
u
v
w
x
Macros
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
grpc
src
core
lib
gpr
tls.h
Go to the documentation of this file.
1
/*
2
*
3
* Copyright 2015 gRPC authors.
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*
17
*/
18
19
#ifndef GRPC_CORE_LIB_GPR_TLS_H
20
#define GRPC_CORE_LIB_GPR_TLS_H
21
22
#include <
grpc/support/port_platform.h
>
23
24
#include <type_traits>
25
33
namespace
grpc_core
{
34
35
// This class is never instantiated. It exists to statically ensure that all
36
// TLS usage is compatible with the most restrictive implementation, allowing
37
// developers to write correct code regardless of the platform they develop on.
38
template
<
typename
T>
39
class
TlsTypeConstrainer
{
40
static_assert(
std::is_trivial<T>::value
,
41
"TLS support is limited to trivial types"
);
42
43
public
:
44
using
Type
=
T
;
45
};
46
47
}
// namespace grpc_core
48
49
#if defined(GPR_PTHREAD_TLS)
50
51
#include <pthread.h>
52
53
#include <algorithm>
54
#include <array>
55
#include <cstring>
56
57
namespace
grpc_core
{
58
59
template
<
typename
T>
60
class
PthreadTlsImpl : TlsTypeConstrainer<T> {
61
public
:
62
PthreadTlsImpl(
const
PthreadTlsImpl&) =
delete
;
63
PthreadTlsImpl& operator=(
const
PthreadTlsImpl&) =
delete
;
64
65
// Achtung! This class emulates C++ `thread_local` using pthread keys. Each
66
// instance of this class is a stand in for a C++ `thread_local`. Think of
67
// each `thread_local` as a *global* pthread_key_t and a type tag. An
68
// important consequence of this is that the lifetime of a `pthread_key_t`
69
// is precisely the lifetime of an instance of this class. To understand why
70
// this is, consider the following scenario given a fictional implementation
71
// of this class which creates and destroys its `pthread_key_t` each time
72
// a given block of code runs (all actions take place on a single thread):
73
//
74
// - instance 1 (type tag = T*) is initialized, is assigned `pthread_key_t` 1
75
// - instance 2 (type tag = int) is initialized, is assigned `pthread_key_t` 2
76
// - instances 1 and 2 store and retrieve values; all is well
77
// - instances 1 and 2 are de-initialized; their keys are released to the pool
78
//
79
// - another run commences
80
// - instance 1 receives key 2
81
// - a value is read from instance 1, it observes a value of type int, but
82
// interprets it as T*; undefined behavior, kaboom
83
//
84
// To properly ensure these invariants are upheld the `pthread_key_t` must be
85
// `const`, which means it can only be released in the destructor. This is a
86
// a violation of the style guide, since these objects are always static (see
87
// footnote) but this code is used in sufficiently narrow circumstances to
88
// justify the deviation.
89
//
90
// https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
91
PthreadTlsImpl()
92
: keys_([]() {
93
typename
std::remove_const<decltype(PthreadTlsImpl::keys_)>
::type
94
keys
;
95
for
(pthread_key_t&
key
:
keys
) {
96
if
(0 != pthread_key_create(&
key
,
nullptr
)) abort();
97
}
98
return
keys
;
99
}()) {}
100
PthreadTlsImpl(
T
t) : PthreadTlsImpl() { *
this
=
t
; }
101
~PthreadTlsImpl() {
102
for
(pthread_key_t
key
: keys_) {
103
if
(0 != pthread_key_delete(
key
)) abort();
104
}
105
}
106
107
operator
T
()
const
{
108
T
t
;
109
char
*
dst
=
reinterpret_cast<
char
*
>
(&
t
);
110
for
(pthread_key_t
key
: keys_) {
111
uintptr_t
src =
uintptr_t
(pthread_getspecific(
key
));
112
size_t
remaining =
reinterpret_cast<
char
*
>
(&
t
+ 1) -
dst
;
113
size_t
step
=
std::min
(
sizeof
(src), remaining);
114
memcpy
(
dst
, &src,
step
);
115
dst
+=
step
;
116
}
117
return
t
;
118
}
119
120
T
operator->()
const
{
121
static_assert(
std::is_pointer<T>::value
,
122
"operator-> only usable on pointers"
);
123
return
this->
operator
T
();
124
}
125
126
T
operator=(
T
t) {
127
char
* src =
reinterpret_cast<
char
*
>
(&
t
);
128
for
(pthread_key_t
key
: keys_) {
129
uintptr_t
dst
;
130
size_t
remaining =
reinterpret_cast<
char
*
>
(&
t
+ 1) - src;
131
size_t
step
=
std::min
(
sizeof
(
dst
), remaining);
132
memcpy
(&
dst
, src,
step
);
133
if
(0 != pthread_setspecific(
key
,
reinterpret_cast<
void
*
>
(
dst
))) abort();
134
src +=
step
;
135
}
136
return
t
;
137
}
138
139
private
:
140
const
std::array
<pthread_key_t,
141
(
sizeof
(
T
) +
sizeof
(
void
*) - 1) /
sizeof
(
void
*)>
142
keys_;
143
};
144
145
}
// namespace grpc_core
146
147
#define GPR_THREAD_LOCAL(type) grpc_core::PthreadTlsImpl<type>
148
149
#else
150
151
#define GPR_THREAD_LOCAL(type) \
152
thread_local typename grpc_core::TlsTypeConstrainer<type>::Type
153
154
#endif
155
156
#endif
/* GRPC_CORE_LIB_GPR_TLS_H */
dst
static const char dst[]
Definition:
test-fs-copyfile.c:37
keys
const void * keys
Definition:
abseil-cpp/absl/random/internal/randen.cc:49
grpc_core
Definition:
call_metric_recorder.h:31
array
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern array
Definition:
bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:111
T
#define T(upbtypeconst, upbtype, ctype, default_value)
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
grpc_core::TlsTypeConstrainer
Definition:
tls.h:39
uintptr_t
_W64 unsigned int uintptr_t
Definition:
stdint-msvc2008.h:119
min
#define min(a, b)
Definition:
qsort.h:83
value
const char * value
Definition:
hpack_parser_table.cc:165
key
const char * key
Definition:
hpack_parser_table.cc:164
absl::str_format_internal::LengthMod::t
@ t
step
static int step
Definition:
test-mutexes.c:31
asyncio_get_stats.type
type
Definition:
asyncio_get_stats.py:37
grpc_core::TlsTypeConstrainer::Type
T Type
Definition:
tls.h:44
port_platform.h
grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:39