def until_any(*futures, **kwargs):
    """Return a future that resolves when any of the passed futures resolves.

    Resolves with the value yielded by the first future to resolve.

    Note, this will only work with tornado futures.

    """
    timeout = kwargs.get('timeout', None)
    ioloop = kwargs.get('ioloop', None) or tornado.ioloop.IOLoop.current()
    any_future = tornado_Future()

    def handle_done(done_future):
        if not any_future.done():
            try:
                any_future.set_result(done_future.result())
            except Exception:
                any_future.set_exc_info(done_future.exc_info())
            # (NM) Nasty hack to remove handle_done from the callback list to prevent a
            # memory leak where one of the futures resolves quickly, particularly when
            # used together with AsyncState.until_state(). Also addresses Jira issue
            # CM-593
            for f in futures:
                if f._callbacks:
                    try:
                        f._callbacks.remove(handle_done)
                    except ValueError:
                        pass

    for f in futures:
        f.add_done_callback(handle_done)
        if any_future.done():
            break

    if timeout:
        return with_timeout(ioloop.time() + timeout, any_future, ioloop)
    else:
        return any_future
Return a future that resolves when any of the passed futures resolves.

    Resolves with the value yielded by the first future to resolve.

    Note, this will only work with tornado futures.