Skip to content

Commit 325dc24

Browse files
authored
More support for sloppy shutdowns. (#165)
We were seeing occasional crashes in the logger code when a program exited while native objects were still alive. The global static logger was cleaned up during module unload, so if another thread is logging in the middle of that ... crash. Attempt to fix by NOT cleaning up global statics during module unload. It's not clear to me whether C modules can be reloaded, so this seems like an acceptable solution. If someone can show me where the reload process is documented, and has a use case, we can try harder to support it. Maybe track the number of living native objects, and clean up global statics if the count is 0.
1 parent 72885c7 commit 325dc24

File tree

1 file changed

+4
-27
lines changed

1 file changed

+4
-27
lines changed

source/module.c

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -570,19 +570,6 @@ PyDoc_STRVAR(s_module_doc, "C extension for binding AWS implementations of MQTT,
570570
* Module Init
571571
******************************************************************************/
572572

573-
static void s_module_free(void) {
574-
if (s_logger_init) {
575-
aws_logger_clean_up(&s_logger);
576-
}
577-
578-
aws_hash_table_clean_up(&s_py_to_aws_error_map);
579-
aws_hash_table_clean_up(&s_aws_to_py_error_map);
580-
581-
aws_mqtt_library_clean_up();
582-
aws_auth_library_clean_up();
583-
aws_http_library_clean_up();
584-
}
585-
586573
static void s_module_init(void) {
587574
s_install_crash_handler();
588575

@@ -599,22 +586,17 @@ static void s_module_init(void) {
599586

600587
#if PY_MAJOR_VERSION == 3
601588

602-
static void s_py3_module_free(void *userdata) {
603-
(void)userdata;
604-
s_module_free();
605-
}
606-
607589
PyMODINIT_FUNC PyInit__awscrt(void) {
608590
static struct PyModuleDef s_module_def = {
609591
PyModuleDef_HEAD_INIT,
610592
s_module_name,
611593
s_module_doc,
612594
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
613595
s_module_methods,
614-
NULL, /* slots for multi-phase initialization */
615-
NULL, /* traversal fn to call during GC traversal */
616-
NULL, /* clear fn to call during GC clear */
617-
s_py3_module_free, /* fn to call during deallocation of the module object */
596+
NULL, /* slots for multi-phase initialization */
597+
NULL, /* traversal fn to call during GC traversal */
598+
NULL, /* clear fn to call during GC clear */
599+
NULL, /* fn to call during deallocation of the module object */
618600
};
619601

620602
PyObject *m = PyModule_Create(&s_module_def);
@@ -633,11 +615,6 @@ PyMODINIT_FUNC init_awscrt(void) {
633615
AWS_FATAL_ASSERT(0 && "Failed to initialize _awscrt");
634616
}
635617

636-
/* Python 2 doesn't let us pass a module-free fn to the module-create fn, so register a global at-exit fn. */
637-
if (Py_AtExit(s_module_free) == -1) {
638-
AWS_FATAL_ASSERT(0 && "Failed to register atexit function for _awscrt");
639-
}
640-
641618
s_module_init();
642619
}
643620

0 commit comments

Comments
 (0)