1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "thread_private_data_ctl.h"
16
17 #include "wrapper_log.h"
18 namespace OHOS {
19 constexpr int32_t PTHREAD_KEY_T_NOT_INITIALIZED = -1;
20 pthread_key_t ThreadPrivateDataCtl::key_ = PTHREAD_KEY_T_NOT_INITIALIZED;
21 pthread_once_t ThreadPrivateDataCtl::onceCtl_ = PTHREAD_ONCE_INIT;
22
KeyInit()23 void ThreadPrivateDataCtl::KeyInit()
24 {
25 if (pthread_key_create(&key_, nullptr) != 0) {
26 WLOGE("Failed to create thread key.");
27 return;
28 }
29 WLOGD("pthread_key_create. key = %{public}d", key_);
30 }
31
ValidateKey()32 void ThreadPrivateDataCtl::ValidateKey()
33 {
34 pthread_once(&onceCtl_, KeyInit);
35 }
36
GetPrivateData()37 ThreadPrivateData* ThreadPrivateDataCtl::GetPrivateData()
38 {
39 ValidateKey();
40 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
41 if (data == nullptr) {
42 data = new ThreadPrivateData;
43 pthread_setspecific(key_, data);
44 }
45 return data;
46 }
47
ClearPrivateData()48 void ThreadPrivateDataCtl::ClearPrivateData()
49 {
50 if (key_ != PTHREAD_KEY_T_NOT_INITIALIZED) {
51 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
52 if (data) {
53 pthread_setspecific(key_, nullptr);
54 delete data;
55 }
56 }
57 }
58
GetError()59 EGLint ThreadPrivateDataCtl::GetError()
60 {
61 if (key_ == PTHREAD_KEY_T_NOT_INITIALIZED) {
62 return EGL_SUCCESS;
63 }
64
65 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
66 if (!data) {
67 return EGL_SUCCESS;
68 }
69
70 EGLint error = data->error;
71 data->error = EGL_SUCCESS;
72
73 return error;
74 }
75
SetError(EGLint error)76 void ThreadPrivateDataCtl::SetError(EGLint error)
77 {
78 ValidateKey();
79 ThreadPrivateData *data = GetPrivateData();
80 if (data->error != error) {
81 WLOGW("ThreadPrivateDataCtl::SetError error = %{public}d.", error);
82 data->error = error;
83 }
84 }
85
SetContext(EGLContext ctx)86 void ThreadPrivateDataCtl::SetContext(EGLContext ctx)
87 {
88 ValidateKey();
89 GetPrivateData()->ctx = ctx;
90 }
91
GetContext()92 EGLContext ThreadPrivateDataCtl::GetContext()
93 {
94 if (key_ == PTHREAD_KEY_T_NOT_INITIALIZED) {
95 return EGL_NO_CONTEXT;
96 }
97
98 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
99 if (!data) {
100 return EGL_NO_CONTEXT;
101 }
102
103 return data->ctx;
104 }
105
SetGlHookTable(GlHookTable * table)106 void ThreadPrivateDataCtl::SetGlHookTable(GlHookTable *table)
107 {
108 ValidateKey();
109 GetPrivateData()->table = table;
110 }
111
GetGlHookTable()112 GlHookTable *ThreadPrivateDataCtl::GetGlHookTable()
113 {
114 if (key_ == PTHREAD_KEY_T_NOT_INITIALIZED) {
115 return nullptr;
116 }
117
118 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
119 if (!data) {
120 return nullptr;
121 }
122
123 return data->table;
124 }
125 } // namespace OHOS
126