diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2014-04-04 09:51:49 (GMT) |
---|---|---|
committer | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2014-04-04 09:51:49 (GMT) |
commit | 156307bfd67aacbdeb393c6bf831b6a63df92eb2 (patch) | |
tree | cf643083d97f669432d50e1351b6cdbcf446b80c /Lib/logging | |
parent | b30b34c1aaa400279ad4f58814ea14f2a362be55 (diff) | |
download | cpython-156307bfd67aacbdeb393c6bf831b6a63df92eb2.zip cpython-156307bfd67aacbdeb393c6bf831b6a63df92eb2.tar.gz cpython-156307bfd67aacbdeb393c6bf831b6a63df92eb2.tar.bz2 |
Issue #21149: Improved thread-safety in logging cleanup during interpreter shutdown.
Diffstat (limited to 'Lib/logging')
-rw-r--r-- | Lib/logging/__init__.py | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 478c5af..181bc15 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -711,16 +711,17 @@ def _removeHandlerRef(wr): Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are - # set to None. If _acquireLock is None, assume this is the case and do - # nothing. - if (_acquireLock is not None and _handlerList is not None and - _releaseLock is not None): - _acquireLock() + # set to None. It can also be called from another thread. So we need to + # pre-emptively grab the necessary globals and check if they're None, + # to prevent race conditions and failures during interpreter shutdown. + acquire, release, handlers = _acquireLock, _releaseLock, _handlerList + if acquire and release and handlers: + acquire() try: - if wr in _handlerList: - _handlerList.remove(wr) + if wr in handlers: + handlers.remove(wr) finally: - _releaseLock() + release() def _addHandlerRef(handler): """ |