Example #1
0
class Interpreter_thread(Thread):
    """The threaded interpreter."""

    def __init__(self):
        """Initialise the object."""

        # Set up the thread object.
        Thread.__init__(self)

        # Set the thread to be daemonic so that relax can exit.
        self.daemon = True

        # Create a queue object for the user function calls.
        self._queue = Queue()

        # The list of user functions still in the queue.
        self._uf_list = []

        # A flag for exiting the thread.
        self._exit = False


    def empty(self):
        """Is the queue empty?"""

        # Execution is locked.
        if status.exec_lock.locked():
            return False

        # There are still queued calls.
        elif len(self._uf_list):
            return False

        # The queue is empty.
        else:
            return True


    def exit(self):
        """Cause the thread to exit once all currently queued user functions are processed."""

        # First set the flag.
        self._exit = True

        # Then queue a dummy user function.
        self._queue.put([None, None, None])


    def join(self):
        """Wrapper method for the Queue.join() method."""

        # Join the queue.
        self._queue.join()


    def queue(self, fn, *args, **kwds):
        """Queue up a user function for asynchronous execution.

        @param fn:      The user function as a string.
        @type fn:       str
        @param args:    The user function arguments.
        @type args:     any arguments
        @param kwds:    The user function keyword arguments.
        @type kwds:     any keyword arguments
        """

        # Add the user function name to the list.
        self._uf_list.append(repr(fn))

        # Place the user function and its args onto the queue.
        self._queue.put([fn, args, kwds])


    def run(self):
        """Execute the thread."""

        # Loop until told to exit.
        while not self._exit:
            # Get the user function from the queue.
            fn, args, kwds = self._queue.get()

            # No user function.
            if fn == None:
                continue

            # Execution lock.
            status.exec_lock.acquire('gui', mode='interpreter thread')

            # Execute the user function, catching errors (the nested try-except statements within the try-finally statements are for Python 2.4 and earlier support).
            try:
                try:
                    fn(*args, **kwds)

                # Catch all RelaxErrors.
                except AllRelaxErrors:
                    instance = sys.exc_info()[1]

                    # Display a dialog with the error.
                    wx.CallAfter(gui_raise, instance, raise_flag=False)

                # Handle all other errors.
                except:
                    # Print the exception.
                    print_exc()

            # Release the lock.
            finally:
                # Signal that the queue item has been processed.
                self._queue.task_done()

                # Release the execution lock.
                status.exec_lock.release()

                # Remove the user function from the list.
                self._uf_list.pop(self._uf_list.index(repr(fn)))

            # Notify all observers that a user function has completed.
            status.observers.gui_uf.notify()
Example #2
0
class Interpreter_thread(Thread):
    """The threaded interpreter."""
    def __init__(self):
        """Initialise the object."""

        # Set up the thread object.
        Thread.__init__(self)

        # Set the thread to be daemonic so that relax can exit.
        self.daemon = True

        # Create a queue object for the user function calls.
        self._queue = Queue()

        # The list of user functions still in the queue.
        self._uf_list = []

        # A flag for exiting the thread.
        self._exit = False

    def empty(self):
        """Is the queue empty?"""

        # Execution is locked.
        if status.exec_lock.locked():
            return False

        # There are still queued calls.
        elif len(self._uf_list):
            return False

        # The queue is empty.
        else:
            return True

    def exit(self):
        """Cause the thread to exit once all currently queued user functions are processed."""

        # First set the flag.
        self._exit = True

        # Then queue a dummy user function.
        self._queue.put([None, None, None])

    def join(self):
        """Wrapper method for the Queue.join() method."""

        # Join the queue.
        self._queue.join()

    def queue(self, fn, *args, **kwds):
        """Queue up a user function for asynchronous execution.

        @param fn:      The user function as a string.
        @type fn:       str
        @param args:    The user function arguments.
        @type args:     any arguments
        @param kwds:    The user function keyword arguments.
        @type kwds:     any keyword arguments
        """

        # Add the user function name to the list.
        self._uf_list.append(repr(fn))

        # Place the user function and its args onto the queue.
        self._queue.put([fn, args, kwds])

    def run(self):
        """Execute the thread."""

        # Loop until told to exit.
        while not self._exit:
            # Get the user function from the queue.
            fn, args, kwds = self._queue.get()

            # No user function.
            if fn == None:
                continue

            # Execution lock.
            status.exec_lock.acquire('gui', mode='interpreter thread')

            # Execute the user function, catching errors (the nested try-except statements within the try-finally statements are for Python 2.4 and earlier support).
            try:
                try:
                    fn(*args, **kwds)

                # Catch all RelaxErrors.
                except AllRelaxErrors:
                    instance = sys.exc_info()[1]

                    # Display a dialog with the error.
                    wx.CallAfter(gui_raise, instance, raise_flag=False)

                # Handle all other errors.
                except:
                    # Print the exception.
                    print_exc()

            # Release the lock.
            finally:
                # Signal that the queue item has been processed.
                self._queue.task_done()

                # Release the execution lock.
                status.exec_lock.release()

                # Remove the user function from the list.
                self._uf_list.pop(self._uf_list.index(repr(fn)))

            # Notify all observers that a user function has completed.
            status.observers.gui_uf.notify()