Convert ERR_STRING_DATA to new multi-threading API
authorAlessandro Ghedini <alessandro@ghedini.me>
Sat, 5 Mar 2016 21:31:43 +0000 (21:31 +0000)
committerAlessandro Ghedini <alessandro@cloudflare.com>
Tue, 8 Mar 2016 14:11:59 +0000 (14:11 +0000)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/err/err.c
include/openssl/crypto.h

index 36ba9c7..da6d3ee 100644 (file)
@@ -234,6 +234,9 @@ static ERR_STRING_DATA ERR_str_reasons[] = {
 static CRYPTO_ONCE err_init = CRYPTO_ONCE_STATIC_INIT;
 static CRYPTO_THREAD_LOCAL err_thread_local;
 
+static CRYPTO_ONCE err_string_init = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_RWLOCK *err_string_lock;
+
 /* Predeclarations of the "err_defaults" functions */
 static LHASH_OF(ERR_STRING_DATA) *get_hash(int create, int lockit);
 static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
@@ -269,7 +272,7 @@ static LHASH_OF(ERR_STRING_DATA) *get_hash(int create, int lockit)
     LHASH_OF(ERR_STRING_DATA) *ret = NULL;
 
     if (lockit)
-        CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+        CRYPTO_THREAD_write_lock(err_string_lock);
     if (!int_error_hash && create) {
         int_error_hash = lh_ERR_STRING_DATA_new(err_string_data_hash,
                                                 err_string_data_cmp);
@@ -277,7 +280,7 @@ static LHASH_OF(ERR_STRING_DATA) *get_hash(int create, int lockit)
     if (int_error_hash != NULL)
         ret = int_error_hash;
     if (lockit)
-        CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+        CRYPTO_THREAD_unlock(err_string_lock);
 
     return ret;
 }
@@ -287,11 +290,11 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
     ERR_STRING_DATA *p = NULL;
     LHASH_OF(ERR_STRING_DATA) *hash;
 
-    CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_read_lock(err_string_lock);
     hash = get_hash(0, 0);
     if (hash)
         p = lh_ERR_STRING_DATA_retrieve(hash, d);
-    CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_unlock(err_string_lock);
 
     return p;
 }
@@ -318,16 +321,9 @@ static void build_SYS_str_reasons(void)
     static int init = 1;
     int i;
 
-    CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-    if (!init) {
-        CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-        return;
-    }
-
-    CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-    CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_write_lock(err_string_lock);
     if (!init) {
-        CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+        CRYPTO_THREAD_unlock(err_string_lock);
         return;
     }
 
@@ -355,7 +351,7 @@ static void build_SYS_str_reasons(void)
 
     init = 0;
 
-    CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_unlock(err_string_lock);
 }
 #endif
 
@@ -391,9 +387,18 @@ static void ERR_STATE_free(ERR_STATE *s)
     OPENSSL_free(s);
 }
 
+static void do_err_strings_init(void)
+{
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+    err_string_lock = CRYPTO_THREAD_lock_new();
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+}
+
 void ERR_load_ERR_strings(void)
 {
 #ifndef OPENSSL_NO_ERR
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
     err_load_strings(0, ERR_str_libraries);
     err_load_strings(0, ERR_str_reasons);
     err_load_strings(ERR_LIB_SYS, ERR_str_functs);
@@ -406,7 +411,7 @@ static void err_load_strings(int lib, ERR_STRING_DATA *str)
 {
     LHASH_OF(ERR_STRING_DATA) *hash;
 
-    CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_write_lock(err_string_lock);
     hash = get_hash(1, 0);
     if (hash) {
         for (; str->error; str++) {
@@ -415,7 +420,7 @@ static void err_load_strings(int lib, ERR_STRING_DATA *str)
             (void)lh_ERR_STRING_DATA_insert(hash, str);
         }
     }
-    CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_unlock(err_string_lock);
 }
 
 void ERR_load_strings(int lib, ERR_STRING_DATA *str)
@@ -428,7 +433,9 @@ void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
 {
     LHASH_OF(ERR_STRING_DATA) *hash;
 
-    CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
     hash = get_hash(0, 0);
     if (hash) {
         for (; str->error; str++) {
@@ -437,15 +444,17 @@ void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
             (void)lh_ERR_STRING_DATA_delete(hash, str);
         }
     }
-    CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_unlock(err_string_lock);
 }
 
 void ERR_free_strings(void)
 {
-    CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
     lh_ERR_STRING_DATA_free(int_error_hash);
     int_error_hash = NULL;
-    CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_unlock(err_string_lock);
 }
 
 /********************************************************/
@@ -686,6 +695,8 @@ const char *ERR_lib_error_string(unsigned long e)
     ERR_STRING_DATA d, *p;
     unsigned long l;
 
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
     l = ERR_GET_LIB(e);
     d.error = ERR_PACK(l, 0, 0);
     p = int_err_get_item(&d);
@@ -697,6 +708,8 @@ const char *ERR_func_error_string(unsigned long e)
     ERR_STRING_DATA d, *p;
     unsigned long l, f;
 
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
     l = ERR_GET_LIB(e);
     f = ERR_GET_FUNC(e);
     d.error = ERR_PACK(l, f, 0);
@@ -709,6 +722,8 @@ const char *ERR_reason_error_string(unsigned long e)
     ERR_STRING_DATA d, *p = NULL;
     unsigned long l, r;
 
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
     l = ERR_GET_LIB(e);
     r = ERR_GET_REASON(e);
     d.error = ERR_PACK(l, 0, r);
@@ -772,9 +787,11 @@ int ERR_get_next_error_library(void)
 {
     int ret;
 
-    CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
     ret = int_err_library_number++;
-    CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+    CRYPTO_THREAD_unlock(err_string_lock);
     return ret;
 }
 
index 0f09197..53c26b9 100644 (file)
@@ -165,7 +165,6 @@ extern "C" {
  * names in cryptlib.c
  */
 
-# define CRYPTO_LOCK_ERR                 1
 # define CRYPTO_LOCK_X509                3
 # define CRYPTO_LOCK_X509_INFO           4
 # define CRYPTO_LOCK_X509_PKEY           5