[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)

513538

assert_python_ok('-c', code)