summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/run.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/idlelib/run.py')
-rw-r--r--Lib/idlelib/run.py130
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)