Add BIO_get_new_index()

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
diff --git a/crypto/bio/b_addr.c b/crypto/bio/b_addr.c
index 4e8785f..17ab3e4 100644
--- a/crypto/bio/b_addr.c
+++ b/crypto/bio/b_addr.c
@@ -19,6 +19,7 @@
 #include <ctype.h>
 
 CRYPTO_RWLOCK *bio_lookup_lock;
+extern CRYPTO_RWLOCK  *bio_type_lock;
 static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
 
 /*
@@ -605,7 +606,8 @@
 DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
 {
     bio_lookup_lock = CRYPTO_THREAD_lock_new();
-    return (bio_lookup_lock != NULL);
+    bio_type_lock = CRYPTO_THREAD_lock_new();
+    return bio_lookup_lock != NULL && bio_type_lock != NULL;
 }
 
 /*-
diff --git a/crypto/bio/bio_lcl.h b/crypto/bio/bio_lcl.h
index f5a886c..5d0b827 100644
--- a/crypto/bio/bio_lcl.h
+++ b/crypto/bio/bio_lcl.h
@@ -137,6 +137,7 @@
 # endif
 
 extern CRYPTO_RWLOCK *bio_lookup_lock;
+extern CRYPTO_RWLOCK *bio_type_lock;
 
 int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa);
 const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap);
diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c
index 98f3707..8a00103 100644
--- a/crypto/bio/bio_lib.c
+++ b/crypto/bio/bio_lib.c
@@ -594,5 +594,7 @@
     bio_sock_cleanup_int();
     CRYPTO_THREAD_lock_free(bio_lookup_lock);
     bio_lookup_lock = NULL;
+    CRYPTO_THREAD_lock_free(bio_type_lock);
+    bio_type_lock = NULL;
 #endif
 }
diff --git a/crypto/bio/bio_meth.c b/crypto/bio/bio_meth.c
index d172047..7754b00 100644
--- a/crypto/bio/bio_meth.c
+++ b/crypto/bio/bio_meth.c
@@ -9,6 +9,18 @@
 
 #include "bio_lcl.h"
 
+CRYPTO_RWLOCK *bio_type_lock;
+static int bio_count = BIO_TYPE_START;
+
+int BIO_get_new_index()
+{
+    int newval;
+
+    if (!CRYPTO_atomic_add(&bio_count, 1, &newval, bio_type_lock))
+        return -1;
+    return newval;
+}
+
 BIO_METHOD *BIO_meth_new(int type, const char *name)
 {
     BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD));