Fixed most bugs with I/O (except dangling resources)
This commit is contained in:
parent
acc436d518
commit
3ac6ea58cb
|
@ -22,8 +22,7 @@ from aiosched.internals.syscalls import (
|
||||||
cancel,
|
cancel,
|
||||||
set_context,
|
set_context,
|
||||||
close_context,
|
close_context,
|
||||||
join,
|
join
|
||||||
current_task,
|
|
||||||
)
|
)
|
||||||
from typing import Any, Coroutine, Callable
|
from typing import Any, Coroutine, Callable
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ class TaskContext(Task):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(other, TaskContext):
|
if isinstance(other, TaskContext):
|
||||||
return super().__eq__(self, other)
|
return super().__eq__(other)
|
||||||
elif isinstance(other, Task):
|
elif isinstance(other, Task):
|
||||||
return other == self.entry_point
|
return other == self.entry_point
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -75,7 +75,7 @@ class AsyncStream:
|
||||||
|
|
||||||
async def write(self, data):
|
async def write(self, data):
|
||||||
"""
|
"""
|
||||||
Writes data b to the file.
|
Writes data to the stream.
|
||||||
Returns the number of bytes
|
Returns the number of bytes
|
||||||
written
|
written
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -120,17 +120,18 @@ class FIFOKernel:
|
||||||
# There's tasks sleeping and/or on the
|
# There's tasks sleeping and/or on the
|
||||||
# ready queue!
|
# ready queue!
|
||||||
return False
|
return False
|
||||||
for key in self.selector.get_map().values():
|
if self.selector.get_map():
|
||||||
# We don't just do any([self.paused, self.run_ready, self.selector.get_map()])
|
for key in self.selector.get_map().values():
|
||||||
# because we don't want to just know if there's any resources we're waiting on,
|
# We don't just do any([self.paused, self.run_ready, self.selector.get_map()])
|
||||||
# but if there's at least one non-terminated task that owns a resource we're
|
# because we don't want to just know if there's any resources we're waiting on,
|
||||||
# waiting on. This avoids issues such as the event loop never exiting if the
|
# but if there's at least one non-terminated task that owns a resource we're
|
||||||
# user forgets to close a socket, for example
|
# waiting on. This avoids issues such as the event loop never exiting if the
|
||||||
key.data: Task
|
# user forgets to close a socket, for example
|
||||||
if key.data.done():
|
key.data: Task
|
||||||
continue
|
if key.data.done():
|
||||||
elif self.get_task_io(key.data):
|
continue
|
||||||
return False
|
elif self.get_task_io(key.data):
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def close(self, force: bool = False):
|
def close(self, force: bool = False):
|
||||||
|
@ -406,7 +407,11 @@ class FIFOKernel:
|
||||||
lambda o: o.fileobj == stream,
|
lambda o: o.fileobj == stream,
|
||||||
dict(self.selector.get_map()).values(),
|
dict(self.selector.get_map()).values(),
|
||||||
):
|
):
|
||||||
self.handle_task_run(partial(k.data.throw, exc), k.data)
|
if k.data != self.current_task:
|
||||||
|
# We don't want to raise an error inside
|
||||||
|
# the task that's trying to close the stream!
|
||||||
|
self.handle_task_run(partial(k.data.throw, exc), k.data)
|
||||||
|
self.reschedule_running()
|
||||||
|
|
||||||
def cancel(self, task: Task):
|
def cancel(self, task: Task):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,7 +8,7 @@ async def producer(c: aiosched.NetworkChannel, n: int):
|
||||||
await c.write(str(i).encode())
|
await c.write(str(i).encode())
|
||||||
print(f"[producer] Sent {i}")
|
print(f"[producer] Sent {i}")
|
||||||
await aiosched.sleep(0.5) # This makes the receiver wait on us!
|
await aiosched.sleep(0.5) # This makes the receiver wait on us!
|
||||||
#await c.close()
|
await c.close()
|
||||||
print("[producer] Done")
|
print("[producer] Done")
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue