bpo-41503: Fix race between setTarget and flush in logging.handlers.MemoryHandler (GH-21765)
This commit is contained in:
parent
fff3c28052
commit
2353d77fad
|
@ -1324,7 +1324,11 @@ class MemoryHandler(BufferingHandler):
|
||||||
"""
|
"""
|
||||||
Set the target handler for this handler.
|
Set the target handler for this handler.
|
||||||
"""
|
"""
|
||||||
self.target = target
|
self.acquire()
|
||||||
|
try:
|
||||||
|
self.target = target
|
||||||
|
finally:
|
||||||
|
self.release()
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1160,6 +1160,27 @@ class MemoryHandlerTest(BaseTest):
|
||||||
# assert that no new lines have been added
|
# assert that no new lines have been added
|
||||||
self.assert_log_lines(lines) # no change
|
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):
|
class ExceptionFormatter(logging.Formatter):
|
||||||
"""A special exception formatter."""
|
"""A special exception formatter."""
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed a race between setTarget and flush in logging.handlers.MemoryHandler.
|
Loading…
Reference in New Issue