diff options
Diffstat (limited to 'Lib/idlelib/run.py')
| -rw-r--r-- | Lib/idlelib/run.py | 130 | 
1 files changed, 75 insertions, 55 deletions
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 497cbbd..320525c 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -1,4 +1,5 @@  import sys +import os  import time  import socket  import traceback @@ -20,12 +21,8 @@ import __main__  # the socket) and the main thread (which runs user code), plus global  # completion and exit flags: -server = None                # RPCServer instance -queue = Queue.Queue(0) -execution_finished = False  exit_requested = False -  def main():      """Start the Python execution server in a subprocess @@ -44,8 +41,6 @@ def main():      register and unregister themselves.      """ -    global queue, execution_finished, exit_requested -      port = 8833      if sys.argv[1:]:          port = int(sys.argv[1]) @@ -58,21 +53,23 @@ def main():      while 1:          try:              if exit_requested: -                sys.exit() -            # XXX KBK 22Mar03 eventually check queue here! -            pass -            time.sleep(0.05) +                os._exit(0) +            try: +                seq, request = rpc.request_queue.get(0) +            except Queue.Empty: +                time.sleep(0.05) +                continue +            method, args, kwargs = request +            ret = method(*args, **kwargs) +            rpc.response_queue.put((seq, ret))          except KeyboardInterrupt: -            ##execution_finished = True              continue  def manage_socket(address): -    global server, exit_requested -      for i in range(6):          time.sleep(i)          try: -            server = rpc.RPCServer(address, MyHandler) +            server = MyRPCServer(address, MyHandler)              break          except socket.error, err:              if i < 3: @@ -82,10 +79,41 @@ def manage_socket(address):                                                + err[1] + ", retrying...."      else:          print>>sys.__stderr__, "\nConnection to Idle failed, exiting." +        global exit_requested          exit_requested = True +        return      server.handle_request() # A single request only +class MyRPCServer(rpc.RPCServer): + +    def handle_error(self, request, client_address): +        """Override RPCServer method for IDLE + +        Interrupt the MainThread and exit server if link is dropped. + +        """ +        try: +            raise +        except SystemExit: +            raise +        except EOFError: +            global exit_requested +            exit_requested = True +            interrupt.interrupt_main() +        except: +            erf = sys.__stderr__ +            print>>erf, '\n' + '-'*40 +            print>>erf, 'Unhandled server exception!' +            print>>erf, 'Thread: %s' % threading.currentThread().getName() +            print>>erf, 'Client Address: ', client_address +            print>>erf, 'Request: ', repr(request) +            traceback.print_exc(file=erf) +            print>>erf, '\n*** Unrecoverable, server exiting!' +            print>>erf, '-'*40 +            os._exit(0) + +  class MyHandler(rpc.RPCHandler):      def handle(self): @@ -95,7 +123,20 @@ class MyHandler(rpc.RPCHandler):          sys.stdin = self.get_remote_proxy("stdin")          sys.stdout = self.get_remote_proxy("stdout")          sys.stderr = self.get_remote_proxy("stderr") -        rpc.RPCHandler.getresponse(self, myseq=None, wait=0.5) +        rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) + +    def exithook(self): +        "override SocketIO method - wait for MainThread to shut us down" +        while 1: pass + +    def EOFhook(self): +        "Override SocketIO method - terminate wait on callback and exit thread" +        global exit_requested +        exit_requested = True + +    def decode_interrupthook(self): +        "interrupt awakened thread" +        interrupt.interrupt_main()  class Executive: @@ -106,44 +147,30 @@ class Executive:          self.calltip = CallTips.CallTips()      def runcode(self, code): -        global queue, execution_finished - -        execution_finished = False -        queue.put(code) -        # dequeue and run in subthread -        self.runcode_from_queue() -        while not execution_finished: -            time.sleep(0.05) - -    def runcode_from_queue(self): -        global queue, execution_finished - -        # poll until queue has code object, using threads, just block? -        while True: -            try: -                code = queue.get(0) -                break -            except Queue.Empty: -                time.sleep(0.05)          try:              exec code in self.locals          except: -            self.flush_stdout() -            efile = sys.stderr -            typ, val, tb = info = sys.exc_info() -            sys.last_type, sys.last_value, sys.last_traceback = info -            tbe = traceback.extract_tb(tb) -            print >>efile, 'Traceback (most recent call last):' -            exclude = ("run.py", "rpc.py", "RemoteDebugger.py", "bdb.py") -            self.cleanup_traceback(tbe, exclude) -            traceback.print_list(tbe, file=efile) -            lines = traceback.format_exception_only(typ, val) -            for line in lines: -                print>>efile, line, -            execution_finished = True +            try: +                if exit_requested: +                    os._exit(0) +                self.flush_stdout() +                efile = sys.stderr +                typ, val, tb = info = sys.exc_info() +                sys.last_type, sys.last_value, sys.last_traceback = info +                tbe = traceback.extract_tb(tb) +                print >>efile, 'Traceback (most recent call last):' +                exclude = ("run.py", "rpc.py", "threading.py", +                           "RemoteDebugger.py", "bdb.py") +                self.cleanup_traceback(tbe, exclude) +                traceback.print_list(tbe, file=efile) +                lines = traceback.format_exception_only(typ, val) +                for line in lines: +                    print>>efile, line, +            except: +                sys.stderr = sys.__stderr__ +                raise          else:              self.flush_stdout() -            execution_finished = True      def flush_stdout(self):          try: @@ -184,15 +211,8 @@ class Executive:              tb[i] = fn, ln, nm, line      def interrupt_the_server(self): -        self.rpchandler.interrupted = True -        ##print>>sys.__stderr__, "** Interrupt main!"          interrupt.interrupt_main() -    def shutdown_the_server(self): -        global exit_requested - -        exit_requested = True -      def start_the_debugger(self, gui_adap_oid):          return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)  | 
