get SSL support to work again
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index b680c41..64f4578 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -2,14 +2,15 @@
 
    SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
    Re-worked a bit by Bill Janssen to add server-side support and
-   certificate decoding.
+   certificate decoding.  Chris Stawarz contributed some non-blocking
+   patches.
 
    This module is imported by ssl.py. It should *not* be used
    directly.
 
    XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE?
 
-   XXX what about SSL_MODE_AUTO_RETRY
+   XXX what about SSL_MODE_AUTO_RETRY?
 */
 
 #include "Python.h"
@@ -17,7 +18,7 @@
 #ifdef WITH_THREAD
 #include "pythread.h"
 #define PySSL_BEGIN_ALLOW_THREADS { \
-			PyThreadState *_save;  \
+			PyThreadState *_save = NULL;  \
 			if (_ssl_locks_count>0) {_save = PyEval_SaveThread();}
 #define PySSL_BLOCK_THREADS	if (_ssl_locks_count>0){PyEval_RestoreThread(_save)};
 #define PySSL_UNBLOCK_THREADS	if (_ssl_locks_count>0){_save = PyEval_SaveThread()};
@@ -114,8 +115,6 @@
 	SSL_CTX*	ctx;
 	SSL*		ssl;
 	X509*		peer_cert;
-	char		server[X509_NAME_MAXLEN];
-	char		issuer[X509_NAME_MAXLEN];
 
 } PySSLObject;
 
@@ -265,15 +264,11 @@
 	PySSLObject *self;
 	char *errstr = NULL;
 	int ret;
-	int err;
-	int sockstate;
 	int verification_mode;
 
 	self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
 	if (self == NULL)
 		return NULL;
-	memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
-	memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
 	self->peer_cert = NULL;
 	self->ssl = NULL;
 	self->ctx = NULL;
@@ -388,57 +383,6 @@
 		SSL_set_accept_state(self->ssl);
 	PySSL_END_ALLOW_THREADS
 
-	/* Actually negotiate SSL connection */
-	/* XXX If SSL_connect() returns 0, it's also a failure. */
-	sockstate = 0;
-	do {
-		PySSL_BEGIN_ALLOW_THREADS
-		if (socket_type == PY_SSL_CLIENT)
-			ret = SSL_connect(self->ssl);
-		else
-			ret = SSL_accept(self->ssl);
-		err = SSL_get_error(self->ssl, ret);
-		PySSL_END_ALLOW_THREADS
-		if(PyErr_CheckSignals()) {
-			goto fail;
-		}
-		if (err == SSL_ERROR_WANT_READ) {
-			sockstate = check_socket_and_wait_for_timeout(Sock, 0);
-		} else if (err == SSL_ERROR_WANT_WRITE) {
-			sockstate = check_socket_and_wait_for_timeout(Sock, 1);
-		} else {
-			sockstate = SOCKET_OPERATION_OK;
-		}
-		if (sockstate == SOCKET_HAS_TIMED_OUT) {
-			PyErr_SetString(PySSLErrorObject,
-				ERRSTR("The connect operation timed out"));
-			goto fail;
-		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
-			PyErr_SetString(PySSLErrorObject,
-				ERRSTR("Underlying socket has been closed."));
-			goto fail;
-		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
-			PyErr_SetString(PySSLErrorObject,
-			  ERRSTR("Underlying socket too large for select()."));
-			goto fail;
-		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
-			break;
-		}
-	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
-	if (ret < 1) {
-		PySSL_SetError(self, ret, __FILE__, __LINE__);
-		goto fail;
-	}
-	self->ssl->debug = 1;
-
-	PySSL_BEGIN_ALLOW_THREADS
-	if ((self->peer_cert = SSL_get_peer_certificate(self->ssl))) {
-		X509_NAME_oneline(X509_get_subject_name(self->peer_cert),
-				  self->server, X509_NAME_MAXLEN);
-		X509_NAME_oneline(X509_get_issuer_name(self->peer_cert),
-				  self->issuer, X509_NAME_MAXLEN);
-	}
-	PySSL_END_ALLOW_THREADS
 	self->Socket = Sock;
 	Py_INCREF(self->Socket);
 	return self;
@@ -488,16 +432,58 @@
 
 /* SSL object methods */
 
-static PyObject *
-PySSL_server(PySSLObject *self)
+static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
 {
-	return PyUnicode_FromString(self->server);
-}
+	int ret;
+	int err;
+	int sockstate;
 
-static PyObject *
-PySSL_issuer(PySSLObject *self)
-{
-	return PyUnicode_FromString(self->issuer);
+	/* Actually negotiate SSL connection */
+	/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
+	sockstate = 0;
+	do {
+		PySSL_BEGIN_ALLOW_THREADS
+		ret = SSL_do_handshake(self->ssl);
+		err = SSL_get_error(self->ssl, ret);
+		PySSL_END_ALLOW_THREADS
+		if(PyErr_CheckSignals()) {
+			return NULL;
+		}
+		if (err == SSL_ERROR_WANT_READ) {
+			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+		} else if (err == SSL_ERROR_WANT_WRITE) {
+			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+		} else {
+			sockstate = SOCKET_OPERATION_OK;
+		}
+		if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject,
+				ERRSTR("The handshake operation timed out"));
+			return NULL;
+		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+			PyErr_SetString(PySSLErrorObject,
+				ERRSTR("Underlying socket has been closed."));
+			return NULL;
+		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+			PyErr_SetString(PySSLErrorObject,
+			  ERRSTR("Underlying socket too large for select()."));
+			return NULL;
+		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
+			break;
+		}
+	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+	if (ret < 1)
+		return PySSL_SetError(self, ret, __FILE__, __LINE__);
+	self->ssl->debug = 1;
+
+	if (self->peer_cert)
+		X509_free (self->peer_cert);
+        PySSL_BEGIN_ALLOW_THREADS
+	self->peer_cert = SSL_get_peer_certificate(self->ssl);
+	PySSL_END_ALLOW_THREADS
+
+	Py_INCREF(Py_None);
+	return Py_None;
 }
 
 static PyObject *
@@ -515,7 +501,7 @@
 		_setSSLError(NULL, 0, __FILE__, __LINE__);
 		goto fail;
 	}
-	name_obj = PyString_FromStringAndSize(namebuf, buflen);
+	name_obj = PyUnicode_FromStringAndSize(namebuf, buflen);
 	if (name_obj == NULL)
 		goto fail;
 	
@@ -681,21 +667,24 @@
 		/* now decode the altName */
 		ext = X509_get_ext(certificate, i);
 		if(!(method = X509V3_EXT_get(ext))) {
-			PyErr_SetString(PySSLErrorObject,
-					ERRSTR("No method for internalizing subjectAltName!"));
+			PyErr_SetString
+                          (PySSLErrorObject,
+                           ERRSTR("No method for internalizing subjectAltName!"));
 			goto fail;
 		}
 
 		p = ext->value->data;
 		if(method->it)
-			names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL,
-								&p,
-								ext->value->length,
-								ASN1_ITEM_ptr(method->it)));
+			names = (GENERAL_NAMES*)
+                          (ASN1_item_d2i(NULL,
+                                         &p,
+                                         ext->value->length,
+                                         ASN1_ITEM_ptr(method->it)));
 		else
-			names = (GENERAL_NAMES*) (method->d2i(NULL,
-							      &p,
-							      ext->value->length));
+			names = (GENERAL_NAMES*)
+                          (method->d2i(NULL,
+                                       &p,
+                                       ext->value->length));
 
 		for(j = 0; j < sk_GENERAL_NAME_num(names); j++) {
 
@@ -704,14 +693,15 @@
 			name = sk_GENERAL_NAME_value(names, j);
 			if (name->type == GEN_DIRNAME) {
 
-				/* we special-case DirName as a tuple of tuples of attributes */
+				/* we special-case DirName as a tuple of
+                                   tuples of attributes */
 
 				t = PyTuple_New(2);
 				if (t == NULL) {
 					goto fail;
 				}
 
-				v = PyString_FromString("DirName");
+				v = PyUnicode_FromString("DirName");
 				if (v == NULL) {
 					Py_DECREF(t);
 					goto fail;
@@ -742,13 +732,14 @@
 				t = PyTuple_New(2);
 				if (t == NULL)
 					goto fail;
-				v = PyString_FromStringAndSize(buf, (vptr - buf));
+				v = PyUnicode_FromStringAndSize(buf, (vptr - buf));
 				if (v == NULL) {
 					Py_DECREF(t);
 					goto fail;
 				}
 				PyTuple_SET_ITEM(t, 0, v);
-				v = PyString_FromStringAndSize((vptr + 1), (len - (vptr - buf + 1)));
+				v = PyUnicode_FromStringAndSize((vptr + 1),
+                                                                (len - (vptr - buf + 1)));
 				if (v == NULL) {
 					Py_DECREF(t);
 					goto fail;
@@ -849,7 +840,7 @@
 			_setSSLError(NULL, 0, __FILE__, __LINE__);
 			goto fail1;
 		}
-		sn_obj = PyString_FromStringAndSize(buf, len);
+		sn_obj = PyUnicode_FromStringAndSize(buf, len);
 		if (sn_obj == NULL)
 			goto fail1;
 		if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) {
@@ -866,7 +857,7 @@
 			_setSSLError(NULL, 0, __FILE__, __LINE__);
 			goto fail1;
 		}
-		pnotBefore = PyString_FromStringAndSize(buf, len);
+		pnotBefore = PyUnicode_FromStringAndSize(buf, len);
 		if (pnotBefore == NULL)
 			goto fail1;
 		if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) {
@@ -884,7 +875,7 @@
 		_setSSLError(NULL, 0, __FILE__, __LINE__);
 		goto fail1;
 	}
-	pnotAfter = PyString_FromStringAndSize(buf, len);
+	pnotAfter = PyUnicode_FromStringAndSize(buf, len);
 	if (pnotAfter == NULL)
 		goto fail1;
 	if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) {
@@ -928,22 +919,26 @@
 	BIO *cert;
 	int verbose = 1;
 
-	if (!PyArg_ParseTuple(args, "s|i:test_decode_certificate", &filename, &verbose))
+	if (!PyArg_ParseTuple(args, "s|i:test_decode_certificate",
+                              &filename, &verbose))
 		return NULL;
 
 	if ((cert=BIO_new(BIO_s_file())) == NULL) {
-		PyErr_SetString(PySSLErrorObject, "Can't malloc memory to read file");
+		PyErr_SetString(PySSLErrorObject,
+                                "Can't malloc memory to read file");
 		goto fail0;
 	}
 
 	if (BIO_read_filename(cert,filename) <= 0) {
-		PyErr_SetString(PySSLErrorObject, "Can't open file");
+		PyErr_SetString(PySSLErrorObject,
+                                "Can't open file");
 		goto fail0;
 	}
 
 	x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);
 	if (x == NULL) {
-		PyErr_SetString(PySSLErrorObject, "Error decoding PEM-encoded file");
+		PyErr_SetString(PySSLErrorObject,
+                                "Error decoding PEM-encoded file");
 		goto fail0;
 	}
 
@@ -981,7 +976,9 @@
 			PySSL_SetError(self, len, __FILE__, __LINE__);
 			return NULL;
 		}
-		retval = PyString_FromStringAndSize((const char *) bytes_buf, len);
+                /* this is actually an immutable bytes sequence */
+		retval = PyBytes_FromStringAndSize
+                  ((const char *) bytes_buf, len);
 		OPENSSL_free(bytes_buf);
 		return retval;
 
@@ -1028,7 +1025,7 @@
 	if (cipher_name == NULL) {
 		PyTuple_SET_ITEM(retval, 0, Py_None);
 	} else {
-		v = PyString_FromString(cipher_name);
+		v = PyUnicode_FromString(cipher_name);
 		if (v == NULL)
 			goto fail0;
 		PyTuple_SET_ITEM(retval, 0, v);
@@ -1037,7 +1034,7 @@
 	if (cipher_protocol == NULL) {
 		PyTuple_SET_ITEM(retval, 1, Py_None);
 	} else {
-		v = PyString_FromString(cipher_protocol);
+		v = PyUnicode_FromString(cipher_protocol);
 		if (v == NULL)
 			goto fail0;
 		PyTuple_SET_ITEM(retval, 1, v);
@@ -1127,7 +1124,9 @@
 		rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
 	PySSL_END_ALLOW_THREADS
 
+#ifdef HAVE_POLL
 normal_return:
+#endif
 	/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
 	   (when we are able to write or when there's something to read) */
 	return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK;
@@ -1140,10 +1139,16 @@
 	int count;
 	int sockstate;
 	int err;
+        int nonblocking;
 
-	if (!PyArg_ParseTuple(args, "s#:write", &data, &count))
+	if (!PyArg_ParseTuple(args, "y#:write", &data, &count))
 		return NULL;
 
+        /* just in case the blocking state of the socket has been changed */
+	nonblocking = (self->Socket->sock_timeout >= 0.0);
+        BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);
+        BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);
+
 	sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
 	if (sockstate == SOCKET_HAS_TIMED_OUT) {
 		PyErr_SetString(PySSLErrorObject,
@@ -1200,19 +1205,58 @@
 Writes the string s into the SSL object.  Returns the number\n\
 of bytes written.");
 
+static PyObject *PySSL_SSLpending(PySSLObject *self)
+{
+	int count = 0;
+
+	PySSL_BEGIN_ALLOW_THREADS
+	count = SSL_pending(self->ssl);
+	PySSL_END_ALLOW_THREADS
+	if (count < 0)
+		return PySSL_SetError(self, count, __FILE__, __LINE__);
+	else
+		return PyInt_FromLong(count);
+}
+
+PyDoc_STRVAR(PySSL_SSLpending_doc,
+"pending() -> count\n\
+\n\
+Returns the number of already decrypted bytes available for read,\n\
+pending on the connection.\n");
+
 static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
 {
-	PyObject *buf;
-	int count = 0;
+	PyObject *buf = NULL;
+	int buf_passed = 0;
+	int count = -1;
 	int len = 1024;
 	int sockstate;
 	int err;
+        int nonblocking;
 
-	if (!PyArg_ParseTuple(args, "|i:read", &len))
+	if (!PyArg_ParseTuple(args, "|Oi:read", &buf, &count))
 		return NULL;
 
-	if (!(buf = PyBytes_FromStringAndSize((char *) 0, len)))
-		return NULL;
+        if ((buf == NULL) || (buf == Py_None)) {
+		if (!(buf = PyBytes_FromStringAndSize((char *) 0, len)))
+			return NULL;
+        } else if (PyInt_Check(buf)) {
+		len = PyInt_AS_LONG(buf);
+		if (!(buf = PyBytes_FromStringAndSize((char *) 0, len)))
+			return NULL;
+	} else {
+		if (!PyBytes_Check(buf))
+			return NULL;
+		len = PyBytes_Size(buf);
+		if ((count > 0) && (count <= len))
+			len = count;
+		buf_passed = 1;
+	}
+
+        /* just in case the blocking state of the socket has been changed */
+	nonblocking = (self->Socket->sock_timeout >= 0.0);
+        BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);
+        BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);
 
 	/* first check if there are bytes ready to be read */
 	PySSL_BEGIN_ALLOW_THREADS
@@ -1224,27 +1268,38 @@
 		if (sockstate == SOCKET_HAS_TIMED_OUT) {
 			PyErr_SetString(PySSLErrorObject,
 					"The read operation timed out");
-			Py_DECREF(buf);
+			if (!buf_passed) {
+				Py_DECREF(buf);
+			}
 			return NULL;
 		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
 			PyErr_SetString(PySSLErrorObject,
 				"Underlying socket too large for select().");
+			if (!buf_passed) {
+				Py_DECREF(buf);
+			}
 			Py_DECREF(buf);
 			return NULL;
 		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
 			/* should contain a zero-length string */
-			_PyString_Resize(&buf, 0);
-			return buf;
+			if (!buf_passed) {
+				PyBytes_Resize(buf, 0);
+				return buf;
+			} else {
+				return PyInt_FromLong(0);
+			}
 		}
 	}
 	do {
 		err = 0;
 		PySSL_BEGIN_ALLOW_THREADS
-		count = SSL_read(self->ssl, PyBytes_AS_STRING(buf), len);
+		count = SSL_read(self->ssl, PyBytes_AsString(buf), len);
 		err = SSL_get_error(self->ssl, count);
 		PySSL_END_ALLOW_THREADS
 		if(PyErr_CheckSignals()) {
-			Py_DECREF(buf);
+			if (!buf_passed) {
+				Py_DECREF(buf);
+			}
 			return NULL;
 		}
 		if (err == SSL_ERROR_WANT_READ) {
@@ -1257,44 +1312,55 @@
 			   (SSL_get_shutdown(self->ssl) ==
 			    SSL_RECEIVED_SHUTDOWN))
 		{
-			_PyString_Resize(&buf, 0);
-			return buf;
+			if (!buf_passed) {
+				PyBytes_Resize(buf, 0);
+				return buf;
+			} else {
+				return PyInt_FromLong(0);
+			}
 		} else {
 			sockstate = SOCKET_OPERATION_OK;
 		}
 		if (sockstate == SOCKET_HAS_TIMED_OUT) {
 			PyErr_SetString(PySSLErrorObject,
 					"The read operation timed out");
-			Py_DECREF(buf);
+			if (!buf_passed) {
+				Py_DECREF(buf);
+			}
 			return NULL;
 		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
 			break;
 		}
 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
 	if (count <= 0) {
-		Py_DECREF(buf);
+		if (!buf_passed) {
+			Py_DECREF(buf);
+		}
 		return PySSL_SetError(self, count, __FILE__, __LINE__);
 	}
-	if (count != len)
-		if (PyBytes_Resize(buf, count) < 0) {
-                        Py_DECREF(buf);
-                        return NULL;
-                }
-	return buf;
+	if (!buf_passed) {
+		if (count != len) {
+			PyBytes_Resize(buf, count);
+		}
+		return buf;
+	} else {
+		return PyInt_FromLong(count);
+	}
 }
 
 PyDoc_STRVAR(PySSL_SSLread_doc,
-"read([len]) -> bytes\n\
+"read([len]) -> string\n\
 \n\
 Read up to len bytes from the SSL socket.");
 
 static PyMethodDef PySSLMethods[] = {
+	{"do_handshake", (PyCFunction)PySSL_SSLdo_handshake, METH_NOARGS},
 	{"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
 	 PySSL_SSLwrite_doc},
 	{"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
 	 PySSL_SSLread_doc},
-	{"server", (PyCFunction)PySSL_server, METH_NOARGS},
-	{"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
+	{"pending", (PyCFunction)PySSL_SSLpending, METH_NOARGS,
+	 PySSL_SSLpending_doc},
 	{"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS,
 	 PySSL_peercert_doc},
 	{"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS},
@@ -1350,26 +1416,26 @@
 static PyObject *
 PySSL_RAND_status(PyObject *self)
 {
-    return PyBool_FromLong(RAND_status());
+    return PyInt_FromLong(RAND_status());
 }
 
 PyDoc_STRVAR(PySSL_RAND_status_doc,
 "RAND_status() -> 0 or 1\n\
 \n\
-Returns True if the OpenSSL PRNG has been seeded with enough data and\n\
-False if not.  It is necessary to seed the PRNG with RAND_add()\n\
-on some platforms before using the ssl() function.");
+Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\
+It is necessary to seed the PRNG with RAND_add() on some platforms before\n\
+using the ssl() function.");
 
 static PyObject *
 PySSL_RAND_egd(PyObject *self, PyObject *arg)
 {
     int bytes;
 
-    if (!PyString_Check(arg))
+    if (!PyUnicode_Check(arg))
 	return PyErr_Format(PyExc_TypeError,
 			    "RAND_egd() expected string, found %s",
 			    Py_Type(arg)->tp_name);
-    bytes = RAND_egd(PyString_AS_STRING(arg));
+    bytes = RAND_egd(PyUnicode_AsString(arg));
     if (bytes == -1) {
 	PyErr_SetString(PySSLErrorObject,
 			"EGD connection failed or EGD did not return "
@@ -1418,16 +1484,17 @@
 	return PyThread_get_thread_ident();
 }
 
-static void _ssl_thread_locking_function (int mode, int n, const char *file, int line) {
+static void _ssl_thread_locking_function
+        (int mode, int n, const char *file, int line) {
 	/* this function is needed to perform locking on shared data
 	   structures. (Note that OpenSSL uses a number of global data
-	   structures that will be implicitly shared whenever multiple threads
-	   use OpenSSL.) Multi-threaded applications will crash at random if
-	   it is not set.
+	   structures that will be implicitly shared whenever multiple
+	   threads use OpenSSL.) Multi-threaded applications will
+	   crash at random if it is not set.
 
-	   locking_function() must be able to handle up to CRYPTO_num_locks()
-	   different mutex locks. It sets the n-th lock if mode & CRYPTO_LOCK, and
-	   releases it otherwise.
+	   locking_function() must be able to handle up to
+	   CRYPTO_num_locks() different mutex locks. It sets the n-th
+	   lock if mode & CRYPTO_LOCK, and releases it otherwise.
 
 	   file and line are the file number of the function setting the
 	   lock. They can be useful for debugging.
@@ -1454,7 +1521,8 @@
 			malloc(sizeof(PyThread_type_lock) * _ssl_locks_count);
 		if (_ssl_locks == NULL)
 			return 0;
-		memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count);
+		memset(_ssl_locks, 0,
+                       sizeof(PyThread_type_lock) * _ssl_locks_count);
 		for (i = 0;  i < _ssl_locks_count;  i++) {
 			_ssl_locks[i] = PyThread_allocate_lock();
 			if (_ssl_locks[i] == NULL) {