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/sha1module.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/sha1module.c')
-rw-r--r-- | Modules/sha1module.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 3fd5312..eda6b56 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -49,7 +49,8 @@ typedef long long SHA1_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. + bool use_mutex; + PyMutex mutex; PyThread_type_lock lock; Hacl_Streaming_SHA1_state *hash_state; } SHA1object; @@ -76,7 +77,8 @@ newSHA1object(SHA1State *st) if (sha == NULL) { return NULL; } - sha->lock = NULL; + HASHLIB_INIT_MUTEX(sha); + PyObject_GC_Track(sha); return sha; } @@ -94,9 +96,6 @@ static void SHA1_dealloc(SHA1object *ptr) { Hacl_Streaming_SHA1_legacy_free(ptr->hash_state); - if (ptr->lock != NULL) { - PyThread_free_lock(ptr->lock); - } PyTypeObject *tp = Py_TYPE(ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -192,14 +191,14 @@ SHA1Type_update(SHA1object *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); |