Skip to content

Commit 5676be4

Browse files
committed
add guard for free threading
1 parent 012b81f commit 5676be4

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
Fix a data race in :class:`decimal.Context` status flag updates in the
2-
:term:`free-threaded build`.
1+
Fix data races in :meth:`decimal.Context.create_decimal` and
2+
:meth:`decimal.Context.clear_flags` when updating
3+
:class:`decimal.Context` status flags in the :term:`free-threaded build`.

Modules/_decimal/_decimal.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,9 @@ typedef struct {
218218

219219
typedef struct PyDecContextObject {
220220
PyObject_HEAD
221+
#ifdef Py_GIL_DISABLED
221222
PyMutex ctx_lock;
223+
#endif
222224
mpd_context_t ctx;
223225
PyObject *traps;
224226
PyObject *flags;
@@ -247,10 +249,17 @@ typedef struct {
247249
#define SdFlagAddr(v) (_PyDecSignalDictObject_CAST(v)->flags)
248250
#define SdFlags(v) (*_PyDecSignalDictObject_CAST(v)->flags)
249251
#define CTX(v) (&_PyDecContextObject_CAST(v)->ctx)
252+
#define CtxCaps(v) (_PyDecContextObject_CAST(v)->capitals)
253+
254+
#ifdef Py_GIL_DISABLED
250255
#define CTX_LOCK_INIT(v) _PyDecContextObject_CAST(v)->ctx_lock = (PyMutex){0}
251256
#define CTX_LOCK(v) PyMutex_Lock(&_PyDecContextObject_CAST(v)->ctx_lock)
252257
#define CTX_UNLOCK(v) PyMutex_Unlock(&_PyDecContextObject_CAST(v)->ctx_lock)
253-
#define CtxCaps(v) (_PyDecContextObject_CAST(v)->capitals)
258+
#else
259+
#define CTX_LOCK_INIT(v) ((void)0)
260+
#define CTX_LOCK(v) ((void)0)
261+
#define CTX_UNLOCK(v) ((void)0)
262+
#endif
254263

255264
static inline decimal_state *
256265
get_module_state_from_ctx(PyObject *v)
@@ -1457,7 +1466,7 @@ context_new(PyTypeObject *type,
14571466
if (self == NULL) {
14581467
return NULL;
14591468
}
1460-
self->ctx_lock = (PyMutex){0};
1469+
CTX_LOCK_INIT(self);
14611470

14621471
self->traps = PyObject_CallObject((PyObject *)state->PyDecSignalDict_Type, NULL);
14631472
if (self->traps == NULL) {

0 commit comments

Comments
 (0)