@@ -24,6 +24,18 @@ module _multiprocessing
2424
2525#include "clinic/multiprocessing.c.h"
2626
27+ typedef struct {
28+ PyTypeObject * semlock_type ;
29+ } _multiprocessingstate ;
30+
31+ static inline
32+ _multiprocessingstate * get_module_state (PyObject * module )
33+ {
34+ void * state = PyModule_GetState (module );
35+ assert (state != NULL );
36+ return (_multiprocessingstate * )state ;
37+ }
38+
2739/*
2840 * Function which raises exceptions based on error codes
2941 */
@@ -186,35 +198,38 @@ static PyMethodDef module_methods[] = {
186198static int
187199multiprocessing_exec (PyObject * module )
188200{
201+ _multiprocessingstate * state = get_module_state (module );
189202#ifdef HAVE_MP_SEMAPHORE
190203
191- /* Add _PyMp_SemLock type to module */
192- if (PyModule_AddType (module , & _PyMp_SemLockType ) < 0 ) {
204+ state -> semlock_type = (PyTypeObject * )PyType_FromModuleAndSpec (
205+
10BC0
module , & _PyMp_SemLockType_spec , NULL );
206+
207+ if (state -> semlock_type == NULL ) {
208+ return -1 ;
209+ }
210+ if (PyModule_AddType (module , state -> semlock_type ) < 0 ) {
193211 return -1 ;
194212 }
195213
196- {
197- PyObject * py_sem_value_max ;
198- /* Some systems define SEM_VALUE_MAX as an unsigned value that
199- * causes it to be negative when used as an int (NetBSD).
200- *
201- * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
202- * when using clang -Wunreachable-code. */
203- if ((int )(SEM_VALUE_MAX ) < (0 ))
204- py_sem_value_max = PyLong_FromLong (INT_MAX );
205- else
206- py_sem_value_max = PyLong_FromLong (SEM_VALUE_MAX );
207-
208- if (py_sem_value_max == NULL ) {
209- return -1 ;
210- }
211- if (PyDict_SetItemString (_PyMp_SemLockType .tp_dict , "SEM_VALUE_MAX" ,
212- py_sem_value_max ) < 0 ) {
213- Py_DECREF (py_sem_value_max );
214- return -1 ;
215- }
214+ PyObject * py_sem_value_max ;
215+ /* Some systems define SEM_VALUE_MAX as an unsigned value that
216+ * causes it to be negative when used as an int (NetBSD).
217+ *
218+ * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
219+ * when using clang -Wunreachable-code. */
220+ if ((int )(SEM_VALUE_MAX ) < (0 ))
221+ py_sem_value_max = PyLong_FromLong (INT_MAX );
222+ else
223+ py_sem_value_max = PyLong_FromLong (SEM_VALUE_MAX );
224+ if (py_sem_value_max == NULL ) {
225+ return -1 ;
226+ }
227+ if (PyDict_SetItemString (state -> semlock_type -> tp_dict , "SEM_VALUE_MAX" ,
228+ py_sem_value_max ) < 0 ) {
216229 Py_DECREF (py_sem_value_max );
230+ return -1 ;
217231 }
232+ Py_DECREF (py_sem_value_max );
218233
219234#endif
220235
@@ -260,6 +275,28 @@ multiprocessing_exec(PyObject *module)
260275 return 0 ;
261276}
262277
278+ static int
279+ multiprocessing_traverse (PyObject * module , visitproc visit , void * arg )
280+ {
281+ _multiprocessingstate * state = get_module_state (module );
282+ Py_VISIT (state -> semlock_type );
283+ return 0 ;
284+ }
285+
286+ static int
287+ multiprocessing_clear (PyObject * module )
288+ {
289+ _multiprocessingstate * state = get_module_state (module );
290+ Py_CLEAR (state -> semlock_type );
291+ return 0 ;
292+ }
293+
294+ static void
295+ multiprocessing_dealloc (void * module )
296+ {
297+ (void )multiprocessing_clear ((PyObject * )module );
298+ }
299+
263300static PyModuleDef_Slot multiprocessing_slots [] = {
264301 {Py_mod_exec , multiprocessing_exec },
265302 {0 , NULL }
@@ -268,8 +305,12 @@ static PyModuleDef_Slot multiprocessing_slots[] = {
268305static struct PyModuleDef multiprocessing_module = {
269306 PyModuleDef_HEAD_INIT ,
270307 .m_name = "_multiprocessing" ,
308+ .m_size = sizeof (_multiprocessingstate ),
271309 .m_methods = module_methods ,
272310 .m_slots = multiprocessing_slots ,
311+ .m_traverse = multiprocessing_traverse ,
312+ .m_clear = multiprocessing_clear ,
313+ .m_free = multiprocessing_dealloc ,
273314};
274315
275316PyMODINIT_FUNC
0 commit comments