summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/idevice.c104
1 files changed, 47 insertions, 57 deletions
diff --git a/src/idevice.c b/src/idevice.c
index b14db66..d07b691 100644
--- a/src/idevice.c
+++ b/src/idevice.c
@@ -124,32 +124,32 @@ static void id_function(CRYPTO_THREADID *thread)
124#endif 124#endif
125#endif /* HAVE_OPENSSL */ 125#endif /* HAVE_OPENSSL */
126 126
127static void internal_idevice_init(void) 127// Reference: https://stackoverflow.com/a/2390626/1806760
128{ 128// Initializer/finalizer sample for MSVC and GCC/Clang.
129#if defined(HAVE_OPENSSL) 129// 2010-2016 Joe Lowe. Released into the public domain.
130#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 130
131 int i; 131#ifdef __cplusplus
132 SSL_library_init(); 132 #define INITIALIZER(f) \
133 133 static void f(void); \
134 mutex_buf = malloc(CRYPTO_num_locks() * sizeof(mutex_t)); 134 struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
135 if (!mutex_buf) 135 static void f(void)
136 return; 136#elif defined(_MSC_VER)
137 for (i = 0; i < CRYPTO_num_locks(); i++) 137 #pragma section(".CRT$XCU",read)
138 mutex_init(&mutex_buf[i]); 138 #define INITIALIZER2_(f,p) \
139 139 static void f(void); \
140#if OPENSSL_VERSION_NUMBER < 0x10000000L 140 __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
141 CRYPTO_set_id_callback(id_function); 141 __pragma(comment(linker,"/include:" p #f "_")) \
142 static void f(void)
143 #ifdef _WIN64
144 #define INITIALIZER(f) INITIALIZER2_(f,"")
145 #else
146 #define INITIALIZER(f) INITIALIZER2_(f,"_")
147 #endif
142#else 148#else
143 CRYPTO_THREADID_set_callback(id_function); 149 #define INITIALIZER(f) \
150 static void f(void) __attribute__((__constructor__)); \
151 static void f(void)
144#endif 152#endif
145 CRYPTO_set_locking_callback(locking_function);
146#endif
147#elif defined(HAVE_GNUTLS)
148 gnutls_global_init();
149#elif defined(HAVE_MBEDTLS)
150 // NO-OP
151#endif
152}
153 153
154static void internal_idevice_deinit(void) 154static void internal_idevice_deinit(void)
155{ 155{
@@ -181,43 +181,33 @@ static void internal_idevice_deinit(void)
181#endif 181#endif
182} 182}
183 183
184static thread_once_t init_once = THREAD_ONCE_INIT; 184INITIALIZER(internal_idevice_init)
185static thread_once_t deinit_once = THREAD_ONCE_INIT;
186
187#ifndef HAVE_ATTRIBUTE_CONSTRUCTOR
188 #if defined(__llvm__) || defined(__GNUC__)
189 #define HAVE_ATTRIBUTE_CONSTRUCTOR
190 #endif
191#endif
192
193#ifdef HAVE_ATTRIBUTE_CONSTRUCTOR
194static void __attribute__((constructor)) libimobiledevice_initialize(void)
195{ 185{
196 thread_once(&init_once, internal_idevice_init); 186#if defined(HAVE_OPENSSL)
197} 187#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
188 int i;
189 SSL_library_init();
198 190
199static void __attribute__((destructor)) libimobiledevice_deinitialize(void) 191 mutex_buf = malloc(CRYPTO_num_locks() * sizeof(mutex_t));
200{ 192 if (!mutex_buf)
201 thread_once(&deinit_once, internal_idevice_deinit); 193 return;
202} 194 for (i = 0; i < CRYPTO_num_locks(); i++)
203#elif defined(WIN32) 195 mutex_init(&mutex_buf[i]);
204BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) 196
205{ 197#if OPENSSL_VERSION_NUMBER < 0x10000000L
206 switch (dwReason) { 198 CRYPTO_set_id_callback(id_function);
207 case DLL_PROCESS_ATTACH:
208 thread_once(&init_once, internal_idevice_init);
209 break;
210 case DLL_PROCESS_DETACH:
211 thread_once(&deinit_once, internal_idevice_deinit);
212 break;
213 default:
214 break;
215 }
216 return 1;
217}
218#else 199#else
219#warning No compiler support for constructor/destructor attributes, some features might not be available. 200 CRYPTO_THREADID_set_callback(id_function);
201#endif
202 CRYPTO_set_locking_callback(locking_function);
220#endif 203#endif
204#elif defined(HAVE_GNUTLS)
205 gnutls_global_init();
206#elif defined(HAVE_MBEDTLS)
207 // NO-OP
208#endif
209 atexit(internal_idevice_deinit);
210}
221 211
222const char* libimobiledevice_version() 212const char* libimobiledevice_version()
223{ 213{