# ioloop.py IOLoop defadd_future(self, future, callback): """Schedules a callback on the ``IOLoop`` when the given `.Future` is finished. The callback is invoked with one argument, the `.Future`. """ assert is_future(future) callback = stack_context.wrap(callback) future.add_done_callback( lambda future: self.add_callback(callback, future))
# gen.py Runner defhandle_yield(self, yielded): # Lists containing YieldPoints require stack contexts; # other lists are handled via multi_future in convert_yielded. if (isinstance(yielded, list) and any(isinstance(f, YieldPoint) for f in yielded)): yielded = Multi(yielded) elif (isinstance(yielded, dict) and any(isinstance(f, YieldPoint) for f in yielded.values())): yielded = Multi(yielded)
# gen.py Runner defrun(self): """Starts or resumes the generator, running until it reaches a yield point that is not ready. """ if self.running or self.finished: return try: self.running = True whileTrue: future = self.future ifnot future.done(): return self.future = None try: orig_stack_contexts = stack_context._state.contexts exc_info = None
if stack_context._state.contexts isnot orig_stack_contexts: self.gen.throw( stack_context.StackContextInconsistentError( 'stack_context inconsistency (probably caused ' 'by yield within a "with StackContext" block)')) except (StopIteration, Return) as e: self.finished = True self.future = _null_future if self.pending_callbacks andnot self.had_exception: # If we ran cleanly without waiting on all callbacks # raise an error (really more of a warning). If we # had an exception then some callbacks may have been # orphaned, so skip the check in that case. raise LeakedCallbackError( "finished without waiting for callbacks %r" % self.pending_callbacks) self.result_future.set_result(getattr(e, 'value', None)) self.result_future = None self._deactivate_stack_context() return except Exception: self.finished = True self.future = _null_future self.result_future.set_exc_info(sys.exc_info()) self.result_future = None self._deactivate_stack_context() return ifnot self.handle_yield(yielded): return finally: self.running = False