|
@@ -872,7 +872,7 @@ int mg_atomic_inc(volatile int * addr)
|
|
|
ret = InterlockedIncrement(addr);
|
|
|
#elif defined(__GNUC__)
|
|
|
ret = __sync_add_and_fetch(addr, 1);
|
|
|
-#else
|
|
|
+#else
|
|
|
ret = (++(*addr));
|
|
|
#endif
|
|
|
return ret;
|
|
@@ -6104,7 +6104,7 @@ static int sslize(struct mg_connection *conn, SSL_CTX *s, int (*func)(SSL *))
|
|
|
func(conn->ssl) == 1;
|
|
|
}
|
|
|
|
|
|
-/* Return OpenSSL error message */
|
|
|
+/* Return OpenSSL error message (from CRYPTO lib) */
|
|
|
static const char *ssl_error(void)
|
|
|
{
|
|
|
unsigned long err;
|
|
@@ -6169,10 +6169,38 @@ static void *load_dll(struct mg_context *ctx, const char *dll_name,
|
|
|
}
|
|
|
#endif /* NO_SSL_DL */
|
|
|
|
|
|
+static int initialize_ssl(struct mg_context *ctx)
|
|
|
+{
|
|
|
+ int i, size;
|
|
|
+
|
|
|
+#if !defined(NO_SSL_DL)
|
|
|
+ ctx->cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw);
|
|
|
+ if (!ctx->cryptolib_dll_handle) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+#endif /* NO_SSL_DL */
|
|
|
+
|
|
|
+ /* Initialize locking callbacks, needed for thread safety.
|
|
|
+ http://www.openssl.org/support/faq.html#PROG1 */
|
|
|
+ size = sizeof(pthread_mutex_t) * CRYPTO_num_locks();
|
|
|
+ if ((ssl_mutexes = (pthread_mutex_t *) mg_malloc((size_t)size)) == NULL) {
|
|
|
+ mg_cry(fc(ctx), "%s: cannot allocate mutexes: %s", __func__, ssl_error());
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < CRYPTO_num_locks(); i++) {
|
|
|
+ pthread_mutex_init(&ssl_mutexes[i], NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ CRYPTO_set_locking_callback(&ssl_locking_callback);
|
|
|
+ CRYPTO_set_id_callback(&ssl_id_callback);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
/* Dynamically load SSL library. Set up ctx->ssl_ctx pointer. */
|
|
|
static int set_ssl_option(struct mg_context *ctx)
|
|
|
{
|
|
|
- int i, size;
|
|
|
const char *pem;
|
|
|
|
|
|
/* If PEM file is not specified and the init_ssl callback
|
|
@@ -6182,10 +6210,13 @@ static int set_ssl_option(struct mg_context *ctx)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+ if (!initialize_ssl(ctx)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
#if !defined(NO_SSL_DL)
|
|
|
ctx->ssllib_dll_handle = load_dll(ctx, SSL_LIB, ssl_sw);
|
|
|
- ctx->cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw);
|
|
|
- if (!ctx->ssllib_dll_handle || !ctx->cryptolib_dll_handle) {
|
|
|
+ if (!ctx->ssllib_dll_handle) {
|
|
|
return 0;
|
|
|
}
|
|
|
#endif /* NO_SSL_DL */
|
|
@@ -6213,21 +6244,6 @@ static int set_ssl_option(struct mg_context *ctx)
|
|
|
(void) SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem);
|
|
|
}
|
|
|
|
|
|
- /* Initialize locking callbacks, needed for thread safety.
|
|
|
- http://www.openssl.org/support/faq.html#PROG1 */
|
|
|
- size = sizeof(pthread_mutex_t) * CRYPTO_num_locks();
|
|
|
- if ((ssl_mutexes = (pthread_mutex_t *) mg_malloc((size_t)size)) == NULL) {
|
|
|
- mg_cry(fc(ctx), "%s: cannot allocate mutexes: %s", __func__, ssl_error());
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < CRYPTO_num_locks(); i++) {
|
|
|
- pthread_mutex_init(&ssl_mutexes[i], NULL);
|
|
|
- }
|
|
|
-
|
|
|
- CRYPTO_set_locking_callback(&ssl_locking_callback);
|
|
|
- CRYPTO_set_id_callback(&ssl_id_callback);
|
|
|
-
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -7091,15 +7107,15 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
|
|
|
if ((ctx = (struct mg_context *) mg_calloc(1, sizeof(*ctx))) == NULL) {
|
|
|
return NULL;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (mg_atomic_inc(&sTlsInit)==1) {
|
|
|
- if (0 != pthread_key_create(&sTlsKey, NULL)) {
|
|
|
+ if (0 != pthread_key_create(&sTlsKey, NULL)) {
|
|
|
/* Fatal error - abort start. However, this situation should never occur in practice. */
|
|
|
mg_atomic_dec(&sTlsInit);
|
|
|
mg_cry(fc(ctx), "Cannot initialize thread local storage");
|
|
|
- mg_free(ctx);
|
|
|
+ mg_free(ctx);
|
|
|
return NULL;
|
|
|
- }
|
|
|
+ }
|
|
|
} else {
|
|
|
/* TODO: check if sTlsKey is already initialized */
|
|
|
mg_sleep(1);
|