Skip to content

Commit 0f1f1ea

Browse files
Global state to module state
1 parent 4c31528 commit 0f1f1ea

File tree

1 file changed

+66
-35
lines changed

1 file changed

+66
-35
lines changed

Modules/_zoneinfo.c

Lines changed: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ typedef struct {
100100
_ttinfo NO_TTINFO;
101101
} zoneinfo_state;
102102

103-
// Globals
104-
static zoneinfo_state global_state;
105-
106103
// Constants
107104
static const int EPOCHORDINAL = 719163;
108105
static int DAYS_IN_MONTH[] = {
@@ -194,19 +191,29 @@ static PyObject *
194191
zone_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type,
195192
PyObject *const key);
196193

197-
zoneinfo_state *zoneinfo_get_state(PyObject *mod)
194+
static inline zoneinfo_state *
195+
zoneinfo_get_state(PyObject *mod)
198196
{
199-
return &global_state;
197+
zoneinfo_state *state = (zoneinfo_state *)PyModule_GetState(mod);
198+
assert(state != NULL);
199+
return state;
200200
}
201201

202-
zoneinfo_state *zoneinfo_get_state_by_cls(PyTypeObject *cls)
202+
static inline zoneinfo_state *
203+
zoneinfo_get_state_by_cls(PyTypeObject *cls)
203204
{
204-
return &global_state;
205+
zoneinfo_state *state = (zoneinfo_state *)PyType_GetModuleState(cls);
206+
assert(state != NULL);
207+
return state;
205208
}
206209

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)
208213
{
209-
return &global_state;
214+
PyObject *mod = PyType_GetModuleByDef(self, &zoneinfomodule);
215+
assert(mod != NULL);
216+
return zoneinfo_get_state(mod);
210217
}
211218

212219
static PyObject *
@@ -2732,36 +2739,57 @@ static PyType_Spec zoneinfo_spec = {
27322739
/////
27332740
// Specify the _zoneinfo module
27342741
static PyMethodDef module_methods[] = {{NULL, NULL}};
2735-
static void
2736-
module_free(void *m)
2737-
{
2738-
zoneinfo_state *state = zoneinfo_get_state(m);
27392742

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);
27432747

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);
27452754

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;
27532761
}
27542762

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);
27632766

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);
27642781
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);
27652793
}
27662794

27672795
static int
@@ -2823,13 +2851,16 @@ static PyModuleDef_Slot zoneinfomodule_slots[] = {
28232851
{Py_mod_exec, zoneinfomodule_exec}, {0, NULL}};
28242852

28252853
static struct PyModuleDef zoneinfomodule = {
2826-
PyModuleDef_HEAD_INIT,
2854+
.m_base = PyModuleDef_HEAD_INIT,
28272855
.m_name = "_zoneinfo",
28282856
.m_doc = "C implementation of the zoneinfo module",
2829-
.m_size = 0,
2857+
.m_size = sizeof(zoneinfo_state),
28302858
.m_methods = module_methods,
28312859
.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+
};
28332864

28342865
PyMODINIT_FUNC
28352866
PyInit__zoneinfo(void)

0 commit comments

Comments
 (0)