kopia lustrzana https://github.com/micropython/micropython
extmod/uasyncio: Allow task state to be a callable.
This implements a form of CPython's "add_done_callback()", but at this stage it is a hidden feature and only intended to be used internally. Signed-off-by: Damien George <damien@micropython.org>pull/8459/head
rodzic
a41bc5a7ca
commit
335002a4c0
|
@ -265,6 +265,9 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
||||||
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
|
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
|
||||||
// Allocate the waiting queue.
|
// Allocate the waiting queue.
|
||||||
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
|
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
|
||||||
|
} else if (mp_obj_get_type(self->state) != &task_queue_type) {
|
||||||
|
// Task has state used for another purpose, so can't also wait on it.
|
||||||
|
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't wait"));
|
||||||
}
|
}
|
||||||
return self_in;
|
return self_in;
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,6 +195,11 @@ def run_until_complete(main_task=None):
|
||||||
if t.state is True:
|
if t.state is True:
|
||||||
# "None" indicates that the task is complete and not await'ed on (yet).
|
# "None" indicates that the task is complete and not await'ed on (yet).
|
||||||
t.state = None
|
t.state = None
|
||||||
|
elif callable(t.state):
|
||||||
|
# The task has a callback registered to be called on completion.
|
||||||
|
t.state(t, er)
|
||||||
|
t.state = False
|
||||||
|
waiting = True
|
||||||
else:
|
else:
|
||||||
# Schedule any other tasks waiting on the completion of this task.
|
# Schedule any other tasks waiting on the completion of this task.
|
||||||
while t.state.peek():
|
while t.state.peek():
|
||||||
|
|
|
@ -123,7 +123,7 @@ class Task:
|
||||||
def __init__(self, coro, globals=None):
|
def __init__(self, coro, globals=None):
|
||||||
self.coro = coro # Coroutine of this Task
|
self.coro = coro # Coroutine of this Task
|
||||||
self.data = None # General data for queue it is waiting on
|
self.data = None # General data for queue it is waiting on
|
||||||
self.state = True # None, False, True or a TaskQueue instance
|
self.state = True # None, False, True, a callable, or a TaskQueue instance
|
||||||
self.ph_key = 0 # Pairing heap
|
self.ph_key = 0 # Pairing heap
|
||||||
self.ph_child = None # Paring heap
|
self.ph_child = None # Paring heap
|
||||||
self.ph_child_last = None # Paring heap
|
self.ph_child_last = None # Paring heap
|
||||||
|
@ -137,6 +137,9 @@ class Task:
|
||||||
elif self.state is True:
|
elif self.state is True:
|
||||||
# Allocated head of linked list of Tasks waiting on completion of this task.
|
# Allocated head of linked list of Tasks waiting on completion of this task.
|
||||||
self.state = TaskQueue()
|
self.state = TaskQueue()
|
||||||
|
elif type(self.state) is not TaskQueue:
|
||||||
|
# Task has state used for another purpose, so can't also wait on it.
|
||||||
|
raise RuntimeError("can't wait")
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
|
|
Ładowanie…
Reference in New Issue