def runsource(self, source, filename="<input>", symbol="single"):
        """Compile and run some source in the interpreter.

        Modified version of code.py's runsource(), to handle threading issues.
        See the original for full docstring details."""

        # If Ctrl-C was typed, we reset the flag and return right away
        if shellglobals.KBINT:
            shellglobals.KBINT = False
            return False

        if self._kill:
            # can't queue new code if we are being killed
            return True

        try:
            code = self.compile(source, filename, symbol)
        except (OverflowError, SyntaxError, ValueError):
            # Case 1
            self.showsyntaxerror(filename)
            return False

        if code is None:
            # Case 2
            return True

        # shortcut - if we are in worker thread, or the worker thread is not running,
        # execute directly (to allow recursion and prevent deadlock if code is run early
        # in IPython construction)

        if (not self.reactor_started
                or (self.worker_ident is None and not self.first_run)
                or self.worker_ident == thread.get_ident()
                or shellglobals.run_in_frontend(source)):
            InteractiveShell.runcode(self, code)
            return

        # Case 3
        # Store code in queue, so the execution thread can handle it.

        self.first_run = False
        completed_ev, received_ev = threading.Event(), threading.Event()

        self.code_queue.put((code, completed_ev, received_ev))

        reactor.callLater(0.0, self.runcode)
        received_ev.wait(5)
        if not received_ev.isSet():
            # the mainloop is dead, start executing code directly
            print "Warning: Timeout for mainloop thread exceeded"
            print "switching to nonthreaded mode (until mainloop wakes up again)"
            self.worker_ident = None
        else:
            completed_ev.wait()

        return False
Beispiel #2
0
    def runsource(self, source, filename="<input>", symbol="single"):
        """Compile and run some source in the interpreter.

        Modified version of code.py's runsource(), to handle threading issues.
        See the original for full docstring details."""
        
        # If Ctrl-C was typed, we reset the flag and return right away
        if shellglobals.KBINT:
            shellglobals.KBINT = False
            return False

        if self._kill:
            # can't queue new code if we are being killed
            return True
        
        try:
            code = self.compile(source, filename, symbol)
        except (OverflowError, SyntaxError, ValueError):
            # Case 1
            self.showsyntaxerror(filename)
            return False

        if code is None:
            # Case 2
            return True

        # shortcut - if we are in worker thread, or the worker thread is not running, 
        # execute directly (to allow recursion and prevent deadlock if code is run early 
        # in IPython construction)
        
        if (not self.reactor_started or (self.worker_ident is None and not self.first_run) 
            or self.worker_ident == thread.get_ident() or shellglobals.run_in_frontend(source)):
            InteractiveShell.runcode(self,code)
            return

        # Case 3
        # Store code in queue, so the execution thread can handle it.
 
        self.first_run = False
        completed_ev, received_ev = threading.Event(), threading.Event() 
        
        self.code_queue.put((code,completed_ev, received_ev))

        reactor.callLater(0.0,self.runcode)
        received_ev.wait(5)
        if not received_ev.isSet():
            # the mainloop is dead, start executing code directly
            print "Warning: Timeout for mainloop thread exceeded"
            print "switching to nonthreaded mode (until mainloop wakes up again)"
            self.worker_ident = None
        else:            
            completed_ev.wait()
        
        return False
Beispiel #3
0
    def runcode(self):
        """Execute a code object.

        Multithreaded wrapper around IPython's runcode()."""
        
        
        # we are in worker thread, stash out the id for runsource() 
        self.worker_ident = thread.get_ident()

        if self._kill:
            print >>Term.cout, 'Closing threads...',
            Term.cout.flush()
            for tokill in self.on_kill:
                tokill()
            print >>Term.cout, 'Done.'
            # allow kill() to return
            self._kill.set()
            return True

        # Install SIGINT handler.  We do it every time to ensure that if user
        # code modifies it, we restore our own handling.
        try:
            pass
            signal(SIGINT,shellglobals.sigint_handler)
        except SystemError:
            # This happens under Windows, which seems to have all sorts
            # of problems with signal handling.  Oh well...
            pass

        # Flush queue of pending code by calling the run methood of the parent
        # class with all items which may be in the queue.
        code_to_run = None
        while 1:
            try:
                code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()                
            except Queue.Empty:
                break
            received_ev.set()

            
            # Exceptions need to be raised differently depending on which
            # thread is active.  This convoluted try/except is only there to
            # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
            # at the wrong time doesn't deadlock everything.  The global
            # CODE_TO_RUN is set to true/false as close as possible to the
            # runcode() call, so that the KBINT handler is correctly informed.
            try:
                try:
                   shellglobals.CODE_RUN = True
                   InteractiveShell.runcode(self,code_to_run)
                except KeyboardInterrupt:
                   print "Keyboard interrupted in mainloop"
                   while not self.code_queue.empty():
                      code = self.code_queue.get_nowait()
                   break
            finally:
                shellglobals.CODE_RUN = False
                # allow runsource() return from wait
                completed_ev.set()                
        
        # This MUST return true for gtk threading to work
        return True
    def runcode(self):
        """Execute a code object.

        Multithreaded wrapper around IPython's runcode()."""

        # we are in worker thread, stash out the id for runsource()
        self.worker_ident = thread.get_ident()

        if self._kill:
            print >> Term.cout, 'Closing threads...',
            Term.cout.flush()
            for tokill in self.on_kill:
                tokill()
            print >> Term.cout, 'Done.'
            # allow kill() to return
            self._kill.set()
            return True

        # Install SIGINT handler.  We do it every time to ensure that if user
        # code modifies it, we restore our own handling.
        try:
            pass
            signal(SIGINT, shellglobals.sigint_handler)
        except SystemError:
            # This happens under Windows, which seems to have all sorts
            # of problems with signal handling.  Oh well...
            pass

        # Flush queue of pending code by calling the run methood of the parent
        # class with all items which may be in the queue.
        code_to_run = None
        while 1:
            try:
                code_to_run, completed_ev, received_ev = self.code_queue.get_nowait(
                )
            except Queue.Empty:
                break
            received_ev.set()

            # Exceptions need to be raised differently depending on which
            # thread is active.  This convoluted try/except is only there to
            # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
            # at the wrong time doesn't deadlock everything.  The global
            # CODE_TO_RUN is set to true/false as close as possible to the
            # runcode() call, so that the KBINT handler is correctly informed.
            try:
                try:
                    shellglobals.CODE_RUN = True
                    InteractiveShell.runcode(self, code_to_run)
                except KeyboardInterrupt:
                    print "Keyboard interrupted in mainloop"
                    while not self.code_queue.empty():
                        code = self.code_queue.get_nowait()
                    break
            finally:
                shellglobals.CODE_RUN = False
                # allow runsource() return from wait
                completed_ev.set()

        # This MUST return true for gtk threading to work
        return True