summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-07-04 03:33:11 +0200
committerGravatar Nikias Bassen2017-07-04 03:33:11 +0200
commitb7e78e276b2a72527b2fe6bf584707682681bcdd (patch)
tree84a9467917063a27c61ab60fbc98fe453b7dd3c5 /src
parent6d7418a8cc3a5da6ed558152d201686742ab6fcc (diff)
downloadlibideviceactivation-b7e78e276b2a72527b2fe6bf584707682681bcdd.tar.gz
libideviceactivation-b7e78e276b2a72527b2fe6bf584707682681bcdd.tar.bz2
Make sure to only globally init/deinit libcurl upon library load/unload
Up until now libcurl was initialized/deinitialized every time a request was sent. However curl_global_cleanup() also affects other libraries' code so that e.g. OpenSSL-related functions could fail.
Diffstat (limited to 'src')
-rw-r--r--src/activation.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/src/activation.c b/src/activation.c
index 57d5ea1..d8cbc6f 100644
--- a/src/activation.c
+++ b/src/activation.c
@@ -40,6 +40,12 @@
#endif
#endif
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#endif
+
#include <libideviceactivation.h>
#define IDEVICE_ACTIVATION_USER_AGENT_IOS "iOS Device Activator (MobileActivation-20 built on Jan 15 2012 at 19:07:28)"
@@ -77,7 +83,73 @@ struct idevice_activation_response_private {
int has_errors;
};
-int debug_level = 0;
+
+static void internal_libideviceactivation_init(void)
+{
+ curl_global_init(CURL_GLOBAL_ALL);
+}
+
+static void internal_libideviceactivation_deinit(void)
+{
+ curl_global_cleanup();
+}
+
+#ifdef WIN32
+
+typedef volatile struct {
+ LONG lock;
+ int state;
+} thread_once_t;
+
+static thread_once_t init_once = {0, 0};
+static thread_once_t deinit_once = {0, 0};
+
+void thread_once(thread_once_t *once_control, void (*init_routine)(void))
+{
+ while (InterlockedExchange(&(once_control->lock), 1) != 0) {
+ Sleep(1);
+ }
+ if (!once_control->state) {
+ once_control->state = 1;
+ init_routine();
+ }
+ InterlockedExchange(&(once_control->lock), 0);
+}
+
+BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
+{
+ switch (dwReason) {
+ case DLL_PROCESS_ATTACH:
+ thread_once(&init_once, internal_libideviceactivation_init);
+ break;
+ case DLL_PROCESS_DETACH:
+ thread_once(&deinit_once, internal_libideviceactivation_deinit);
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+#else
+
+static pthread_once_t init_once = PTHREAD_ONCE_INIT;
+static pthread_once_t deinit_once = PTHREAD_ONCE_INIT;
+
+static void __attribute__((constructor)) libideviceactivation_initialize(void)
+{
+ pthread_once(&init_once, internal_libideviceactivation_init);
+}
+
+static void __attribute__((destructor)) libideviceactivation_deinitialize(void)
+{
+ pthread_once(&deinit_once, internal_libideviceactivation_deinit);
+}
+
+#endif
+
+
+static int debug_level = 0;
IDEVICE_ACTIVATION_API void idevice_activation_set_debug_level(int level) {
debug_level = level;
@@ -967,7 +1039,6 @@ IDEVICE_ACTIVATION_API idevice_activation_error_t idevice_activation_send_reques
goto cleanup;
}
- curl_global_init(CURL_GLOBAL_ALL);
CURL* handle = curl_easy_init();
struct curl_httppost* form = NULL;
@@ -1105,7 +1176,5 @@ cleanup:
if (handle)
curl_easy_cleanup(handle);
- curl_global_cleanup();
-
return result;
}