@@ -303,12 +303,20 @@ PyTypeObject JSObjectItemsProxyType = {
303
303
};
304
304
305
305
static void cleanup () {
306
+ // Clean up the PythonMonkey module
307
+ Py_XDECREF (PythonMonkey_Null);
308
+ Py_XDECREF (PythonMonkey_BigInt);
309
+
310
+ // Clean up SpiderMonkey
306
311
delete autoRealm;
307
312
delete global;
308
313
if (GLOBAL_CX) JS_DestroyContext (GLOBAL_CX);
309
314
delete JOB_QUEUE;
310
315
JS_ShutDown ();
311
316
}
317
+ static void cleanup (PyObject *) {
318
+ cleanup ();
319
+ }
312
320
313
321
static PyObject *collect (PyObject *self, PyObject *args) {
314
322
JS_GC (GLOBAL_CX);
@@ -550,7 +558,6 @@ PyMODINIT_FUNC PyInit_pythonmonkey(void)
550
558
PyErr_SetString (SpiderMonkeyError, " Spidermonkey could not be initialized." );
551
559
return NULL ;
552
560
}
553
- Py_AtExit (cleanup);
554
561
555
562
GLOBAL_CX = JS_NewContext (JS::DefaultHeapMaxBytes);
556
563
if (!GLOBAL_CX) {
@@ -643,6 +650,16 @@ PyMODINIT_FUNC PyInit_pythonmonkey(void)
643
650
if (pyModule == NULL )
644
651
return NULL ;
645
652
653
+ // Clean up SpiderMonkey when the PythonMonkey module gets destroyed (module.___cleanup is GCed)
654
+ // The `cleanup` function will be called automatically when this PyCapsule gets GCed
655
+ // We cannot use `Py_AtExit(cleanup);` because the GIL is unavailable after Python finalization, no more Python APIs can be called.
656
+ PyObject *autoDestructor = PyCapsule_New (&pythonmonkey, NULL , cleanup);
657
+ if (PyModule_AddObject (pyModule, " ___cleanup" , autoDestructor) < 0 ) {
658
+ Py_DECREF (autoDestructor);
659
+ Py_DECREF (pyModule);
660
+ return NULL ;
661
+ }
662
+
646
663
Py_INCREF (&NullType);
647
664
if (PyModule_AddObject (pyModule, " null" , (PyObject *)&NullType) < 0 ) {
648
665
Py_DECREF (&NullType);
0 commit comments