diff --git a/src/crystal/at_exit_handlers.cr b/src/crystal/at_exit_handlers.cr index 7cd7b8cbc244..071a8700e824 100644 --- a/src/crystal/at_exit_handlers.cr +++ b/src/crystal/at_exit_handlers.cr @@ -1,21 +1,24 @@ # :nodoc: module Crystal::AtExitHandlers - private class_getter(handlers) { [] of Int32, ::Exception? -> } + @@mutex = ::Thread::Mutex.new def self.add(handler) - handlers << handler + @@mutex.synchronize do + handlers = @@handlers ||= [] of Int32, ::Exception? -> + handlers << handler + end end def self.run(status, exception = nil) - if handlers = @@handlers - # Run the registered handlers in reverse order - while handler = handlers.pop? - begin - handler.call status, exception - rescue handler_ex - Crystal::System.print_error "Error running at_exit handler: %s\n", handler_ex.message || "" - status = 1 if status.zero? - end + return status unless @@handlers + + # Run the registered handlers in reverse order + while handler = @@mutex.synchronize { @@handlers.try(&.pop?) } + begin + handler.call status, exception + rescue handler_ex + Crystal::System.print_error "Error running at_exit handler: %s\n", handler_ex.message || "" + status = 1 if status.zero? end end