Skip to content

Commit

Permalink
yield_indefinitely -> wait_task_rescheduled
Browse files Browse the repository at this point in the history
  • Loading branch information
njsmith committed Sep 4, 2017
1 parent 8c3109d commit 68a1898
Show file tree
Hide file tree
Showing 14 changed files with 41 additions and 35 deletions.
8 changes: 4 additions & 4 deletions docs/source/reference-hazmat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -398,19 +398,19 @@ make sure that the call always acts as a checkpoint, it calls
Low-level blocking
------------------

.. autofunction:: yield_indefinitely
.. autofunction:: wait_task_rescheduled
.. autoclass:: Abort
.. autofunction:: reschedule

Here's an example lock class implemented using
:func:`yield_indefinitely` directly. This implementation has a number
:func:`wait_task_rescheduled` directly. This implementation has a number
of flaws, including lack of fairness, O(n) cancellation, missing error
checking, failure to insert a checkpoint on the non-blocking path,
etc. If you really want to implement your own lock, then you should
study the implementation of :class:`trio.Lock` and use
:class:`ParkingLot`, which handles some of these issues for you. But
this does serve to illustrate the basic structure of the
:func:`yield_indefinitely` API::
:func:`wait_task_rescheduled` API::

class NotVeryGoodLock:
def __init__(self):
Expand All @@ -424,7 +424,7 @@ this does serve to illustrate the basic structure of the
def abort_fn(_):
self._blocked_tasks.remove(task)
return trio.hazmat.Abort.SUCCEEDED
await trio.hazmat.yield_indefinitely(abort_fn)
await trio.hazmat.wait_task_rescheduled(abort_fn)
self._held = True

def release(self):
Expand Down
4 changes: 4 additions & 0 deletions trio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@
_deprecate.DeprecatedAttribute(
hazmat.checkpoint_if_cancelled, "0.2.0", issue=157
),
"yield_indefinitely":
_deprecate.DeprecatedAttribute(
hazmat.wait_task_rescheduled, "0.2.0", issue=157
),
}

# Having the public path in .__module__ attributes is important for:
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_io_epoll.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def abort(_):
self._update_registrations(fd, True)
return _core.Abort.SUCCEEDED

await _core.yield_indefinitely(abort)
await _core.wait_task_rescheduled(abort)

@_public
@_hazmat
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_io_kqueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def abort(raise_cancel):
del self._registered[key]
return r

return await _core.yield_indefinitely(abort)
return await _core.wait_task_rescheduled(abort)

async def _wait_common(self, fd, filter):
if not isinstance(fd, int):
Expand Down
4 changes: 2 additions & 2 deletions trio/_core/_io_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def abort(raise_cancel_):
_check(kernel32.CancelIoEx(handle, lpOverlapped))
return _core.Abort.FAILED

await _core.yield_indefinitely(abort)
await _core.wait_task_rescheduled(abort)
if lpOverlapped.Internal != 0:
if lpOverlapped.Internal == ErrorCodes.ERROR_OPERATION_ABORTED:
assert raise_cancel is not None
Expand Down Expand Up @@ -373,7 +373,7 @@ def abort(_):
del self._socket_waiters[which][sock]
return _core.Abort.SUCCEEDED

await _core.yield_indefinitely(abort)
await _core.wait_task_rescheduled(abort)

@_public
@_hazmat
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_parking_lot.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ async def park(self):
"""
task = _core.current_task()
self._parked[task] = None
await _core.yield_indefinitely(self._abort_func_for(task))
await _core.wait_task_rescheduled(self._abort_func_for(task))

def _pop_several(self, count):
for _ in range(min(count, len(self._parked))):
Expand Down
14 changes: 7 additions & 7 deletions trio/_core/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from ._traps import (
cancel_shielded_checkpoint,
Abort,
yield_indefinitely,
wait_task_rescheduled,
YieldBrieflyNoCancel,
YieldIndefinitely,
)
Expand Down Expand Up @@ -829,18 +829,18 @@ def reschedule(self, task, next_send=Value(None)):
"""Reschedule the given task with the given
:class:`~trio.hazmat.Result`.
See :func:`yield_indefinitely` for the gory details.
See :func:`wait_task_rescheduled` for the gory details.
There must be exactly one call to :func:`reschedule` for every call to
:func:`yield_indefinitely`. (And when counting, keep in mind that
:func:`wait_task_rescheduled`. (And when counting, keep in mind that
returning :data:`Abort.SUCCEEDED` from an abort callback is equivalent
to calling :func:`reschedule` once.)
Args:
task (trio.hazmat.Task): the task to be rescheduled. Must be blocked
in a call to :func:`yield_indefinitely`.
in a call to :func:`wait_task_rescheduled`.
next_send (trio.hazmat.Result): the value (or error) to return (or
raise) from :func:`yield_indefinitely`.
raise) from :func:`wait_task_rescheduled`.
"""
assert task._runner is self
Expand Down Expand Up @@ -1341,7 +1341,7 @@ def abort(_):
del self.waiting_for_idle[key]
return Abort.SUCCEEDED

await yield_indefinitely(abort)
await wait_task_rescheduled(abort)

################
# Instrumentation
Expand Down Expand Up @@ -1756,7 +1756,7 @@ async def checkpoint():
"""
with open_cancel_scope(deadline=-inf) as scope:
await _core.yield_indefinitely(lambda _: _core.Abort.SUCCEEDED)
await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)


@_hazmat
Expand Down
14 changes: 7 additions & 7 deletions trio/_core/_traps.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from . import _hazmat

__all__ = ["cancel_shielded_checkpoint", "Abort", "yield_indefinitely"]
__all__ = ["cancel_shielded_checkpoint", "Abort", "wait_task_rescheduled"]


# Decorator to turn a generator into a well-behaved async function:
Expand Down Expand Up @@ -53,7 +53,7 @@ def cancel_shielded_checkpoint():
class Abort(enum.Enum):
""":class:`enum.Enum` used as the return value from abort functions.
See :func:`yield_indefinitely` for details.
See :func:`wait_task_rescheduled` for details.
.. data:: SUCCEEDED
FAILED
Expand All @@ -71,7 +71,7 @@ class YieldIndefinitely:

@_hazmat
@asyncfunction
def yield_indefinitely(abort_func):
def wait_task_rescheduled(abort_func):
"""Put the current task to sleep, with cancellation support.
This is the lowest-level API for blocking in trio. Every time a
Expand All @@ -85,7 +85,7 @@ def yield_indefinitely(abort_func):
arrangements for "someone" to call :func:`reschedule` on the current task
at some later point.
Then you call :func:`yield_indefinitely`, passing in ``abort_func``, an
Then you call :func:`wait_task_rescheduled`, passing in ``abort_func``, an
"abort callback".
(Terminology: in trio, "aborting" is the process of attempting to
Expand All @@ -94,7 +94,7 @@ def yield_indefinitely(abort_func):
There are two possibilities for what happens next:
1. "Someone" calls :func:`reschedule` on the current task, and
:func:`yield_indefinitely` returns or raises whatever value or error
:func:`wait_task_rescheduled` returns or raises whatever value or error
was passed to :func:`reschedule`.
2. The call's context transitions to a cancelled state (e.g. due to a
Expand Down Expand Up @@ -145,13 +145,13 @@ def abort(inner_raise_cancel):
outer_raise_cancel = inner_raise_cancel
TRY_TO_CANCEL_OPERATION()
return trio.hazmat.Abort.FAILED
await yield_indefinitely(abort)
await wait_task_rescheduled(abort)
if OPERATION_WAS_SUCCESSFULLY_CANCELLED:
# raises the error
outer_raise_cancel()
In any case it's guaranteed that we only call the ``abort_func`` at most
once per call to :func:`yield_indefinitely`.
once per call to :func:`wait_task_rescheduled`.
.. warning::
Expand Down
8 changes: 5 additions & 3 deletions trio/_core/tests/test_ki.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ async def raiser(name, record):
# If we didn't raise (b/c protected), then we *should* get
# cancelled at the next opportunity
try:
await _core.yield_indefinitely(lambda _: _core.Abort.SUCCEEDED)
await _core.wait_task_rescheduled(
lambda _: _core.Abort.SUCCEEDED
)
except _core.Cancelled:
record.add((name + " cancel ok"))

Expand Down Expand Up @@ -335,7 +337,7 @@ def abort(_):
_core.reschedule(task, _core.Value(1))
return _core.Abort.FAILED

assert await _core.yield_indefinitely(abort) == 1
assert await _core.wait_task_rescheduled(abort) == 1
with pytest.raises(KeyboardInterrupt):
await _core.checkpoint()

Expand All @@ -356,7 +358,7 @@ def abort(raise_cancel):
return _core.Abort.FAILED

with pytest.raises(KeyboardInterrupt):
assert await _core.yield_indefinitely(abort)
assert await _core.wait_task_rescheduled(abort)
await _core.checkpoint()

_core.run(main)
Expand Down
10 changes: 5 additions & 5 deletions trio/_core/tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# its rescheduled with, which is really only useful for tests of
# rescheduling...
async def sleep_forever():
return await _core.yield_indefinitely(lambda _: _core.Abort.SUCCEEDED)
return await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)


# Some of our tests need to leak coroutines, and thus trigger the
Expand Down Expand Up @@ -949,7 +949,7 @@ async def stubborn_sleeper():
with _core.open_cancel_scope() as scope:
stubborn_scope[0] = scope
record.append("sleep")
x = await _core.yield_indefinitely(lambda _: _core.Abort.FAILED)
x = await _core.wait_task_rescheduled(lambda _: _core.Abort.FAILED)
assert x == 1
record.append("woke")
try:
Expand Down Expand Up @@ -985,7 +985,7 @@ async def main():
with _core.open_cancel_scope() as scope:
scope.cancel()
# None is not a legal return value here
await _core.yield_indefinitely(lambda _: None)
await _core.wait_task_rescheduled(lambda _: None)

with pytest.raises(_core.TrioInternalError):
_core.run(main)
Expand Down Expand Up @@ -1447,7 +1447,7 @@ def slow_abort(raise_cancel):
call_soon(_core.reschedule, task, result)
return _core.Abort.FAILED

await _core.yield_indefinitely(slow_abort)
await _core.wait_task_rescheduled(slow_abort)


async def test_slow_abort_edge_cases():
Expand All @@ -1465,7 +1465,7 @@ def slow_abort(raise_cancel):

with pytest.raises(_core.Cancelled):
record.append("sleeping")
await _core.yield_indefinitely(slow_abort)
await _core.wait_task_rescheduled(slow_abort)
record.append("cancelled")
# blocking again, this time it's okay, because we're shielded
await _core.checkpoint()
Expand Down
2 changes: 1 addition & 1 deletion trio/_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,4 @@ def abort(_):
else:
return _core.Abort.FAILED

return await _core.yield_indefinitely(abort)
return await _core.wait_task_rescheduled(abort)
2 changes: 1 addition & 1 deletion trio/_timeouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async def sleep_forever():
Equivalent to calling ``await sleep(math.inf)``.
"""
await _core.yield_indefinitely(lambda _: _core.Abort.SUCCEEDED)
await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)


async def sleep_until(deadline):
Expand Down
2 changes: 1 addition & 1 deletion trio/tests/test_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def test_await_in_trio_thread_while_main_exits():
async def trio_fn():
record.append("sleeping")
ev.set()
await _core.yield_indefinitely(lambda _: _core.Abort.SUCCEEDED)
await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)

def thread_fn(await_in_trio_thread):
try:
Expand Down
2 changes: 1 addition & 1 deletion trio/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,6 @@ def test_module_metadata_is_fixed_up():
assert trio.open_cancel_scope.__module__ == "trio"
assert trio.ssl.SSLStream.__module__ == "trio.ssl"
assert trio.abc.Stream.__module__ == "trio.abc"
assert trio.hazmat.yield_indefinitely.__module__ == "trio.hazmat"
assert trio.hazmat.wait_task_rescheduled.__module__ == "trio.hazmat"
import trio.testing
assert trio.testing.trio_test.__module__ == "trio.testing"

0 comments on commit 68a1898

Please sign in to comment.