Index: tls.c
==================================================================
--- tls.c
+++ tls.c
@@ -63,11 +63,11 @@
 
 static SSL_CTX *CTX_Init(State *statePtr, int proto, char *key,
 			char *cert, char *CAdir, char *CAfile, char *ciphers,
 			char *DHparams);
 
-static int	TlsLibInit(void);
+static int	TlsLibInit(int uninitialize);
 
 #define TLS_PROTO_SSL2		0x01
 #define TLS_PROTO_SSL3		0x02
 #define TLS_PROTO_TLS1		0x04
 #define TLS_PROTO_TLS1_1	0x08
@@ -115,33 +115,26 @@
 /*
  * Threaded operation requires locking callbacks
  * Based from /crypto/cryptlib.c of OpenSSL and NSOpenSSL.
  */
 
-#ifndef CRYPTO_NUM_LOCKS
-#define CRYPTO_NUM_LOCKS 128
-#endif
-static Tcl_Mutex locks[CRYPTO_NUM_LOCKS];
+static Tcl_Mutex *locks = NULL;
 static Tcl_Mutex init_mx;
 
-static void          CryptoThreadLockCallback (int mode, int n, const char *file, int line);
-static unsigned long CryptoThreadIdCallback   (void);
-
-static void
-CryptoThreadLockCallback(int mode, int n, const char *file, int line)
-{
-    if (mode & CRYPTO_LOCK) {
-       Tcl_MutexLock(&locks[n]);
-    } else {
-       Tcl_MutexUnlock(&locks[n]);
-    }
-}
-
-static unsigned long
-CryptoThreadIdCallback(void)
-{
-    return (unsigned long) Tcl_GetCurrentThread();
+static void          CryptoThreadLockCallback(int mode, int n, const char *file, int line);
+static unsigned long CryptoThreadIdCallback(void);
+
+static void CryptoThreadLockCallback(int mode, int n, const char *file, int line) {
+	if (mode & CRYPTO_LOCK) {
+		Tcl_MutexLock(&locks[n]);
+	} else {
+		Tcl_MutexUnlock(&locks[n]);
+	}
+}
+
+static unsigned long CryptoThreadIdCallback(void) {
+	return (unsigned long) Tcl_GetCurrentThread();
 }
 #endif /* OPENSSL_THREADS */
 #endif /* TCL_THREADS */
 
 
@@ -1624,11 +1617,11 @@
 #endif
 	     == NULL) {
 		return TCL_ERROR;
 	}
 
-	if (TlsLibInit() != TCL_OK) {
+	if (TlsLibInit(0) != TCL_OK) {
 		Tcl_AppendResult(interp, "could not initialize SSL library", NULL);
 		return TCL_ERROR;
 	}
 
 	Tcl_CreateObjCommand(interp, "tls::ciphers", CiphersObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
@@ -1684,33 +1677,56 @@
  *	Result:
  *		none
  *
  *------------------------------------------------------*
  */
-static int TlsLibInit(void) {
+static int TlsLibInit(int uninitialize) {
 	static int initialized = 0;
 	int status = TCL_OK;
+#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
+	size_t num_locks;
+#endif
+
+	if (uninitialize) {
+		if (!initialized) {
+			dprintf("Asked to uninitialize, but we are not initialized");
+
+			return(TCL_OK);
+		}
+
+		dprintf("Asked to uninitialize");
+#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
+		Tcl_MutexLock(&init_mx);
+
+		CRYPTO_set_locking_callback(NULL);
+		CRYPTO_set_id_callback(NULL);
+
+		if (locks) {
+			free(locks);
+			locks = NULL;
+		}
+#endif
+		initialized = 0;
+
+#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
+		Tcl_MutexUnlock(&init_mx);
+#endif
+
+		return(TCL_OK);
+	}
 
 	if (initialized) {
 		return(status);
 	}
 
 	initialized = 1;
 
 #if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
-	size_t num_locks;
-
 	Tcl_MutexLock(&init_mx);
-#endif
 
-#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
-	/* should we consider allocating mutexes? */
 	num_locks = CRYPTO_num_locks();
-	if (num_locks > CRYPTO_NUM_LOCKS) {
-		status = TCL_ERROR;
-		goto done;
-	}
+	locks = malloc(sizeof(*locks) * num_locks);
 
 	CRYPTO_set_locking_callback(CryptoThreadLockCallback);
 	CRYPTO_set_id_callback(CryptoThreadIdCallback);
 #endif