Skip to content

Commit a30acc9

Browse files
committed
Add cancellation callback
1 parent f9701cb commit a30acc9

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

Lib/asyncio/unix_events.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,13 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
328328
return 0 # empty file
329329

330330
fut = self.create_future()
331-
fd = sock.fileno()
332-
self._sock_sendfile_native_impl(fut, None, fd, fileno,
331+
self._sock_sendfile_native_impl(fut, None, sock, fileno,
333332
offset, count, blocksize, 0)
334333
return await fut
335334

336-
def _sock_sendfile_native_impl(self, fut, registered_fd, fd, fileno,
335+
def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno,
337336
offset, count, blocksize, total_sent):
337+
fd = sock.fileno()
338338
if registered_fd is not None:
339339
# Remove the callback early. It should be rare that the
340340
# selector says the fd is ready but the call still returns
@@ -354,8 +354,11 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, fd, fileno,
354354
try:
355355
sent = os.sendfile(fd, fileno, offset, blocksize)
356356
except (BlockingIOError, InterruptedError):
357-
self.add_writer(fd, self._sock_sendfile_native_impl, fut, fd, fd,
358-
fileno, offset, count, blocksize. total_sent)
357+
if registered_fd is None:
358+
self._sock_add_cancellation_callback(fut, sock)
359+
self.add_writer(fd, self._sock_sendfile_native_impl, fut,
360+
fd, sock, fileno,
361+
offset, count, blocksize. total_sent)
359362
except OSError as exc:
360363
if total_sent == 0:
361364
# We can get here for different reasons, the main
@@ -380,14 +383,24 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, fd, fileno,
380383
else:
381384
offset += sent
382385
total_sent += sent
386+
if registered_fd is None:
387+
self._sock_add_cancellation_callback(fut, sock)
383388
self.add_writer(fd, self._sock_sendfile_native_impl, fut,
384-
fd, fd, fileno,
389+
fd, sock, fileno,
385390
offset, count, blocksize, total_sent)
386391

387392
def _sock_sendfile_update_filepos(self, fileno, offset, total_sent):
388393
if total_sent > 0:
389394
os.lseek(fileno, offset, os.SEEK_SET)
390395

396+
def _sock_add_cancellation_callback(self, fut, sock):
397+
def cb(fut):
398+
if fut.cancelled():
399+
fd = sock.fileno()
400+
if fd!= -1:
401+
self.remove_writer(fd)
402+
fut.add_done_callback(cb)
403+
391404

392405
class _UnixReadPipeTransport(transports.ReadTransport):
393406

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,11 @@ def __init__(self, loop):
430430
self.closed = False
431431
self.data = bytearray()
432432
self.fut = loop.create_future()
433+
self.transport = None
433434

434435
def connection_made(self, transport):
435436
self.started = True
437+
self.transport = transport
436438

437439
def data_received(self, data):
438440
self.data.extend(data)
@@ -480,6 +482,9 @@ def prepare(self):
480482
self.run_loop(self.loop.sock_connect(sock, (support.HOST, port)))
481483

482484
def cleanup():
485+
proto.transport.close()
486+
self.run_loop(proto.wait_closed())
487+
483488
server.close()
484489
self.run_loop(server.wait_closed())
485490

0 commit comments

Comments
 (0)