Make CRYPTO_library_init use a CRYPTO_once_t.
Initialization by multiple consumers on ARM is still problematic due to
CRYPTO_set_NEON_{capable,functional}, until we reimplement that in-library, but
if that is called before the first CRYPTO_library_init, this change makes it
safe.
BUG=556462
Change-Id: I5845d09cca909bace8293ba7adf09a3bd0d4f943
Reviewed-on: https://boringssl-review.googlesource.com/6519
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/crypto.c b/crypto/crypto.c
index 9d2e616..ace1c82 100644
--- a/crypto/crypto.c
+++ b/crypto/crypto.c
@@ -88,22 +88,22 @@
#endif
-#if defined(OPENSSL_WINDOWS)
+#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER)
#define OPENSSL_CDECL __cdecl
#else
#define OPENSSL_CDECL
#endif
-#if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
-#if !defined(OPENSSL_WINDOWS)
-static void do_library_init(void) __attribute__ ((constructor));
-#else
+#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
+static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
+#elif defined(OPENSSL_WINDOWS)
#pragma section(".CRT$XCU", read)
static void __cdecl do_library_init(void);
__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) =
do_library_init;
+#else
+static void do_library_init(void) __attribute__ ((constructor));
#endif
-#endif /* !BORINGSSL_NO_STATIC_INITIALIZER */
/* do_library_init is the actual initialization function. If
* BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static
@@ -119,9 +119,9 @@
void CRYPTO_library_init(void) {
/* TODO(davidben): It would be tidier if this build knob could be replaced
* with an internal lazy-init mechanism that would handle things correctly
- * in-library. */
+ * in-library. https://crbug.com/542879 */
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
- do_library_init();
+ CRYPTO_once(&once, do_library_init);
#endif
}