really fix race condition

PR: 262
diff --git a/CHANGES b/CHANGES
index b217662..1a312d9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1927,8 +1927,12 @@
      (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes).
      [Bodo Moeller]
 
-  *) Fix race condition in SSLv3_client_method().
-     [Bodo Moeller]
+  *) Fix initialization code race conditions in
+        SSLv23_client_method(),   SSLv23_server_method(),
+        SSLv2_client_method(),    SSLv2_server_method(),
+        SSLv3_client_method(),    SSLv3_server_method(),
+        TLSv1_client_method(),    TLSv1_server_method().
+     [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
 
   *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
      the cached sessions are flushed, as the remove_cb() might use ex_data
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index b72f7fb..5d8debd 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -94,6 +94,7 @@
 	"ssl_session",
 	"ssl_sess_cert",
 	"ssl",
+	"ssl_method",
 	"rand",
 	"rand2",
 	"debug_malloc",
@@ -111,7 +112,7 @@
 	"ecdsa",
 	"ec",
 	"ecdh",
-#if CRYPTO_NUM_LOCKS != 34
+#if CRYPTO_NUM_LOCKS != 35
 # error "Inconsistency between crypto.h and cryptlib.c"
 #endif
 	};
diff --git a/crypto/crypto.h b/crypto/crypto.h
index e4d1526..1490db9 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -111,30 +111,31 @@
 #define CRYPTO_LOCK_DSA			8
 #define CRYPTO_LOCK_RSA			9
 #define CRYPTO_LOCK_EVP_PKEY		10
-#define	CRYPTO_LOCK_X509_STORE		11
-#define	CRYPTO_LOCK_SSL_CTX		12
-#define	CRYPTO_LOCK_SSL_CERT		13
-#define	CRYPTO_LOCK_SSL_SESSION		14
-#define	CRYPTO_LOCK_SSL_SESS_CERT	15
-#define	CRYPTO_LOCK_SSL			16
-#define	CRYPTO_LOCK_RAND		17
-#define	CRYPTO_LOCK_RAND2		18
-#define	CRYPTO_LOCK_MALLOC		19
-#define	CRYPTO_LOCK_BIO			20
-#define	CRYPTO_LOCK_GETHOSTBYNAME	21
-#define	CRYPTO_LOCK_GETSERVBYNAME	22
-#define	CRYPTO_LOCK_READDIR		23
-#define	CRYPTO_LOCK_RSA_BLINDING	24
-#define	CRYPTO_LOCK_DH			25
-#define	CRYPTO_LOCK_MALLOC2		26
-#define	CRYPTO_LOCK_DSO			27
-#define	CRYPTO_LOCK_DYNLOCK		28
-#define	CRYPTO_LOCK_ENGINE		29
-#define	CRYPTO_LOCK_UI			30
-#define CRYPTO_LOCK_ECDSA               31
-#define CRYPTO_LOCK_EC			32
-#define CRYPTO_LOCK_ECDH			33
-#define	CRYPTO_NUM_LOCKS		34
+#define CRYPTO_LOCK_X509_STORE		11
+#define CRYPTO_LOCK_SSL_CTX		12
+#define CRYPTO_LOCK_SSL_CERT		13
+#define CRYPTO_LOCK_SSL_SESSION		14
+#define CRYPTO_LOCK_SSL_SESS_CERT	15
+#define CRYPTO_LOCK_SSL			16
+#define CRYPTO_LOCK_SSL_METHOD		17
+#define CRYPTO_LOCK_RAND		18
+#define CRYPTO_LOCK_RAND2		19
+#define CRYPTO_LOCK_MALLOC		20
+#define CRYPTO_LOCK_BIO			21
+#define CRYPTO_LOCK_GETHOSTBYNAME	22
+#define CRYPTO_LOCK_GETSERVBYNAME	23
+#define CRYPTO_LOCK_READDIR		24
+#define CRYPTO_LOCK_RSA_BLINDING	25
+#define CRYPTO_LOCK_DH			26
+#define CRYPTO_LOCK_MALLOC2		27
+#define CRYPTO_LOCK_DSO			28
+#define CRYPTO_LOCK_DYNLOCK		29
+#define CRYPTO_LOCK_ENGINE		30
+#define CRYPTO_LOCK_UI			31
+#define CRYPTO_LOCK_ECDSA               32
+#define CRYPTO_LOCK_EC			33
+#define CRYPTO_LOCK_ECDH		34
+#define CRYPTO_NUM_LOCKS		35
 
 #define CRYPTO_LOCK		1
 #define CRYPTO_UNLOCK		2
@@ -156,7 +157,7 @@
 #endif
 #else
 #define CRYPTO_w_lock(a)
-#define	CRYPTO_w_unlock(a)
+#define CRYPTO_w_unlock(a)
 #define CRYPTO_r_lock(a)
 #define CRYPTO_r_unlock(a)
 #define CRYPTO_add(a,b,c)	((*(a))+=(b))
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 019e9ae..9c02cb4 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -87,11 +87,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&SSLv23_client_data,
 			(char *)sslv23_base_method(),sizeof(SSL_METHOD));
 		SSLv23_client_data.ssl_connect=ssl23_connect;
 		SSLv23_client_data.get_ssl_method=ssl23_get_client_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv23_client_data);
 	}
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 8743b61..5c7e9fa 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -139,11 +139,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&SSLv23_server_data,
 			(char *)sslv23_base_method(),sizeof(SSL_METHOD));
 		SSLv23_server_data.ssl_accept=ssl23_accept;
 		SSLv23_server_data.get_ssl_method=ssl23_get_server_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv23_server_data);
 	}
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index 570d066..0d29039 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -145,11 +145,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(),
 			sizeof(SSL_METHOD));
 		SSLv2_client_data.ssl_connect=ssl2_connect;
 		SSLv2_client_data.get_ssl_method=ssl2_get_client_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv2_client_data);
 	}
diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c
index 97dda2d..d64d4e1 100644
--- a/ssl/s2_srvr.c
+++ b/ssl/s2_srvr.c
@@ -145,11 +145,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&SSLv2_server_data,(char *)sslv2_base_method(),
 			sizeof(SSL_METHOD));
 		SSLv2_server_data.ssl_accept=ssl2_accept;
 		SSLv2_server_data.get_ssl_method=ssl2_get_server_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv2_server_data);
 	}
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 578eca4..6e29a6c 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -178,11 +178,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(),
 			sizeof(SSL_METHOD));
 		SSLv3_client_data.ssl_connect=ssl3_connect;
 		SSLv3_client_data.get_ssl_method=ssl3_get_client_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv3_client_data);
 	}
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 4b374a9..7742f3b 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -181,11 +181,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
 			sizeof(SSL_METHOD));
 		SSLv3_server_data.ssl_accept=ssl3_accept;
 		SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv3_server_data);
 	}
diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c
index 9ad518f..3eb3ae5 100644
--- a/ssl/t1_clnt.c
+++ b/ssl/t1_clnt.c
@@ -79,11 +79,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&TLSv1_client_data,(char *)tlsv1_base_method(),
 			sizeof(SSL_METHOD));
 		TLSv1_client_data.ssl_connect=ssl3_connect;
 		TLSv1_client_data.get_ssl_method=tls1_get_client_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&TLSv1_client_data);
 	}
diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c
index 6e765e5..c72e552 100644
--- a/ssl/t1_srvr.c
+++ b/ssl/t1_srvr.c
@@ -80,11 +80,15 @@
 
 	if (init)
 		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
 		memcpy((char *)&TLSv1_server_data,(char *)tlsv1_base_method(),
 			sizeof(SSL_METHOD));
 		TLSv1_server_data.ssl_accept=ssl3_accept;
 		TLSv1_server_data.get_ssl_method=tls1_get_server_method;
 		init=0;
+
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&TLSv1_server_data);
 	}