Use pthreads on MinGW.

Android uses MinGW for some host tools on Windows. That toolchain
doesn't support the #pragma tricks we use for thread-local destructors,
but does appear to support pthreads.

This also lets us remove the INIT_ONCE workaround, although that's
removable anyway since Android's MinGW is now new enough.

Change-Id: I8d1573923fdaac880a50d84acbebbf87461c50d2
Reviewed-on: https://boringssl-review.googlesource.com/11125
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Kenny Root <kroot@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/internal.h b/crypto/internal.h
index d6e341a..8ac60cb 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -121,13 +121,18 @@
 #include <stdalign.h>
 #endif
 
-#if defined(OPENSSL_NO_THREADS)
-#elif defined(OPENSSL_WINDOWS)
+#if !defined(OPENSSL_NO_THREADS) && \
+    (!defined(OPENSSL_WINDOWS) || defined(__MINGW32__))
+#include <pthread.h>
+#define OPENSSL_PTHREADS
+#endif
+
+#if !defined(OPENSSL_NO_THREADS) && !defined(OPENSSL_PTHREADS) && \
+    defined(OPENSSL_WINDOWS)
+#define OPENSSL_WINDOWS_THREADS
 OPENSSL_MSVC_PRAGMA(warning(push, 3))
 #include <windows.h>
 OPENSSL_MSVC_PRAGMA(warning(pop))
-#else
-#include <pthread.h>
 #endif
 
 #if defined(__cplusplus)
@@ -304,25 +309,17 @@
 
 /* Thread-safe initialisation. */
 
-/* Android's mingw-w64 has some prototypes for INIT_ONCE, but is missing
- * others. Work around the missing ones.
- *
- * TODO(davidben): Remove this once Android's mingw-w64 is upgraded. See
- * b/26523949. */
-#if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT)
-typedef RTL_RUN_ONCE INIT_ONCE;
-#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
-#endif
-
 #if defined(OPENSSL_NO_THREADS)
 typedef uint32_t CRYPTO_once_t;
 #define CRYPTO_ONCE_INIT 0
-#elif defined(OPENSSL_WINDOWS)
+#elif defined(OPENSSL_WINDOWS_THREADS)
 typedef INIT_ONCE CRYPTO_once_t;
 #define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT
-#else
+#elif defined(OPENSSL_PTHREADS)
 typedef pthread_once_t CRYPTO_once_t;
 #define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT
+#else
+#error "Unknown threading library"
 #endif
 
 /* CRYPTO_once calls |init| exactly once per process. This is thread-safe: if
@@ -373,16 +370,18 @@
   char padding;  /* Empty structs have different sizes in C and C++. */
 };
 #define CRYPTO_STATIC_MUTEX_INIT { 0 }
-#elif defined(OPENSSL_WINDOWS)
+#elif defined(OPENSSL_WINDOWS_THREADS)
 struct CRYPTO_STATIC_MUTEX {
   SRWLOCK lock;
 };
 #define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT }
-#else
+#elif defined(OPENSSL_PTHREADS)
 struct CRYPTO_STATIC_MUTEX {
   pthread_rwlock_t lock;
 };
 #define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER }
+#else
+#error "Unknown threading library"
 #endif
 
 /* CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a
diff --git a/crypto/thread_pthread.c b/crypto/thread_pthread.c
index 2baa2b4..90ff861 100644
--- a/crypto/thread_pthread.c
+++ b/crypto/thread_pthread.c
@@ -14,7 +14,7 @@
 
 #include "internal.h"
 
-#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
+#if defined(OPENSSL_PTHREADS)
 
 #include <pthread.h>
 #include <stdlib.h>
@@ -173,4 +173,4 @@
   return 1;
 }
 
-#endif  /* !OPENSSL_WINDOWS && !OPENSSL_NO_THREADS */
+#endif  /* OPENSSL_PTHREADS */
diff --git a/crypto/thread_win.c b/crypto/thread_win.c
index c7a90f7..836cf0f 100644
--- a/crypto/thread_win.c
+++ b/crypto/thread_win.c
@@ -14,7 +14,7 @@
 
 #include "internal.h"
 
-#if defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
+#if defined(OPENSSL_WINDOWS_THREADS)
 
 OPENSSL_MSVC_PRAGMA(warning(push, 3))
 #include <windows.h>
@@ -234,4 +234,4 @@
   return 1;
 }
 
-#endif  /* OPENSSL_WINDOWS && !OPENSSL_NO_THREADS */
+#endif  /* OPENSSL_WINDOWS_THREADS */