Esempio n. 1
0
def loop(condition, timeout=None):
    """
    Executes the main loop until condition is met.

    This function may be called recursively, however two loops may not
    run in parallel threads.

    :param condition: a callable or object that is evaluated after each step
                      of the loop.  If it evaluates False, the loop
                      terminates.  (If condition is therefore ``True``, the
                      loop will run forever.)
    :param timeout: number of seconds after which the loop will terminate
                    (regardless of the condition).
    """
    _loop_lock.acquire()
    if is_running() and not is_mainthread():
        # race condition. Two threads started a mainloop and the other
        # one is executed right now. Raise a RuntimeError
        _loop_lock.release()
        raise RuntimeError('loop running in a different thread')

    initial_mainloop = False
    if not is_running():
        # no mainloop is running, set this thread as mainloop and
        # set the internal running state.
        initial_mainloop = True
        set_as_mainthread()
        _set_running(True)
    # ok, that was the critical part
    _loop_lock.release()

    if not callable(condition):
        condition = lambda: condition

    abort = []
    if timeout is not None:
        # timeout handling to stop the mainloop after the given timeout
        # even when the condition is still True.
        sec = timeout
        timeout = OneShotTimer(lambda: abort.append(True))
        timeout.start(sec)

    try:
        while condition() and not abort:
            try:
                notifier.step()
                signals['step'].emit()
            except BaseException, e:
                if signals['exception'].emit(*sys.exc_info()) != False:
                    # Either there are no global exception handlers, or none of
                    # them explicitly returned False to abort mainloop
                    # termination.  So abort the main loop.
                    type, value, tb = sys.exc_info()
                    raise type, value, tb
    finally:
        # make sure we set mainloop status
        if timeout is not None:
            timeout.stop()
        if initial_mainloop:
            _set_running(False)
Esempio n. 2
0
def delay(seconds):
    """
    Returns an InProgress that finishes after the given time in seconds.

    :param obj: object to represent as an InProgress.
    :return: :class:`~kaa.InProgress`
    """
    ip = InProgressCallback()
    timer = OneShotTimer(ip)
    # If the IP gets aborted, stop the timer.  Otherwise the timer
    # will fire and the IP would attempt to get finished a second
    # time (and would therefore raise an exception).
    ip.signals['abort'].connect_weak(lambda exc: timer.stop())
    timer.start(seconds)
    return ip
Esempio n. 3
0
class EventManager(object):
    """
    Class to manage Event and EventHandler objects.
    Internal use only.
    """
    def __init__(self):
        self.queue = []
        self.locked = False
        self.timer = OneShotTimer(self.handle)
        self.handler = []


    def post(self, event):
        """
        Add event to the queue.
        """
        self.queue.append(event)
        if not self.timer.active:
            self.timer.start(0)


    def handle(self):
        """
        Handle the next event.
        """
        if self.locked:
            self.timer.start(0.01)
            return
        if not self.queue:
            return
        self.locked = True
        event = self.queue[0]
        self.queue = self.queue[1:]

        try:
            for handler in copy.copy(self.handler):
                handler(event)
        except Exception, e:
            log.exception('event callback')
        self.locked = False
        if self.queue and not self.timer.active:
            self.timer.start(0)
Esempio n. 4
0
 def __init__(self):
     self.queue = []
     self.locked = False
     self.timer = OneShotTimer(self.handle)
     self.handler = []