Commit 6d3c09f2 authored by Victor Stinner's avatar Victor Stinner

Issue #23680: Reduce risk of race condition in check_interrupted_write_retry()

of test_io. Allocate the large data before scheduling an alarm in 1 second.

On very slow computer, the alarm rings sometimes during the memory allocation.
parent 59b356d6
...@@ -3544,11 +3544,13 @@ class SignalsTest(unittest.TestCase): ...@@ -3544,11 +3544,13 @@ class SignalsTest(unittest.TestCase):
returning a partial result or EINTR), properly invokes the signal returning a partial result or EINTR), properly invokes the signal
handler and retries if the latter returned successfully.""" handler and retries if the latter returned successfully."""
select = support.import_module("select") select = support.import_module("select")
# A quantity that exceeds the buffer size of an anonymous pipe's # A quantity that exceeds the buffer size of an anonymous pipe's
# write end. # write end.
N = support.PIPE_MAX_SIZE N = support.PIPE_MAX_SIZE
r, w = os.pipe() r, w = os.pipe()
fdopen_kwargs["closefd"] = False fdopen_kwargs["closefd"] = False
# We need a separate thread to read from the pipe and allow the # We need a separate thread to read from the pipe and allow the
# write() to finish. This thread is started after the SIGALRM is # write() to finish. This thread is started after the SIGALRM is
# received (forcing a first EINTR in write()). # received (forcing a first EINTR in write()).
...@@ -3566,6 +3568,8 @@ class SignalsTest(unittest.TestCase): ...@@ -3566,6 +3568,8 @@ class SignalsTest(unittest.TestCase):
signal.alarm(1) signal.alarm(1)
def alarm2(sig, frame): def alarm2(sig, frame):
t.start() t.start()
large_data = item * N
signal.signal(signal.SIGALRM, alarm1) signal.signal(signal.SIGALRM, alarm1)
try: try:
wio = self.io.open(w, **fdopen_kwargs) wio = self.io.open(w, **fdopen_kwargs)
...@@ -3575,10 +3579,13 @@ class SignalsTest(unittest.TestCase): ...@@ -3575,10 +3579,13 @@ class SignalsTest(unittest.TestCase):
# and the first alarm) # and the first alarm)
# - second raw write() returns EINTR (because of the second alarm) # - second raw write() returns EINTR (because of the second alarm)
# - subsequent write()s are successful (either partial or complete) # - subsequent write()s are successful (either partial or complete)
self.assertEqual(N, wio.write(item * N)) written = wio.write(large_data)
self.assertEqual(N, written)
wio.flush() wio.flush()
write_finished = True write_finished = True
t.join() t.join()
self.assertEqual(N, sum(len(x) for x in read_results)) self.assertEqual(N, sum(len(x) for x in read_results))
finally: finally:
write_finished = True write_finished = True
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment