Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1757

Show
Ignore:
Timestamp:
10/18/07 21:18:33
Author:
dan
Message:

Moving execv to the main thread to fix restarts on OSX. Removing Reexec. Changing the reloader to signal the bus to restart.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/__init__.py

    r1756 r1757  
    213213engine.autoreload = restsrv.plugins.Autoreloader(engine) 
    214214engine.autoreload.subscribe() 
    215 restsrv.plugins.Reexec(engine).subscribe() 
    216215restsrv.plugins.ThreadManager(engine).subscribe() 
    217216 
  • trunk/cherrypy/restsrv/plugins.py

    r1755 r1757  
    9595        """Python signal handler (self.set_handler subscribes it for you).""" 
    9696        self.bus.publish(self.signals[signum]) 
    97  
    98  
    99 class Reexec(SimplePlugin): 
    100     """A process restarter (using execv) for the 'restart' WSPBus channel. 
    101      
    102     retry: the number of seconds to wait for all parent threads to stop. 
    103         This is only necessary for platforms like OS X which error if all 
    104         threads are not absolutely terminated before calling execv. 
    105     """ 
    106      
    107     def __init__(self, bus, retry=2): 
    108         self.bus = bus 
    109         self.retry = retry 
    110      
    111     def restart(self): 
    112         """Re-execute the current process.""" 
    113         args = sys.argv[:] 
    114         self.bus.log('Re-spawning %s' % ' '.join(args)) 
    115         args.insert(0, sys.executable) 
    116          
    117         if sys.platform == 'win32': 
    118             args = ['"%s"' % arg for arg in args] 
    119          
    120         # Some platforms (OS X) will error if all threads are not 
    121         # ABSOLUTELY terminated, and there doesn't seem to be a way 
    122         # around it other than waiting for the threads to stop. 
    123         # See http://www.cherrypy.org/ticket/581. 
    124         for trial in xrange(self.retry * 10): 
    125             try: 
    126                 os.execv(sys.executable, args) 
    127                 return 
    128             except OSError, x: 
    129                 if x.errno != 45: 
    130                     raise 
    131                 time.sleep(0.1) 
    132         else: 
    133             raise 
    13497 
    13598 
     
    390353                    if mtime is None or mtime > oldtime: 
    391354                        # The file has been deleted or modified. 
     355                        self.bus.log("Restarting because %s changed." % filename) 
     356                        self.thread.cancel() 
    392357                        self.bus.restart() 
     358                        return 
    393359 
    394360 
  • trunk/cherrypy/restsrv/win32.py

    r1740 r1757  
    7373        try: 
    7474            win32event.WaitForSingleObject(event, win32event.INFINITE) 
     75            if self.execv: 
     76                self._do_execv() 
    7577        except SystemExit: 
    7678            self.log('SystemExit raised: shutting down bus') 
  • trunk/cherrypy/restsrv/wspbus.py

    r1752 r1757  
    5858import time 
    5959import traceback as _traceback 
    60  
     60import os 
     61import exceptions 
    6162 
    6263# Use a flag to indicate the state of the bus. 
     
    7879     
    7980    def __init__(self): 
     81        self.execv = False 
    8082        self.state = states.STOPPED 
    8183        self.listeners = dict( 
     
    147149    def restart(self): 
    148150        """Restart the process (may close connections).""" 
     151        if self.execv: 
     152            raise exceptions.AssertionError("Already restarting.") 
     153 
     154        self.execv = True 
    149155        self.stop() 
    150156         
     
    162168            while self.state != state: 
    163169                time.sleep(interval) 
     170            if self.execv: 
     171                self._do_execv() 
    164172        except (KeyboardInterrupt, IOError): 
    165173            # The time.sleep call might raise 
     
    172180            raise 
    173181     
     182    def _do_execv(self): 
     183        """Re-execute the current process.""" 
     184        # Waiting for the child threads to finish is necessary on OS X. 
     185        # See: http://www.cherrypy.org/ticket/581 
     186        self.log("Waiting for child threads...") 
     187        threads = [t for t in threading.enumerate() if t != threading.currentThread()] 
     188        for t in threads: 
     189            t.join() 
     190 
     191        args = sys.argv[:] 
     192        self.log('Re-spawning %s' % ' '.join(args)) 
     193        args.insert(0, sys.executable) 
     194 
     195        if sys.platform == 'win32': 
     196            args = ['"%s"' % arg for arg in args] 
     197 
     198        os.execv(sys.executable, args) 
     199 
     200 
    174201    def stop(self): 
    175202        """Stop all services.""" 

Hosted by WebFaction

Log in as guest/cpguest to create tickets