code: def future_timeout_manager(timeout=None, ioloop=None):
      
      ioloop = ioloop or tornado.ioloop.IOLoop.current()
      t0 = ioloop.time()
  
      def _remaining():
          return timeout - (ioloop.time() - t0) if timeout else None
  
      def maybe_timeout(f):
          """Applies timeout if timeout is not None"""
          if not timeout:
              return f
          else:
              remaining = _remaining()
              deadline = ioloop.time() + remaining
              return with_timeout(deadline, f, ioloop)
  
      maybe_timeout.remaining = _remaining
  
      return maybe_timeout
docs: Create Helper function for yielding with a cumulative timeout if required
  
      Keeps track of time over multiple timeout calls so that a single timeout can
      be placed over multiple operations.
  
      Parameters
      ----------
      timeout : int or None
          Timeout, or None for no timeout
      ioloop : IOLoop instance or None
          tornado IOloop instance to use, or None for IOLoop.current()
  
      Return value
      ------------
  
      maybe_timeout : func
          Accepts a future, and wraps it in
          :func:tornado.gen.with_timeout. maybe_timeout raises
          :class:`tornado.gen.TimeoutError` if the timeout expires
  
          Has a function attribute `remaining()` that returns the remaining
          timeout or None if timeout == None
  
      Example
      -------
  
      ::
  
      @tornado.gen.coroutine
      def multi_op(timeout):
          maybe_timeout = future_timeout_manager(timeout)
          result1 = yield maybe_timeout(op1())
          result2 = yield maybe_timeout(op2())
          # If the cumulative time of op1 and op2 exceeds timeout,
          # :class:`tornado.gen.TimeoutError` is raised