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 
16 #include "module_init.h"
17 
18 namespace OHOS::Request {
19 static pthread_mutex_t *g_lockArray = nullptr;
20 
21 #ifdef USE_OPENSSL
22 
LockCallback(int mode,int type,char * file,int line)23 void ModuleInit::LockCallback(int mode, int type, char *file, int line)
24 {
25     (void)file;
26     (void)line;
27     if (mode & CRYPTO_LOCK) {
28         pthread_mutex_lock(&(g_lockArray[type]));
29     } else {
30         pthread_mutex_unlock(&(g_lockArray[type]));
31     }
32 }
33 
ThreadIdCallback(void)34 unsigned long ModuleInit::ThreadIdCallback(void)
35 {
36     unsigned long ret = static_cast<unsigned long>(pthread_self());
37     return ret;
38 }
39 
40 using THREAD_ID_CALLBACK = unsigned long (*)(void);
41 using LOCK_CALLBACK = void (*)(int mode, int type, char *file, int line);
InitLocks(void)42 void ModuleInit::InitLocks(void)
43 {
44     THREAD_ID_CALLBACK threadIdCallback;
45     LOCK_CALLBACK lockCallback;
46     threadIdCallback = ModuleInit::ThreadIdCallback;
47     lockCallback = ModuleInit::LockCallback;
48     g_lockArray = reinterpret_cast<pthread_mutex_t *>(OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)));
49     if (g_lockArray == nullptr) {
50         REQUEST_HILOGE("failed to create openssl lock");
51         return;
52     }
53     for (int i = 0; i < CRYPTO_num_locks(); i++) {
54         pthread_mutex_init(&(g_lockArray[i]), nullptr);
55     }
56     CRYPTO_set_id_callback(threadIdCallback);
57     CRYPTO_set_locking_callback(lockCallback);
58 }
59 
KillLocks(void)60 void ModuleInit::KillLocks(void)
61 {
62     int i;
63     CRYPTO_set_locking_callback(NULL);
64     for (i = 0; i < CRYPTO_num_locks(); i++) {
65         pthread_mutex_destroy(&(g_lockArray[i]));
66     }
67     OPENSSL_free(g_lockArray);
68 }
69 #endif
70 
ModuleInit()71 ModuleInit::ModuleInit() noexcept
72 {
73     curl_global_init(CURL_GLOBAL_ALL);
74 #if defined(USE_OPENSSL)
75     InitLocks();
76 #endif
77 }
78 
~ModuleInit()79 ModuleInit::~ModuleInit()
80 {
81 #if defined(USE_OPENSSL)
82     KillLocks();
83 #endif
84     curl_global_cleanup();
85 }
86 
87 static ModuleInit mi;
88 } // namespace OHOS::Request