Esempio n. 1
0
 def add_callback(self, callback, *args, **kwargs):
     if thread.get_ident() != self._thread_ident:
         # If we're not on the IOLoop's thread, we need to synchronize
         # with other threads, or waking logic will induce a race.
         with self._callback_lock:
             if self._closing:
                 return
             list_empty = not self._callbacks
             self._callbacks.append(
                 functools.partial(stack_context.wrap(callback), *args,
                                   **kwargs))
             if list_empty:
                 # If we're not in the IOLoop's thread, and we added the
                 # first callback to an empty list, we may need to wake it
                 # up (it may wake up on its own, but an occasional extra
                 # wake is harmless).  Waking up a polling IOLoop is
                 # relatively expensive, so we try to avoid it when we can.
                 self._waker.wake()
     else:
         if self._closing:
             return
         # If we're on the IOLoop's thread, we don't need the lock,
         # since we don't need to wake anyone, just add the
         # callback. Blindly insert into self._callbacks. This is
         # safe even from signal handlers because the GIL makes
         # list.append atomic. One subtlety is that if the signal
         # is interrupting another thread holding the
         # _callback_lock block in IOLoop.start, we may modify
         # either the old or new version of self._callbacks, but
         # either way will work.
         self._callbacks.append(
             functools.partial(stack_context.wrap(callback), *args,
                               **kwargs))
Esempio n. 2
0
 def call_at(self, deadline, callback, *args, **kwargs):
     timeout = _Timeout(
         deadline,
         functools.partial(stack_context.wrap(callback), *args, **kwargs),
         self)
     heapq.heappush(self._timeouts, timeout)
     return timeout
Esempio n. 3
0
    def add_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))
Esempio n. 4
0
File: gen.py Progetto: yetone/hurray
    def wrapper(*args, **kwargs):
        future = func(*args, **kwargs)

        def final_callback(future):
            if future.result() is not None:
                raise ReturnValueIgnoredError(
                    "@gen.engine functions cannot return values: %r" %
                    (future.result(), ))

        # The engine interface doesn't give us any way to return
        # errors but to raise them into the stack context.
        # Save the stack context here to use when the Future has resolved.
        future.add_done_callback(stack_context.wrap(final_callback))
Esempio n. 5
0
    def set_exit_callback(self, callback):
        """Runs ``callback`` when this process exits.

        The callback takes one argument, the return code of the process.

        This method uses a ``SIGCHLD`` handler, which is a global setting
        and may conflict if you have other libraries trying to handle the
        same signal.  If you are using more than one ``IOLoop`` it may
        be necessary to call `Subprocess.initialize` first to designate
        one ``IOLoop`` to run the signal handlers.

        In many cases a close callback on the stdout or stderr streams
        can be used as an alternative to an exit callback if the
        signal handler is causing a problem.
        """
        self._exit_callback = stack_context.wrap(callback)
        Subprocess.initialize(self.io_loop)
        Subprocess._waiting[self.pid] = self
        Subprocess._try_cleanup_process(self.pid)
Esempio n. 6
0
    def wrapper(*args, **kwargs):
        future = TracebackFuture()
        callback, args, kwargs = replacer.replace(
            lambda value=_NO_RESULT: future.set_result(value), args, kwargs)

        def handle_error(typ, value, tb):
            future.set_exc_info((typ, value, tb))
            return True

        exc_info = None
        with ExceptionStackContext(handle_error):
            try:
                result = f(*args, **kwargs)
                if result is not None:
                    raise ReturnValueIgnoredError(
                        "@return_future should not be used with functions "
                        "that return values")
            except:
                exc_info = sys.exc_info()
                raise
        if exc_info is not None:
            # If the initial synchronous part of f() raised an exception,
            # go ahead and raise it to the caller directly without waiting
            # for them to inspect the Future.
            future.result()

        # If the caller passed in a callback, schedule it to be called
        # when the future resolves.  It is important that this happens
        # just before we return the future, or else we risk confusing
        # stack contexts with multiple exceptions (one here with the
        # immediate exception, and again when the future resolves and
        # the callback triggers its exception by calling future.result()).
        if callback is not None:

            def run_callback(future):
                result = future.result()
                if result is _NO_RESULT:
                    callback()
                else:
                    callback(future.result())

            future.add_done_callback(wrap(run_callback))
        return future
Esempio n. 7
0
File: gen.py Progetto: yetone/hurray
 def result_callback(self, key):
     return stack_context.wrap(
         _argument_adapter(functools.partial(self.set_result, key)))
Esempio n. 8
0
 def add_parse_callback(self, callback):
     """Adds a parse callback, to be invoked when option parsing is done."""
     self._parse_callbacks.append(stack_context.wrap(callback))
Esempio n. 9
0
 def add_handler(self, fd, handler, events):
     fd, obj = self.split_fd(fd)
     self._handlers[fd] = (obj, stack_context.wrap(handler))
     self._impl.register(fd, events | self.ERROR)