return 0;
}
+static int
+sslmodule_init_lock(PyObject *module)
+{
+ _sslmodulestate *state = get_ssl_state(module);
+ state->keylog_lock = PyThread_allocate_lock();
+ if (state->keylog_lock == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ return 0;
+}
+
static PyModuleDef_Slot sslmodule_slots[] = {
{Py_mod_exec, sslmodule_init_types},
{Py_mod_exec, sslmodule_init_exceptions},
{Py_mod_exec, sslmodule_init_constants},
{Py_mod_exec, sslmodule_init_versioninfo},
{Py_mod_exec, sslmodule_init_strings},
- // XXX gh-103092: fix isolation.
- {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
- //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+ {Py_mod_exec, sslmodule_init_lock},
+ {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
{0, NULL}
};
sslmodule_free(void *m)
{
sslmodule_clear((PyObject *)m);
+ _sslmodulestate *state = get_ssl_state(m);
+ PyThread_free_lock(state->keylog_lock);
}
static struct PyModuleDef _sslmodule_def = {
PyGILState_STATE threadstate;
PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */
int res, e;
- static PyThread_type_lock *lock = NULL;
threadstate = PyGILState_Ensure();
ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl);
assert(Py_IS_TYPE(ssl_obj, get_state_sock(ssl_obj)->PySSLSocket_Type));
+ PyThread_type_lock lock = get_state_sock(ssl_obj)->keylog_lock;
+ assert(lock != NULL);
if (ssl_obj->ctx->keylog_bio == NULL) {
return;
}
-
- /* Allocate a static lock to synchronize writes to keylog file.
+ /*
* The lock is neither released on exit nor on fork(). The lock is
* also shared between all SSLContexts although contexts may write to
* their own files. IMHO that's good enough for a non-performance
* critical debug helper.
*/
- if (lock == NULL) {
- lock = PyThread_allocate_lock();
- if (lock == NULL) {
- PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
- ssl_obj->exc = PyErr_GetRaisedException();
- return;
- }
- }
PySSL_BEGIN_ALLOW_THREADS
PyThread_acquire_lock(lock, 1);