@@ -76,8 +76,9 @@ typedef struct {
7676#ifndef WITH_DECIMAL_CONTEXTVAR
7777 /* Key for thread state dictionary */
7878 PyObject * tls_context_key ;
79- /* Invariant: NULL or the most recently accessed thread local context */
80- struct PyDecContextObject * cached_context ;
79+ /* Invariant: NULL or a strong reference to the most recently accessed
80+ thread local context. */
81+ struct PyDecContextObject * cached_context ; /* Not borrowed */
8182#else
8283 PyObject * current_context_var ;
8384#endif
@@ -1419,12 +1420,6 @@ context_dealloc(PyDecContextObject *self)
14191420{
14201421 PyTypeObject * tp = Py_TYPE (self );
14211422 PyObject_GC_UnTrack (self );
1422- #ifndef WITH_DECIMAL_CONTEXTVAR
1423- decimal_state * state = get_module_state_by_def (Py_TYPE (self ));
1424- if (self == state -> cached_context ) {
1425- state -> cached_context = NULL ;
1426- }
1427- #endif
14281423 (void )context_clear (self );
14291424 tp -> tp_free (self );
14301425 Py_DECREF (tp );
@@ -1701,7 +1696,8 @@ current_context_from_dict(decimal_state *modstate)
17011696
17021697 /* Cache the context of the current thread, assuming that it
17031698 * will be accessed several times before a thread switch. */
1704- modstate -> cached_context = (PyDecContextObject * )tl_context ;
1699+ Py_XSETREF (modstate -> cached_context ,
1700+ (PyDecContextObject * )Py_NewRef (tl_context ));
17051701 modstate -> cached_context -> tstate = tstate ;
17061702
17071703 /* Borrowed reference with refcount==1 */
@@ -1769,7 +1765,7 @@ PyDec_SetCurrentContext(PyObject *self, PyObject *v)
17691765 Py_INCREF (v );
17701766 }
17711767
1772- state -> cached_context = NULL ;
1768+ Py_CLEAR ( state -> cached_context ) ;
17731769 if (PyDict_SetItem (dict , state -> tls_context_key , v ) < 0 ) {
17741770 Py_DECREF (v );
17751771 return NULL ;
@@ -6122,6 +6118,16 @@ decimal_traverse(PyObject *module, visitproc visit, void *arg)
61226118 Py_VISIT (state -> Rational );
61236119 Py_VISIT (state -> SignalTuple );
61246120
6121+ if (state -> signal_map != NULL ) {
6122+ for (DecCondMap * cm = state -> signal_map ; cm -> name != NULL ; cm ++ ) {
6123+ Py_VISIT (cm -> ex );
6124+ }
6125+ }
6126+ if (state -> cond_map != NULL ) {
6127+ for (DecCondMap * cm = state -> cond_map + 1 ; cm -> name != NULL ; cm ++ ) {
6128+ Py_VISIT (cm -> ex );
6129+ }
6130+ }
61256131 return 0 ;
61266132}
61276133
0 commit comments