def wait(self, key, timeout=5, debug=False):
        """Return the cached value for the given key, or None.

        If timeout is not None, and the value is already being
        calculated by another thread, wait until the given timeout has
        elapsed. If the value is available before the timeout expires,
        it is returned. If not, None is returned, and a sentinel placed
        in the cache to signal other threads to wait.

        If timeout is None, no waiting is performed nor sentinels used.
        """
        value = self.get(key)
        if isinstance(value, threading.Event):
            if timeout is None:
                # Ignore the other thread and recalc it ourselves.
                if debug:
                    cherrypy.log('No timeout', 'TOOLS.CACHING')
                return None

            # Wait until it's done or times out.
            if debug:
                cherrypy.log(
                    'Waiting up to %s seconds' % timeout,
                    'TOOLS.CACHING',
                )
            value.wait(timeout)
            if value.result is not None:
                # The other thread finished its calculation. Use it.
                if debug:
                    cherrypy.log('Result!', 'TOOLS.CACHING')
                return value.result
            # Timed out. Stick an Event in the slot so other threads wait
            # on this one to finish calculating the value.
            if debug:
                cherrypy.log('Timed out', 'TOOLS.CACHING')
            e = threading.Event()
            e.result = None
            dict.__setitem__(self, key, e)

            return None
        elif value is None:
            # Stick an Event in the slot so other threads wait
            # on this one to finish calculating the value.
            if debug:
                cherrypy.log('Timed out', 'TOOLS.CACHING')
            e = threading.Event()
            e.result = None
            dict.__setitem__(self, key, e)
        return value
Return the cached value for the given key, or None.

        If timeout is not None, and the value is already being
        calculated by another thread, wait until the given timeout has
        elapsed. If the value is available before the timeout expires,
        it is returned. If not, None is returned, and a sentinel placed
        in the cache to signal other threads to wait.

        If timeout is None, no waiting is performed nor sentinels used.
        
cherrypy/lib/caching.py