@@ -266,7 +266,7 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
266266 int ret ;
267267 int verification_mode ;
268268
269- self = PyObject_New (PySSLObject , & PySSL_Type ); /* Create new object */
269+ self = PyObject_GC_New (PySSLObject , & PySSL_Type ); /* Create new object */
270270 if (self == NULL )
271271 return NULL ;
272272 self -> peer_cert = NULL ;
@@ -385,6 +385,7 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
385385
386386 self -> Socket = Sock ;
387387 Py_INCREF (self -> Socket );
388+ _PyObject_GC_TRACK (self );
388389 return self ;
389390 fail :
390391 if (errstr )
@@ -1050,16 +1051,41 @@ static PyObject *PySSL_cipher (PySSLObject *self) {
10501051 return NULL ;
10511052}
10521053
1053- static void PySSL_dealloc (PySSLObject * self )
1054+ /* GC support. */
1055+ static int
1056+ PySSL_traverse (PySSLObject * self , visitproc visit , void * arg )
1057+ {
1058+ Py_VISIT (self -> Socket );
1059+ return 0 ;
1060+ }
1061+
1062+ static int
1063+ PySSL_clear (PySSLObject * self )
1064+ {
1065+ Py_CLEAR (self -> Socket );
1066+ return 0 ;
1067+ }
1068+
1069+ static void
1070+ PySSL_dealloc (PySSLObject * self )
10541071{
1072+ PyObject * o ;
1073+ PyObject * exc_type , * exc_value , * exc_tb ;
1074+
1075+ PyErr_Fetch (& exc_type , & exc_value , & exc_tb );
1076+ o = PyObject_CallMethod ((PyObject * )self , "_real_close" , NULL );
1077+ Py_XDECREF (o );
1078+ PyErr_Restore (exc_type , exc_value , exc_tb );
1079+
1080+ PyObject_GC_UnTrack (self );
10551081 if (self -> peer_cert ) /* Possible not to have one? */
1056- X509_free (self -> peer_cert );
1082+ X509_free (self -> peer_cert );
10571083 if (self -> ssl )
10581084 SSL_free (self -> ssl );
10591085 if (self -> ctx )
10601086 SSL_CTX_free (self -> ctx );
1061- Py_XDECREF (self -> Socket );
1062- PyObject_Del ( self );
1087+ Py_CLEAR (self -> Socket );
1088+ Py_Type ( self ) -> tp_free (( PyObject * ) self );
10631089}
10641090
10651091/* If the socket has a timeout, do a select()/poll() on the socket.
@@ -1359,27 +1385,48 @@ static PyMethodDef PySSLMethods[] = {
13591385 {NULL , NULL }
13601386};
13611387
1362- static PyObject * PySSL_getattr (PySSLObject * self , char * name )
1363- {
1364- return Py_FindMethod (PySSLMethods , (PyObject * )self , name );
1365- }
1366-
13671388static PyTypeObject PySSL_Type = {
13681389 PyVarObject_HEAD_INIT (NULL , 0 )
1369- "ssl .SSLContext" , /*tp_name*/
1390+ "_ssl .SSLContext" , /*tp_name*/
13701391 sizeof (PySSLObject ), /*tp_basicsize*/
13711392 0 , /*tp_itemsize*/
13721393 /* methods */
13731394 (destructor )PySSL_dealloc , /*tp_dealloc*/
13741395 0 , /*tp_print*/
1375- ( getattrfunc ) PySSL_getattr , /*tp_getattr*/
1396+ 0 , /*tp_getattr*/
13761397 0 , /*tp_setattr*/
13771398 0 , /*tp_compare*/
13781399 0 , /*tp_repr*/
13791400 0 , /*tp_as_number*/
13801401 0 , /*tp_as_sequence*/
13811402 0 , /*tp_as_mapping*/
13821403 0 , /*tp_hash*/
1404+ 0 , /* tp_call */
1405+ 0 , /* tp_str */
1406+ PyObject_GenericGetAttr , /* tp_getattro */
1407+ 0 , /* tp_setattro */
1408+ 0 , /* tp_as_buffer */
1409+ Py_TPFLAGS_DEFAULT |
1410+ Py_TPFLAGS_HAVE_GC , /* tp_flags */
1411+ 0 , /* tp_doc */
1412+ (traverseproc )PySSL_traverse , /* tp_traverse */
1413+ (inquiry )PySSL_clear , /* tp_clear */
1414+ 0 , /* tp_richcompare */
1415+ 0 , /* tp_weaklistoffset */
1416+ 0 , /* tp_iter */
1417+ 0 , /* tp_iternext */
1418+ PySSLMethods , /* tp_methods */
1419+ 0 , /* tp_members */
1420+ 0 , /* tp_getset */
1421+ 0 , /* tp_base */
1422+ 0 , /* tp_dict */
1423+ 0 , /* tp_descr_get */
1424+ 0 , /* tp_descr_set */
1425+ 0 , /* tp_dictoffset */
1426+ 0 , /* tp_init */
1427+ PyType_GenericAlloc , /* tp_alloc */
1428+ PyType_GenericNew , /* tp_new */
1429+ PyObject_GC_Del , /* tp_free */
13831430};
13841431
13851432#ifdef HAVE_OPENSSL_RAND
0 commit comments