Changeset 2997

Show
Ignore:
Timestamp:
01/31/08 00:58:33 (10 months ago)
Author:
fperez
Message:

Fix long-standing deadlock in threaded shells. Closes #210

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ipython/trunk/IPython/Shell.py

    r2887 r2997  
    359359                                  user_global_ns,banner2) 
    360360 
    361         # Locking control variable.  We need to use a norma lock, not an RLock 
    362         # here.  I'm not exactly sure why, it seems to me like it should be 
    363         # the opposite, but we deadlock with an RLock.  Puzzled... 
    364         self.thread_ready = threading.Condition(threading.Lock()) 
     361        # Locking control variable. 
     362        self.thread_ready = threading.Condition(threading.RLock()) 
    365363 
    366364        # A queue to hold the code to be executed.  A scalar variable is NOT 
     
    409407        # section, so we have to acquire the lock with non-blocking semantics, 
    410408        # else we deadlock. 
    411         got_lock = self.thread_ready.acquire(False
     409        got_lock = self.thread_ready.acquire(
    412410        self.code_queue.put(code) 
    413411        if got_lock: 
    414             self.thread_ready.wait()  # Wait until processed in timeout interval 
    415             self.thread_ready.release() 
     412           self.thread_ready.wait()  # Wait until processed in timeout interval 
     413        self.thread_ready.release() 
    416414 
    417415        return False 
     
    427425        # active 
    428426        CODE_RUN = True 
    429          
    430427        # lock thread-protected stuff 
    431         got_lock = self.thread_ready.acquire(False
     428        self.thread_ready.acquire(
    432429 
    433430        if self._kill: 
     
    449446        # Flush queue of pending code by calling the run methood of the parent 
    450447        # class with all items which may be in the queue. 
     448        code_to_run = None 
    451449        while 1: 
    452450            try: 
     
    454452            except Queue.Empty: 
    455453                break 
    456             if got_lock: 
    457                 self.thread_ready.notify() 
    458                 InteractiveShell.runcode(self,code_to_run) 
    459             else: 
    460                 break 
     454            InteractiveShell.runcode(self,code_to_run) 
    461455             
    462456        # We're done with thread-protected variables 
    463         if got_lock: 
    464             self.thread_ready.release() 
     457        if code_to_run is not None: 
     458           self.thread_ready.notify() 
     459        self.thread_ready.release() 
    465460 
    466461        # We're done... 
  • ipython/trunk/doc/ChangeLog

    r2996 r2997  
     12008-01-30  Fernando Perez  <Fernando.Perez@colorado.edu> 
     2 
     3    * IPython/Shell.py (MTInteractiveShell.__init__): Fixed deadlock 
     4    that could occur due to a race condition in threaded shells. 
     5    Thanks to code provided by Marc, as #210. 
     6 
    172008-01-29  Fernando Perez  <Fernando.Perez@colorado.edu> 
    28