summaryrefslogtreecommitdiffstats
path: root/Modules/sha1module.c
diff options
context:
space:
mode:
authorTomas R <tomas.roun8@gmail.com>2023-11-15 23:53:38 (GMT)
committerGitHub <noreply@github.com>2023-11-15 23:53:38 (GMT)
commita6465605c1417792ec04ced88340cdf104a402b6 (patch)
treeb2e37deeaf10018fe0273052e561d265c9fb498e /Modules/sha1module.c
parent7218bac8c84115a8e9a18a4a8f3146235068facb (diff)
downloadcpython-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.c19
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);