diff options
author | Tomas R <tomas.roun8@gmail.com> | 2023-11-15 23:53:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-15 23:53:38 (GMT) |
commit | a6465605c1417792ec04ced88340cdf104a402b6 (patch) | |
tree | b2e37deeaf10018fe0273052e561d265c9fb498e /Modules/md5module.c | |
parent | 7218bac8c84115a8e9a18a4a8f3146235068facb (diff) | |
download | cpython-a6465605c1417792ec04ced88340cdf104a402b6.zip cpython-a6465605c1417792ec04ced88340cdf104a402b6.tar.gz cpython-a6465605c1417792ec04ced88340cdf104a402b6.tar.bz2 |
gh-111916: Make hashlib related modules thread-safe without the GIL (#111981)
Always use an individual lock on hash objects when in free-threaded builds.
Fixes #111916
Diffstat (limited to 'Modules/md5module.c')
-rw-r--r-- | Modules/md5module.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/Modules/md5module.c b/Modules/md5module.c index 7883a8c..7d2b327 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -16,13 +16,8 @@ /* MD5 objects */ -#ifndef _MSC_VER -#include "pyconfig.h" // Py_NOGIL -#endif - -#ifndef Py_NOGIL -// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED -#define Py_LIMITED_API 0x030c0000 +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 #endif #include "Python.h" @@ -54,8 +49,8 @@ typedef long long MD5_INT64; /* 64-bit integer */ typedef struct { PyObject_HEAD // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; Hacl_Streaming_MD5_state *hash_state; } MD5object; @@ -78,7 +73,11 @@ static MD5object * newMD5object(MD5State * st) { MD5object *md5 = (MD5object *)PyObject_GC_New(MD5object, st->md5_type); - md5->lock = NULL; + if (!md5) { + return NULL; + } + HASHLIB_INIT_MUTEX(md5); + PyObject_GC_Track(md5); return md5; } @@ -95,9 +94,6 @@ static void MD5_dealloc(MD5object *ptr) { Hacl_Streaming_MD5_legacy_free(ptr->hash_state); - if (ptr->lock != NULL) { - PyThread_free_lock(ptr->lock); - } PyTypeObject *tp = Py_TYPE((PyObject*)ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -202,14 +198,14 @@ MD5Type_update(MD5object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); update(self->hash_state, buf.buf, buf.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { update(self->hash_state, buf.buf, buf.len); |