Show More
@@ -375,7 +375,8 b' class MTInteractiveShell(InteractiveShell):' | |||||
375 | if not callable(t): |
|
375 | if not callable(t): | |
376 | raise TypeError,'on_kill must be a list of callables' |
|
376 | raise TypeError,'on_kill must be a list of callables' | |
377 | self.on_kill = on_kill |
|
377 | self.on_kill = on_kill | |
378 |
|
378 | # thread identity of the "worker thread" (that may execute code directly) | ||
|
379 | self.worker_ident = None | |||
379 | def runsource(self, source, filename="<input>", symbol="single"): |
|
380 | def runsource(self, source, filename="<input>", symbol="single"): | |
380 | """Compile and run some source in the interpreter. |
|
381 | """Compile and run some source in the interpreter. | |
381 |
|
382 | |||
@@ -406,7 +407,14 b' class MTInteractiveShell(InteractiveShell):' | |||||
406 | # Note that with macros and other applications, we MAY re-enter this |
|
407 | # Note that with macros and other applications, we MAY re-enter this | |
407 | # section, so we have to acquire the lock with non-blocking semantics, |
|
408 | # section, so we have to acquire the lock with non-blocking semantics, | |
408 | # else we deadlock. |
|
409 | # else we deadlock. | |
409 | got_lock = self.thread_ready.acquire() |
|
410 | ||
|
411 | # shortcut - if we are in worker thread, execute directly (to allow recursion) | |||
|
412 | ||||
|
413 | if self.worker_ident == thread.get_ident(): | |||
|
414 | InteractiveShell.runcode(self,code) | |||
|
415 | return | |||
|
416 | ||||
|
417 | got_lock = self.thread_ready.acquire(blocking=False) | |||
410 | self.code_queue.put(code) |
|
418 | self.code_queue.put(code) | |
411 | if got_lock: |
|
419 | if got_lock: | |
412 | self.thread_ready.wait() # Wait until processed in timeout interval |
|
420 | self.thread_ready.wait() # Wait until processed in timeout interval | |
@@ -420,8 +428,8 b' class MTInteractiveShell(InteractiveShell):' | |||||
420 | Multithreaded wrapper around IPython's runcode().""" |
|
428 | Multithreaded wrapper around IPython's runcode().""" | |
421 |
|
429 | |||
422 | global CODE_RUN |
|
430 | global CODE_RUN | |
423 |
|
||||
424 | # lock thread-protected stuff |
|
431 | # lock thread-protected stuff | |
|
432 | self.worker_ident = thread.get_ident() | |||
425 | got_lock = self.thread_ready.acquire() |
|
433 | got_lock = self.thread_ready.acquire() | |
426 |
|
434 | |||
427 | if self._kill: |
|
435 | if self._kill: | |
@@ -448,7 +456,6 b' class MTInteractiveShell(InteractiveShell):' | |||||
448 | code_to_run = self.code_queue.get_nowait() |
|
456 | code_to_run = self.code_queue.get_nowait() | |
449 | except Queue.Empty: |
|
457 | except Queue.Empty: | |
450 | break |
|
458 | break | |
451 |
|
||||
452 | # Exceptions need to be raised differently depending on which |
|
459 | # Exceptions need to be raised differently depending on which | |
453 | # thread is active. This convoluted try/except is only there to |
|
460 | # thread is active. This convoluted try/except is only there to | |
454 | # protect against asynchronous exceptions, to ensure that a KBINT |
|
461 | # protect against asynchronous exceptions, to ensure that a KBINT |
General Comments 0
You need to be logged in to leave comments.
Login now