[Python-checkins] [3.8] bpo-41503: Fix race between setTarget and flush in logging.handlers.MemoryHandler (GH-21765) (GH-21898)

Miss Islington (bot) webhook-mailer at python.org
Sun Aug 16 12:27:09 EDT 2020


https://github.com/python/cpython/commit/08f0a2109297e8a64e8636d47dce737e5b7ccf2c
commit: 08f0a2109297e8a64e8636d47dce737e5b7ccf2c
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-08-16T09:27:01-07:00
summary:

[3.8] bpo-41503: Fix race between setTarget and flush in logging.handlers.MemoryHandler (GH-21765) (GH-21898)



(cherry picked from commit 2353d77fad7ed9d11d8a4d66b5dd1306cdb94125)


Co-authored-by: Irit Katriel <iritkatriel at yahoo.com>

Automerge-Triggered-By: @vsajip

files:
A Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst
M Lib/logging/handlers.py
M Lib/test/test_logging.py

diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 34ff7a056ef54..29802b61d1c1f 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1294,7 +1294,11 @@ def setTarget(self, target):
         """
         Set the target handler for this handler.
         """
-        self.target = target
+        self.acquire()
+        try:
+            self.target = target
+        finally:
+            self.release()
 
     def flush(self):
         """
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 09b273bf1fb2d..cea51b455eed2 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -1173,6 +1173,27 @@ def test_flush_on_close(self):
         # assert that no new lines have been added
         self.assert_log_lines(lines)  # no change
 
+    def test_race_between_set_target_and_flush(self):
+        class MockRaceConditionHandler:
+            def __init__(self, mem_hdlr):
+                self.mem_hdlr = mem_hdlr
+
+            def removeTarget(self):
+                self.mem_hdlr.setTarget(None)
+
+            def handle(self, msg):
+                t = threading.Thread(target=self.removeTarget)
+                t.daemon = True
+                t.start()
+
+        target = MockRaceConditionHandler(self.mem_hdlr)
+        self.mem_hdlr.setTarget(target)
+
+        for _ in range(10):
+            time.sleep(0.005)
+            self.mem_logger.info("not flushed")
+            self.mem_logger.warning("flushed")
+
 
 class ExceptionFormatter(logging.Formatter):
     """A special exception formatter."""
diff --git a/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst b/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst
new file mode 100644
index 0000000000000..c34996d881937
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-08-07-15-18-16.bpo-41503.IYftcu.rst
@@ -0,0 +1 @@
+Fixed a race between setTarget and flush in logging.handlers.MemoryHandler.
\ No newline at end of file



More information about the Python-checkins mailing list