Skip to content

Commit 63db1de

Browse files
committed
correct mutex usage
1 parent 5cd828a commit 63db1de

2 files changed

Lines changed: 45 additions & 29 deletions

File tree

Modules/hashlib.h

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,33 +50,42 @@
5050

5151
#include "pythread.h"
5252

53-
#define HASHLIB_OBJECT_HEAD \
54-
PyObject_HEAD \
55-
/* prevent undefined behavior via multiple
56-
* threads entering the C API */ \
57-
bool use_mutex; \
53+
#define HASHLIB_LOCK_HEAD \
54+
/*
55+
* Attributes to prevent undefined behaviors
56+
* via multiple threads entering the C API.
57+
*/ \
58+
bool use_mutex; \
5859
PyMutex mutex;
5960

60-
#define ENTER_HASHLIB(obj) \
61-
if ((obj)->use_mutex) { \
62-
PyMutex_Lock(&(obj)->mutex); \
63-
}
64-
#define LEAVE_HASHLIB(obj) \
65-
if ((obj)->use_mutex) { \
66-
PyMutex_Unlock(&(obj)->mutex); \
67-
}
61+
#define HASHLIB_SET_MUTEX_POLICY(OBJ, VALUE) \
62+
_Py_atomic_store_int_relaxed((int *)&(OBJ)->use_mutex, (int)(VALUE))
63+
64+
#define ENTER_HASHLIB(OBJ) \
65+
do { \
66+
if (_Py_atomic_load_int_relaxed((const int *)&(OBJ)->use_mutex)) { \
67+
PyMutex_Lock(&(OBJ)->mutex); \
68+
} \
69+
} while (0)
70+
71+
#define LEAVE_HASHLIB(OBJ) \
72+
do { \
73+
if (_Py_atomic_load_int_relaxed((const int *)&(OBJ)->use_mutex)) { \
74+
PyMutex_Unlock(&(OBJ)->mutex); \
75+
} \
76+
} while (0)
6877

6978
#ifdef Py_GIL_DISABLED
70-
#define HASHLIB_INIT_MUTEX(obj) \
71-
do { \
72-
(obj)->mutex = (PyMutex){0}; \
73-
(obj)->use_mutex = true; \
79+
#define HASHLIB_INIT_MUTEX(OBJ) \
80+
do { \
81+
(OBJ)->mutex = (PyMutex){0}; \
82+
(OBJ)->use_mutex = true; \
7483
} while (0)
7584
#else
76-
#define HASHLIB_INIT_MUTEX(obj) \
77-
do { \
78-
(obj)->mutex = (PyMutex){0}; \
79-
(obj)->use_mutex = false; \
85+
#define HASHLIB_INIT_MUTEX(OBJ) \
86+
do { \
87+
(OBJ)->mutex = (PyMutex){0}; \
88+
(OBJ)->use_mutex = false; \
8089
} while (0)
8190
#endif
8291

Modules/md5module.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
#include "_hacl/Hacl_Hash_MD5.h"
3333

3434
typedef struct {
35-
HASHLIB_OBJECT_HEAD
35+
PyObject_HEAD
36+
HASHLIB_LOCK_HEAD
3637
Hacl_Hash_MD5_state_t *state;
3738
} MD5object;
3839

@@ -181,7 +182,7 @@ static void
181182
md5_update_state_with_lock(MD5object *self, uint8_t *buf, Py_ssize_t len)
182183
{
183184
Py_BEGIN_ALLOW_THREADS
184-
PyMutex_Lock(&self->mutex); // unconditionally acquire a lock
185+
PyMutex_Lock(&self->mutex); // unconditionally acquire a lock
185186
_hacl_md5_update(self->state, buf, len);
186187
PyMutex_Unlock(&self->mutex);
187188
Py_END_ALLOW_THREADS
@@ -190,7 +191,7 @@ md5_update_state_with_lock(MD5object *self, uint8_t *buf, Py_ssize_t len)
190191
static void
191192
md5_update_state_cond_lock(MD5object *self, uint8_t *buf, Py_ssize_t len)
192193
{
193-
ENTER_HASHLIB(self); // conditionally acquire a lock
194+
ENTER_HASHLIB(self); // conditionally acquire a lock
194195
_hacl_md5_update(self->state, buf, len);
195196
LEAVE_HASHLIB(self);
196197
}
@@ -200,10 +201,16 @@ md5_update_state(MD5object *self, uint8_t *buf, Py_ssize_t len)
200201
{
201202
assert(buf != 0);
202203
assert(len >= 0);
203-
if (len != 0) {
204-
len < HASHLIB_GIL_MINSIZE
205-
? md5_update_state_cond_lock(self, buf, len)
206-
: md5_update_state_with_lock(self, buf, len);
204+
if (len == 0) {
205+
return;
206+
}
207+
if (len < HASHLIB_GIL_MINSIZE) {
208+
md5_update_state_cond_lock(self, buf, len);
209+
}
210+
else {
211+
HASHLIB_SET_MUTEX_POLICY(self, 1);
212+
md5_update_state_with_lock(self, buf, len);
213+
HASHLIB_SET_MUTEX_POLICY(self, 0);
207214
}
208215
}
209216

@@ -316,7 +323,7 @@ _md5_md5_impl(PyObject *module, PyObject *data, int usedforsecurity,
316323
Py_buffer buf;
317324
GET_BUFFER_VIEW_OR_ERROR(string, &buf, goto error);
318325
if (buf.len >= HASHLIB_GIL_MINSIZE) {
319-
/* We do not initialize self->lock here as this is the constructor
326+
/* Do not use self->mutex here as this is the constructor
320327
* where it is not yet possible to have concurrent access. */
321328
Py_BEGIN_ALLOW_THREADS
322329
_hacl_md5_update(self->state, buf.buf, buf.len);

0 commit comments

Comments
 (0)