[3.7] bpo-34130: Fix 2 race conditions in test_signal (GH-8329) · python/cpython@296e572
@@ -367,7 +367,6 @@ def handler(signum, frame):
367367 signal.signal(signum, handler)
368368369369 read, write = socket.socketpair()
370- read.setblocking(False)
371370 write.setblocking(False)
372371 signal.set_wakeup_fd(write.fileno())
373372@@ -455,26 +454,51 @@ def handler(signum, frame):
455454 signal.signal(signum, handler)
456455457456 read, write = socket.socketpair()
458- read.setblocking(False)
459- write.setblocking(False)
460457461- # Fill the send buffer
458+ # Fill the socketpair buffer
459+ if sys.platform == 'win32':
460+ # bpo-34130: On Windows, sometimes non-blocking send fails to fill
461+ # the full socketpair buffer, so use a timeout of 50 ms instead.
462+ write.settimeout(0.050)
463+ else:
464+ write.setblocking(False)
465+466+ # Start with large chunk size to reduce the
467+ # number of send needed to fill the buffer.
468+ written = 0
469+ for chunk_size in (2 ** 16, 2 ** 8, 1):
470+ chunk = b"x" * chunk_size
471+ try:
472+ while True:
473+ write.send(chunk)
474+ written += chunk_size
475+ except (BlockingIOError, socket.timeout):
476+ pass
477+478+ print(f"%s bytes written into the socketpair" % written, flush=True)
479+480+ write.setblocking(False)
462481 try:
463- while True:
464- write.send(b"x")
482+ write.send(b"x")
465483 except BlockingIOError:
484+ # The socketpair buffer seems full
466485 pass
486+ else:
487+ raise AssertionError("%s bytes failed to fill the socketpair "
488+ "buffer" % written)
467489468490 # By default, we get a warning when a signal arrives
491+ msg = ('Exception ignored when trying to {action} '
492+ 'to the signal wakeup fd')
469493 signal.set_wakeup_fd(write.fileno())
470494471495 with captured_stderr() as err:
472496 _testcapi.raise_signal(signum)
473497474498 err = err.getvalue()
475- if ('Exception ignored when trying to {action} to the signal wakeup fd'
476- not in err):
477- raise AssertionError(err)
499+ if msg not in err:
500+ raise AssertionError("first set_wakeup_fd() test failed, "
501+ "stderr: %r" % err)
478502479503 # And also if warn_on_full_buffer=True
480504 signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=True)
@@ -483,9 +507,9 @@ def handler(signum, frame):
483507 _testcapi.raise_signal(signum)
484508485509 err = err.getvalue()
486- if ('Exception ignored when trying to {action} to the signal wakeup fd'
487- not in err):
488- raise AssertionError(err)
510+ if msg not in err:
511+ raise AssertionError("set_wakeup_fd(warn_on_full_buffer=True) "
512+ "test failed, stderr: %r" % err)
489513490514 # But not if warn_on_full_buffer=False
491515 signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=False)
@@ -495,7 +519,8 @@ def handler(signum, frame):
495519496520 err = err.getvalue()
497521 if err != "":
498- raise AssertionError("got unexpected output %r" % (err,))
522+ raise AssertionError("set_wakeup_fd(warn_on_full_buffer=False) "
523+ "test failed, stderr: %r" % err)
499524500525 # And then check the default again, to make sure warn_on_full_buffer
501526 # settings don't leak across calls.
@@ -505,9 +530,9 @@ def handler(signum, frame):
505530 _testcapi.raise_signal(signum)
506531507532 err = err.getvalue()
508- if ('Exception ignored when trying to {action} to the signal wakeup fd'
509- not in err):
510- raise AssertionError(err)
533+ if msg not in err:
534+ raise AssertionError("second set_wakeup_fd() test failed, "
535+ "stderr: %r" % err)
511536512537 """.format(action=action)
513538assert_python_ok('-c', code)