/Users/deen/code/yugabyte-db/src/yb/util/threadlocal.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. 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, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | #include "yb/util/threadlocal.h" |
33 | | |
34 | | #include "yb/gutil/once.h" |
35 | | #include "yb/util/errno.h" |
36 | | |
37 | | namespace yb { |
38 | | namespace threadlocal { |
39 | | namespace internal { |
40 | | |
41 | | // One key used by the entire process to attach destructors on thread exit. |
42 | | static pthread_key_t destructors_key; |
43 | | |
44 | | // The above key must only be initialized once per process. |
45 | | static GoogleOnceType once = GOOGLE_ONCE_INIT; |
46 | | |
47 | | // Call all the destructors associated with all THREAD_LOCAL instances in this |
48 | | // thread. |
49 | 928k | static void InvokeDestructors(void* t) { |
50 | 928k | PerThreadDestructorList* d = reinterpret_cast<PerThreadDestructorList*>(t); |
51 | 1.85M | while (d != nullptr) { |
52 | 928k | d->destructor(d->arg); |
53 | 928k | PerThreadDestructorList* next = d->next; |
54 | 928k | delete d; |
55 | 928k | d = next; |
56 | 928k | } |
57 | 928k | } |
58 | | |
59 | | // This key must be initialized only once. |
60 | 24.3k | static void CreateKey() { |
61 | 24.3k | int ret = pthread_key_create(&destructors_key, &InvokeDestructors); |
62 | | // Linux supports up to 1024 keys, we will use only one for all thread locals. |
63 | 24.3k | CHECK_EQ(0, ret) << "pthread_key_create() failed, cannot add destructor to thread: " |
64 | 0 | << "error " << ret << ": " << ErrnoToString(ret); |
65 | 24.3k | } |
66 | | |
67 | | // Adds a destructor to the list. |
68 | 1.63M | void AddDestructor(PerThreadDestructorList* p) { |
69 | 1.63M | GoogleOnceInit(&once, &CreateKey); |
70 | | |
71 | | // Returns NULL if nothing is set yet. |
72 | 1.63M | p->next = reinterpret_cast<PerThreadDestructorList*>(pthread_getspecific(destructors_key)); |
73 | 1.63M | int ret = pthread_setspecific(destructors_key, p); |
74 | | // The only time this check should fail is if we are out of memory, or if |
75 | | // somehow key creation failed, which should be caught by the above CHECK. |
76 | 1.63M | CHECK_EQ(0, ret) << "pthread_setspecific() failed, cannot update destructor list: " |
77 | 0 | << "error " << ret << ": " << ErrnoToString(ret); |
78 | 1.63M | } |
79 | | |
80 | | } // namespace internal |
81 | | } // namespace threadlocal |
82 | | } // namespace yb |