@@ -100,9 +100,6 @@ typedef struct {
100
100
_ttinfo NO_TTINFO ;
101
101
} zoneinfo_state ;
102
102
103
- // Globals
104
- static zoneinfo_state global_state ;
105
-
106
103
// Constants
107
104
static const int EPOCHORDINAL = 719163 ;
108
105
static int DAYS_IN_MONTH [] = {
@@ -194,19 +191,29 @@ static PyObject *
194
191
zone_from_strong_cache (zoneinfo_state * state , const PyTypeObject * const type ,
195
192
PyObject * const key );
196
193
197
- zoneinfo_state * zoneinfo_get_state (PyObject * mod )
194
+ static inline zoneinfo_state *
195
+ zoneinfo_get_state (PyObject * mod )
198
196
{
199
- return & global_state ;
197
+ zoneinfo_state * state = (zoneinfo_state * )PyModule_GetState (mod );
198
+ assert (state != NULL );
199
+ return state ;
200
200
}
201
201
202
- zoneinfo_state * zoneinfo_get_state_by_cls (PyTypeObject * cls )
202
+ static inline zoneinfo_state *
203
+ zoneinfo_get_state_by_cls (PyTypeObject * cls )
203
204
{
204
- return & global_state ;
205
+ zoneinfo_state * state = (zoneinfo_state * )PyType_GetModuleState (cls );
206
+ assert (state != NULL );
207
+ return state ;
205
208
}
206
209
207
- zoneinfo_state * zoneinfo_get_state_by_self (PyTypeObject * self )
210
+ static struct PyModuleDef zoneinfomodule ;
211
+ static inline zoneinfo_state *
212
+ zoneinfo_get_state_by_self (PyTypeObject * self )
208
213
{
209
- return & global_state ;
214
+ PyObject * mod = PyType_GetModuleByDef (self , & zoneinfomodule );
215
+ assert (mod != NULL );
216
+ return zoneinfo_get_state (mod );
210
217
}
211
218
212
219
static PyObject *
@@ -2732,36 +2739,57 @@ static PyType_Spec zoneinfo_spec = {
2732
2739
/////
2733
2740
// Specify the _zoneinfo module
2734
2741
static PyMethodDef module_methods [] = {{NULL , NULL }};
2735
- static void
2736
- module_free (void * m )
2737
- {
2738
- zoneinfo_state * state = zoneinfo_get_state (m );
2739
2742
2740
- Py_CLEAR (state -> io_open );
2741
- Py_CLEAR (state -> _tzpath_find_tzfile );
2742
- Py_CLEAR (state -> _common_mod );
2743
+ static int
2744
+ module_traverse (PyObject * mod , visitproc visit , void * arg )
2745
+ {
2746
+ zoneinfo_state * state = zoneinfo_get_state (mod );
2743
2747
2744
- xdecref_ttinfo (& (state -> NO_TTINFO ));
2748
+ Py_VISIT (state -> ZoneInfoType );
2749
+ Py_VISIT (state -> io_open );
2750
+ Py_VISIT (state -> _tzpath_find_tzfile );
2751
+ Py_VISIT (state -> _common_mod );
2752
+ Py_VISIT (state -> TIMEDELTA_CACHE );
2753
+ Py_VISIT (state -> ZONEINFO_WEAK_CACHE );
2745
2754
2746
- if (state -> TIMEDELTA_CACHE != NULL &&
2747
- Py_REFCNT (state -> TIMEDELTA_CACHE ) > 1 )
2748
- {
2749
- Py_DECREF (state -> TIMEDELTA_CACHE );
2750
- }
2751
- else {
2752
- Py_CLEAR (state -> TIMEDELTA_CACHE );
2755
+ StrongCacheNode * node = state -> ZONEINFO_STRONG_CACHE ;
2756
+ while (node != NULL ) {
2757
+ StrongCacheNode * next = node -> next ;
2758
+ Py_VISIT (node -> key );
2759
+ Py_VISIT (node -> zone );
2760
+ node = next ;
2753
2761
}
2754
2762
2755
- if (state -> ZONEINFO_WEAK_CACHE != NULL &&
2756
- Py_REFCNT (state -> ZONEINFO_WEAK_CACHE ) > 1 )
2757
- {
2758
- Py_DECREF (state -> ZONEINFO_WEAK_CACHE );
2759
- }
2760
- else {
2761
- Py_CLEAR (state -> ZONEINFO_WEAK_CACHE );
2762
- }
2763
+ Py_VISIT (state -> NO_TTINFO .utcoff );
2764
+ Py_VISIT (state -> NO_TTINFO .dstoff );
2765
+ Py_VISIT (state -> NO_TTINFO .tzname );
2763
2766
2767
+ return 0 ;
2768
+ }
2769
+
2770
+ static int
2771
+ module_clear (PyObject * mod )
2772
+ {
2773
+ zoneinfo_state * state = zoneinfo_get_state (mod );
2774
+
2775
+ Py_CLEAR (state -> ZoneInfoType );
2776
+ Py_CLEAR (state -> io_open );
2777
+ Py_CLEAR (state -> _tzpath_find_tzfile );
2778
+ Py_CLEAR (state -> _common_mod );
2779
+ Py_CLEAR (state -> TIMEDELTA_CACHE );
2780
+ Py_CLEAR (state -> ZONEINFO_WEAK_CACHE );
2764
2781
clear_strong_cache (state , state -> ZoneInfoType );
2782
+ Py_CLEAR (state -> NO_TTINFO .utcoff );
2783
+ Py_CLEAR (state -> NO_TTINFO .dstoff );
2784
+ Py_CLEAR (state -> NO_TTINFO .tzname );
2785
+
2786
+ return 0 ;
2787
+ }
2788
+
2789
+ static void
2790
+ module_free (void * mod )
2791
+ {
2792
+ (void )module_clear ((PyObject * )mod );
2765
2793
}
2766
2794
2767
2795
static int
@@ -2823,13 +2851,16 @@ static PyModuleDef_Slot zoneinfomodule_slots[] = {
2823
2851
{Py_mod_exec , zoneinfomodule_exec }, {0 , NULL }};
2824
2852
2825
2853
static struct PyModuleDef zoneinfomodule = {
2826
- PyModuleDef_HEAD_INIT ,
2854
+ . m_base = PyModuleDef_HEAD_INIT ,
2827
2855
.m_name = "_zoneinfo" ,
2828
2856
.m_doc = "C implementation of the zoneinfo module" ,
2829
- .m_size = 0 ,
2857
+ .m_size = sizeof ( zoneinfo_state ) ,
2830
2858
.m_methods = module_methods ,
2831
2859
.m_slots = zoneinfomodule_slots ,
2832
- .m_free = (freefunc )module_free };
2860
+ .m_traverse = module_traverse ,
2861
+ .m_clear = module_clear ,
2862
+ .m_free = module_free ,
2863
+ };
2833
2864
2834
2865
PyMODINIT_FUNC
2835
2866
PyInit__zoneinfo (void )
0 commit comments