Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 626032a

Browse files
committed
Issue #17097: Merge.
2 parents 7c1457b + cca8c53 commit 626032a

3 files changed

Lines changed: 86 additions & 4 deletions

File tree

Lib/multiprocessing/connection.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,10 @@ def _close(self, _close=os.close):
363363
def _send(self, buf, write=_write):
364364
remaining = len(buf)
365365
while True:
366-
n = write(self._handle, buf)
366+
try:
367+
n = write(self._handle, buf)
368+
except InterruptedError:
369+
continue
367370
remaining -= n
368371
if remaining == 0:
369372
break
@@ -374,7 +377,10 @@ def _recv(self, size, read=_read):
374377
handle = self._handle
375378
remaining = size
376379
while remaining > 0:
377-
chunk = read(handle, remaining)
380+
try:
381+
chunk = read(handle, remaining)
382+
except InterruptedError:
383+
continue
378384
n = len(chunk)
379385
if n == 0:
380386
if remaining == size:
@@ -578,7 +584,13 @@ def __init__(self, address, family, backlog=1):
578584
self._unlink = None
579585

580586
def accept(self):
581-
s, self._last_accepted = self._socket.accept()
587+
while True:
588+
try:
589+
s, self._last_accepted = self._socket.accept()
590+
except InterruptedError:
591+
pass
592+
else:
593+
break
582594
s.setblocking(True)
583595
return Connection(s.detach())
584596

Lib/test/test_multiprocessing.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3513,14 +3513,82 @@ def test_lock(self):
35133513
p.join()
35143514
self.assertLessEqual(new_size, old_size)
35153515

3516+
#
3517+
# Issue #17097: EINTR should be ignored by recv(), send(), accept() etc
3518+
#
3519+
3520+
class TestIgnoreEINTR(unittest.TestCase):
3521+
3522+
@classmethod
3523+
def _test_ignore(cls, conn):
3524+
def handler(signum, frame):
3525+
pass
3526+
signal.signal(signal.SIGUSR1, handler)
3527+
conn.send('ready')
3528+
x = conn.recv()
3529+
conn.send(x)
3530+
conn.send_bytes(b'x'*(1024*1024)) # sending 1 MB should block
3531+
3532+
@unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1')
3533+
def test_ignore(self):
3534+
conn, child_conn = multiprocessing.Pipe()
3535+
try:
3536+
p = multiprocessing.Process(target=self._test_ignore,
3537+
args=(child_conn,))
3538+
p.daemon = True
3539+
p.start()
3540+
child_conn.close()
3541+
self.assertEqual(conn.recv(), 'ready')
3542+
time.sleep(0.1)
3543+
os.kill(p.pid, signal.SIGUSR1)
3544+
time.sleep(0.1)
3545+
conn.send(1234)
3546+
self.assertEqual(conn.recv(), 1234)
3547+
time.sleep(0.1)
3548+
os.kill(p.pid, signal.SIGUSR1)
3549+
self.assertEqual(conn.recv_bytes(), b'x'*(1024*1024))
3550+
time.sleep(0.1)
3551+
p.join()
3552+
finally:
3553+
conn.close()
3554+
3555+
@classmethod
3556+
def _test_ignore_listener(cls, conn):
3557+
def handler(signum, frame):
3558+
pass
3559+
signal.signal(signal.SIGUSR1, handler)
3560+
l = multiprocessing.connection.Listener()
3561+
conn.send(l.address)
3562+
a = l.accept()
3563+
a.send('welcome')
3564+
3565+
@unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1')
3566+
def test_ignore_listener(self):
3567+
conn, child_conn = multiprocessing.Pipe()
3568+
try:
3569+
p = multiprocessing.Process(target=self._test_ignore_listener,
3570+
args=(child_conn,))
3571+
p.daemon = True
3572+
p.start()
3573+
child_conn.close()
3574+
address = conn.recv()
3575+
time.sleep(0.1)
3576+
os.kill(p.pid, signal.SIGUSR1)
3577+
time.sleep(0.1)
3578+
client = multiprocessing.connection.Client(address)
3579+
self.assertEqual(client.recv(), 'welcome')
3580+
p.join()
3581+
finally:
3582+
conn.close()
3583+
35163584
#
35173585
#
35183586
#
35193587

35203588
testcases_other = [OtherTest, TestInvalidHandle, TestInitializers,
35213589
TestStdinBadfiledescriptor, TestWait, TestInvalidFamily,
35223590
TestFlags, TestTimeouts, TestNoForkBomb,
3523-
TestForkAwareThreadLock]
3591+
TestForkAwareThreadLock, TestIgnoreEINTR]
35243592

35253593
#
35263594
#

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ Core and Builtins
135135
Library
136136
-------
137137

138+
- Issue #17097: Make multiprocessing ignore EINTR.
139+
138140
- Issue #18339: Negative ints keys in unpickler.memo dict no longer cause a
139141
segfault inside the _pickle C extension.
140142

0 commit comments

Comments
 (0)