mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
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
This commit is contained in:
parent
7218bac8c8
commit
a6465605c1
10 changed files with 188 additions and 137 deletions
|
@ -53,8 +53,8 @@ typedef struct {
|
|||
PyObject_HEAD
|
||||
int digestsize;
|
||||
// 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_SHA2_state_sha2_256 *state;
|
||||
} SHA256object;
|
||||
|
||||
|
@ -62,8 +62,8 @@ typedef struct {
|
|||
PyObject_HEAD
|
||||
int digestsize;
|
||||
// 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_SHA2_state_sha2_512 *state;
|
||||
} SHA512object;
|
||||
|
||||
|
@ -106,7 +106,8 @@ newSHA224object(sha2_state *state)
|
|||
if (!sha) {
|
||||
return NULL;
|
||||
}
|
||||
sha->lock = NULL;
|
||||
HASHLIB_INIT_MUTEX(sha);
|
||||
|
||||
PyObject_GC_Track(sha);
|
||||
return sha;
|
||||
}
|
||||
|
@ -119,7 +120,8 @@ newSHA256object(sha2_state *state)
|
|||
if (!sha) {
|
||||
return NULL;
|
||||
}
|
||||
sha->lock = NULL;
|
||||
HASHLIB_INIT_MUTEX(sha);
|
||||
|
||||
PyObject_GC_Track(sha);
|
||||
return sha;
|
||||
}
|
||||
|
@ -132,7 +134,8 @@ newSHA384object(sha2_state *state)
|
|||
if (!sha) {
|
||||
return NULL;
|
||||
}
|
||||
sha->lock = NULL;
|
||||
HASHLIB_INIT_MUTEX(sha);
|
||||
|
||||
PyObject_GC_Track(sha);
|
||||
return sha;
|
||||
}
|
||||
|
@ -145,7 +148,8 @@ newSHA512object(sha2_state *state)
|
|||
if (!sha) {
|
||||
return NULL;
|
||||
}
|
||||
sha->lock = NULL;
|
||||
HASHLIB_INIT_MUTEX(sha);
|
||||
|
||||
PyObject_GC_Track(sha);
|
||||
return sha;
|
||||
}
|
||||
|
@ -163,9 +167,6 @@ static void
|
|||
SHA256_dealloc(SHA256object *ptr)
|
||||
{
|
||||
Hacl_Streaming_SHA2_free_256(ptr->state);
|
||||
if (ptr->lock != NULL) {
|
||||
PyThread_free_lock(ptr->lock);
|
||||
}
|
||||
PyTypeObject *tp = Py_TYPE(ptr);
|
||||
PyObject_GC_UnTrack(ptr);
|
||||
PyObject_GC_Del(ptr);
|
||||
|
@ -176,9 +177,6 @@ static void
|
|||
SHA512_dealloc(SHA512object *ptr)
|
||||
{
|
||||
Hacl_Streaming_SHA2_free_512(ptr->state);
|
||||
if (ptr->lock != NULL) {
|
||||
PyThread_free_lock(ptr->lock);
|
||||
}
|
||||
PyTypeObject *tp = Py_TYPE(ptr);
|
||||
PyObject_GC_UnTrack(ptr);
|
||||
PyObject_GC_Del(ptr);
|
||||
|
@ -376,14 +374,14 @@ SHA256Type_update(SHA256object *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_256(self->state, buf.buf, buf.len);
|
||||
PyThread_release_lock(self->lock);
|
||||
PyMutex_Unlock(&self->mutex);
|
||||
Py_END_ALLOW_THREADS
|
||||
} else {
|
||||
update_256(self->state, buf.buf, buf.len);
|
||||
|
@ -410,14 +408,14 @@ SHA512Type_update(SHA512object *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_512(self->state, buf.buf, buf.len);
|
||||
PyThread_release_lock(self->lock);
|
||||
PyMutex_Unlock(&self->mutex);
|
||||
Py_END_ALLOW_THREADS
|
||||
} else {
|
||||
update_512(self->state, buf.buf, buf.len);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue