39
39
40
40
#include "docstrings.h"
41
41
42
+ struct PyDecContextObject ;
43
+
42
44
typedef struct {
43
45
PyTypeObject * PyDecContextManager_Type ;
44
46
PyTypeObject * PyDecContext_Type ;
@@ -50,6 +52,15 @@ typedef struct {
50
52
/* Top level Exception; inherits from ArithmeticError */
51
53
PyObject * DecimalException ;
52
54
55
+ #ifndef WITH_DECIMAL_CONTEXTVAR
56
+ /* Key for thread state dictionary */
57
+ PyObject * tls_context_key ;
58
+ /* Invariant: NULL or the most recently accessed thread local context */
59
+ struct PyDecContextObject * cached_context ;
60
+ #else
61
+ PyObject * current_context_var ;
62
+ #endif
63
+
53
64
/* Template for creating new thread contexts, calling Context() without
54
65
* arguments and initializing the module_context on first access. */
55
66
PyObject * default_context_template ;
@@ -104,7 +115,7 @@ typedef struct {
104
115
uint32_t * flags ;
105
116
} PyDecSignalDictObject ;
106
117
107
- typedef struct {
118
+ typedef struct PyDecContextObject {
108
119
PyObject_HEAD
109
120
mpd_context_t ctx ;
110
121
PyObject * traps ;
@@ -119,7 +130,6 @@ typedef struct {
119
130
PyObject * global ;
120
131
} PyDecContextManagerObject ;
121
132
122
-
123
133
#undef MPD
124
134
#undef CTX
125
135
#define PyDec_CheckExact (st , v ) Py_IS_TYPE(v, (st)->PyDec_Type)
@@ -145,16 +155,6 @@ incr_false(void)
145
155
return Py_NewRef (Py_False );
146
156
}
147
157
148
-
149
- #ifndef WITH_DECIMAL_CONTEXTVAR
150
- /* Key for thread state dictionary */
151
- static PyObject * tls_context_key = NULL ;
152
- /* Invariant: NULL or the most recently accessed thread local context */
153
- static PyDecContextObject * cached_context = NULL ;
154
- #else
155
- static PyObject * current_context_var = NULL ;
156
- #endif
157
-
158
158
/* Error codes for functions that return signals or conditions */
159
159
#define DEC_INVALID_SIGNALS (MPD_Max_status+1U)
160
160
#define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1)
@@ -1565,7 +1565,8 @@ current_context_from_dict(void)
1565
1565
return NULL ;
1566
1566
}
1567
1567
1568
- PyObject * tl_context = PyDict_GetItemWithError (dict , tls_context_key );
1568
+ PyObject * tl_context ;
1569
+ tl_context = PyDict_GetItemWithError (dict , modstate -> tls_context_key );
1569
1570
if (tl_context != NULL ) {
1570
1571
/* We already have a thread local context. */
1571
1572
CONTEXT_CHECK (modstate , tl_context );
@@ -1576,13 +1577,13 @@ current_context_from_dict(void)
1576
1577
}
1577
1578
1578
1579
/* Set up a new thread local context. */
1579
- tl_context = context_copy (state -> default_context_template , NULL );
1580
+ tl_context = context_copy (modstate -> default_context_template , NULL );
1580
1581
if (tl_context == NULL ) {
1581
1582
return NULL ;
1582
1583
}
1583
1584
CTX (tl_context )-> status = 0 ;
1584
1585
1585
- if (PyDict_SetItem (dict , tls_context_key , tl_context ) < 0 ) {
1586
+ if (PyDict_SetItem (dict , modstate -> tls_context_key , tl_context ) < 0 ) {
1586
1587
Py_DECREF (tl_context );
1587
1588
return NULL ;
1588
1589
}
@@ -1591,8 +1592,8 @@ current_context_from_dict(void)
1591
1592
1592
1593
/* Cache the context of the current thread, assuming that it
1593
1594
* will be accessed several times before a thread switch. */
1594
- cached_context = (PyDecContextObject * )tl_context ;
1595
- cached_context -> tstate = tstate ;
1595
+ modstate -> cached_context = (PyDecContextObject * )tl_context ;
1596
+ modstate -> cached_context -> tstate = tstate ;
1596
1597
1597
1598
/* Borrowed reference with refcount==1 */
1598
1599
return tl_context ;
@@ -1603,8 +1604,9 @@ static PyObject *
1603
1604
current_context (void )
1604
1605
{
1605
1606
PyThreadState * tstate = _PyThreadState_GET ();
1606
- if (cached_context && cached_context -> tstate == tstate ) {
1607
- return (PyObject * )cached_context ;
1607
+ decimal_state * modstate = GLOBAL_STATE ();
1608
+ if (modstate -> cached_context && modstate -> cached_context -> tstate == tstate ) {
1609
+ return (PyObject * )(modstate -> cached_context );
1608
1610
}
1609
1611
1610
1612
return current_context_from_dict ();
@@ -1662,8 +1664,8 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1662
1664
Py_INCREF (v );
1663
1665
}
1664
1666
1665
- cached_context = NULL ;
1666
- if (PyDict_SetItem (dict , tls_context_key , v ) < 0 ) {
1667
+ state -> cached_context = NULL ;
1668
+ if (PyDict_SetItem (dict , state -> tls_context_key , v ) < 0 ) {
1667
1669
Py_DECREF (v );
1668
1670
return NULL ;
1669
1671
}
@@ -1682,7 +1684,7 @@ init_current_context(void)
1682
1684
}
1683
1685
CTX (tl_context )-> status = 0 ;
1684
1686
1685
- PyObject * tok = PyContextVar_Set (current_context_var , tl_context );
1687
+ PyObject * tok = PyContextVar_Set (state -> current_context_var , tl_context );
1686
1688
if (tok == NULL ) {
1687
1689
Py_DECREF (tl_context );
1688
1690
return NULL ;
@@ -1696,7 +1698,8 @@ static inline PyObject *
1696
1698
current_context (void )
1697
1699
{
1698
1700
PyObject * tl_context ;
1699
- if (PyContextVar_Get (current_context_var , NULL , & tl_context ) < 0 ) {
1701
+ decimal_state * state = GLOBAL_STATE ();
1702
+ if (PyContextVar_Get (state -> current_context_var , NULL , & tl_context ) < 0 ) {
1700
1703
return NULL ;
1701
1704
}
1702
1705
@@ -1744,7 +1747,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1744
1747
Py_INCREF (v );
1745
1748
}
1746
1749
1747
- PyObject * tok = PyContextVar_Set (current_context_var , v );
1750
+ PyObject * tok = PyContextVar_Set (state -> current_context_var , v );
1748
1751
Py_DECREF (v );
1749
1752
if (tok == NULL ) {
1750
1753
return NULL ;
@@ -5987,10 +5990,11 @@ PyInit__decimal(void)
5987
5990
Py_NewRef (state -> default_context_template )));
5988
5991
5989
5992
#ifndef WITH_DECIMAL_CONTEXTVAR
5990
- ASSIGN_PTR (tls_context_key , PyUnicode_FromString ("___DECIMAL_CTX__" ));
5993
+ ASSIGN_PTR (state -> tls_context_key ,
5994
+ PyUnicode_FromString ("___DECIMAL_CTX__" ));
5991
5995
CHECK_INT (PyModule_AddObject (m , "HAVE_CONTEXTVAR" , Py_NewRef (Py_False )));
5992
5996
#else
5993
- ASSIGN_PTR (current_context_var , PyContextVar_New ("decimal_context" , NULL ));
5997
+ ASSIGN_PTR (state -> current_context_var , PyContextVar_New ("decimal_context" , NULL ));
5994
5998
CHECK_INT (PyModule_AddObject (m , "HAVE_CONTEXTVAR" , Py_NewRef (Py_True )));
5995
5999
#endif
5996
6000
CHECK_INT (PyModule_AddObject (m , "HAVE_THREADS" , Py_NewRef (Py_True )));
@@ -6049,9 +6053,9 @@ PyInit__decimal(void)
6049
6053
Py_CLEAR (state -> DecimalTuple ); /* GCOV_NOT_REACHED */
6050
6054
Py_CLEAR (state -> default_context_template ); /* GCOV_NOT_REACHED */
6051
6055
#ifndef WITH_DECIMAL_CONTEXTVAR
6052
- Py_CLEAR (tls_context_key ); /* GCOV_NOT_REACHED */
6056
+ Py_CLEAR (state -> tls_context_key ); /* GCOV_NOT_REACHED */
6053
6057
#else
6054
- Py_CLEAR (current_context_var ); /* GCOV_NOT_REACHED */
6058
+ Py_CLEAR (state -> current_context_var ); /* GCOV_NOT_REACHED */
6055
6059
#endif
6056
6060
Py_CLEAR (state -> basic_context_template ); /* GCOV_NOT_REACHED */
6057
6061
Py_CLEAR (state -> extended_context_template ); /* GCOV_NOT_REACHED */
0 commit comments