##// END OF EJS Templates
MTInteractiveShell: implement "code received" event in runsource & runcode to prevent hanging indefinitely when the mainloop is dead (typical with -gthread) if you close the window
Ville M. Vainio -
Show More
@@ -22,7 +22,7 b" name = 'ipython'"
22 22 # because bdist_rpm does not accept dashes (an RPM) convention, and
23 23 # bdist_deb does not accept underscores (a Debian convention).
24 24
25 revision = '46'
25 revision = '52'
26 26
27 27 version = '0.8.3.bzr.r' + revision
28 28
@@ -372,6 +372,7 b' class MTInteractiveShell(InteractiveShell):'
372 372 self.on_kill = on_kill
373 373 # thread identity of the "worker thread" (that may execute code directly)
374 374 self.worker_ident = None
375
375 376 def runsource(self, source, filename="<input>", symbol="single"):
376 377 """Compile and run some source in the interpreter.
377 378
@@ -411,9 +412,18 b' class MTInteractiveShell(InteractiveShell):'
411 412 # Case 3
412 413 # Store code in queue, so the execution thread can handle it.
413 414
414 ev = threading.Event()
415 self.code_queue.put((code,ev))
416 ev.wait()
415 completed_ev, received_ev = threading.Event(), threading.Event()
416
417 self.code_queue.put((code,completed_ev, received_ev))
418 # first make sure the message was received, with timeout
419 received_ev.wait(5)
420 if not received_ev.isSet():
421 # the mainloop is dead, start executing code directly
422 print "Warning: Timeout for mainloop thread exceeded"
423 print "switching to nonthreaded mode (until mainloop wakes up again)"
424 self.worker_ident = None
425 else:
426 completed_ev.wait()
417 427 return False
418 428
419 429 def runcode(self):
@@ -450,9 +460,11 b' class MTInteractiveShell(InteractiveShell):'
450 460 code_to_run = None
451 461 while 1:
452 462 try:
453 code_to_run, event = self.code_queue.get_nowait()
463 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
454 464 except Queue.Empty:
455 465 break
466 received_ev.set()
467
456 468 # Exceptions need to be raised differently depending on which
457 469 # thread is active. This convoluted try/except is only there to
458 470 # protect against asynchronous exceptions, to ensure that a KBINT
@@ -466,13 +478,14 b' class MTInteractiveShell(InteractiveShell):'
466 478 except KeyboardInterrupt:
467 479 print "Keyboard interrupted in mainloop"
468 480 while not self.code_queue.empty():
469 code, ev = self.code_queue.get_nowait()
470 ev.set()
481 code, ev1,ev2 = self.code_queue.get_nowait()
482 ev1.set()
483 ev2.set()
471 484 break
472 485 finally:
473 486 CODE_RUN = False
474 487 # allow runsource() return from wait
475 event.set()
488 completed_ev.set()
476 489
477 490
478 491 # This MUST return true for gtk threading to work
General Comments 0
You need to be logged in to leave comments. Login now