Skip to content

Commit 2c050e5

Browse files
[3.9] bpo-41503: Fix race between setTarget and flush in logging.handlers.MemoryHandler (GH-21765) (GH-21897)
(cherry picked from commit 2353d77) Co-authored-by: Irit Katriel <[email protected]> Automerge-Triggered-By: @vsajip
1 parent 28bf826 commit 2c050e5

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

Lib/logging/handlers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,11 @@ def setTarget(self, target):
13241324
"""
13251325
Set the target handler for this handler.
13261326
"""
1327-
self.target = target
1327+
self.acquire()
1328+
try:
1329+
self.target = target
1330+
finally:
1331+
self.release()
13281332

13291333
def flush(self):
13301334
"""

Lib/test/test_logging.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,27 @@ def test_flush_on_close(self):
11571157
# assert that no new lines have been added
11581158
self.assert_log_lines(lines) # no change
11591159

1160+
def test_race_between_set_target_and_flush(self):
1161+
class MockRaceConditionHandler:
1162+
def __init__(self, mem_hdlr):
1163+
self.mem_hdlr = mem_hdlr
1164+
1165+
def removeTarget(self):
1166+
self.mem_hdlr.setTarget(None)
1167+
1168+
def handle(self, msg):
1169+
t = threading.Thread(target=self.removeTarget)
1170+
t.daemon = True
1171+
t.start()
1172+
1173+
target = MockRaceConditionHandler(self.mem_hdlr)
1174+
self.mem_hdlr.setTarget(target)
1175+
1176+
for _ in range(10):
1177+
time.sleep(0.005)
1178+
self.mem_logger.info("not flushed")
1179+
self.mem_logger.warning("flushed")
1180+
11601181

11611182
class ExceptionFormatter(logging.Formatter):
11621183
"""A special exception formatter."""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a race between setTarget and flush in logging.handlers.MemoryHandler.

0 commit comments

Comments
 (0)