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 "EGL/egl_wrapper_entry.h"
18 #include "wrapper_log.h"
19 namespace OHOS {
20 constexpr int32_t PTHREAD_KEY_T_NOT_INITIALIZED = -1;
21 pthread_key_t ThreadPrivateDataCtl::key_ = PTHREAD_KEY_T_NOT_INITIALIZED;
22 pthread_key_t ThreadPrivateDataCtl::tableKey_ = PTHREAD_KEY_T_NOT_INITIALIZED;
23 pthread_once_t ThreadPrivateDataCtl::onceCtl_ = PTHREAD_ONCE_INIT;
24
KeyInit()25 void ThreadPrivateDataCtl::KeyInit()
26 {
27 if (pthread_key_create(&key_, nullptr) != 0) {
28 WLOGE("Failed to create thread key.");
29 return;
30 }
31 if (pthread_key_create(&tableKey_, nullptr) != 0) {
32 WLOGE("Failed to create thread key.");
33 return;
34 }
35 WLOGD("pthread_key_create. key = %{public}d", key_);
36 }
37
ValidateKey()38 void ThreadPrivateDataCtl::ValidateKey()
39 {
40 pthread_once(&onceCtl_, KeyInit);
41 }
42
GetPrivateData()43 ThreadPrivateData* ThreadPrivateDataCtl::GetPrivateData()
44 {
45 ValidateKey();
46 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
47 if (data == nullptr) {
48 data = new ThreadPrivateData;
49 pthread_setspecific(key_, data);
50 }
51 return data;
52 }
53
ClearPrivateData()54 void ThreadPrivateDataCtl::ClearPrivateData()
55 {
56 if (key_ != static_cast<pthread_key_t>(PTHREAD_KEY_T_NOT_INITIALIZED)) {
57 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
58 if (data) {
59 pthread_setspecific(key_, nullptr);
60 delete data;
61 }
62 }
63 if (tableKey_ != static_cast<pthread_key_t>(PTHREAD_KEY_T_NOT_INITIALIZED)) {
64 pthread_setspecific(tableKey_, nullptr);
65 }
66 }
67
68 #ifdef EGL_ERROR_ENABLE
ClearError()69 void ThreadPrivateDataCtl::ClearError()
70 {
71 OHOS::EglGetErrorImpl();
72 }
73 #endif
74
GetError()75 EGLint ThreadPrivateDataCtl::GetError()
76 {
77 if (key_ == static_cast<pthread_key_t>(PTHREAD_KEY_T_NOT_INITIALIZED)) {
78 return EGL_SUCCESS;
79 }
80
81 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
82 if (!data) {
83 return EGL_SUCCESS;
84 }
85
86 EGLint error = data->error;
87 data->error = EGL_SUCCESS;
88
89 return error;
90 }
91
SetError(EGLint error)92 void ThreadPrivateDataCtl::SetError(EGLint error)
93 {
94 ValidateKey();
95 ThreadPrivateData *data = GetPrivateData();
96 if (data->error != error) {
97 WLOGW("ThreadPrivateDataCtl::SetError error = %{public}d.", error);
98 data->error = error;
99 }
100 }
101
SetContext(EGLContext ctx)102 void ThreadPrivateDataCtl::SetContext(EGLContext ctx)
103 {
104 ValidateKey();
105 GetPrivateData()->ctx = ctx;
106 }
107
GetContext()108 EGLContext ThreadPrivateDataCtl::GetContext()
109 {
110 if (key_ == static_cast<pthread_key_t>(PTHREAD_KEY_T_NOT_INITIALIZED)) {
111 return EGL_NO_CONTEXT;
112 }
113
114 ThreadPrivateData *data = static_cast<ThreadPrivateData *>(pthread_getspecific(key_));
115 if (!data) {
116 return EGL_NO_CONTEXT;
117 }
118
119 return data->ctx;
120 }
121
SetGlHookTable(GlHookTable * table)122 void ThreadPrivateDataCtl::SetGlHookTable(GlHookTable *table)
123 {
124 ValidateKey();
125 pthread_setspecific(tableKey_, table);
126 }
127
GetGlHookTable()128 GlHookTable *ThreadPrivateDataCtl::GetGlHookTable()
129 {
130 if (tableKey_ == static_cast<pthread_key_t>(PTHREAD_KEY_T_NOT_INITIALIZED)) {
131 return nullptr;
132 }
133 return static_cast<GlHookTable *>(pthread_getspecific(tableKey_));
134 }
135
136 } // namespace OHOS
137