From: Ben Darnell Date: Thu, 25 Feb 2010 00:37:11 +0000 (-0800) Subject: Add a workaround for a bug in os.execv when used on Mac OS X versions X-Git-Tag: v1.0.0~76^2~11 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=f9cda8634bf80bf6978bb443561ae9304e476fee;p=thirdparty%2Ftornado.git Add a workaround for a bug in os.execv when used on Mac OS X versions prior to 10.6 when there are multiple threads in the process. --- diff --git a/tornado/autoreload.py b/tornado/autoreload.py index 583cdc96f..4b3ab364c 100644 --- a/tornado/autoreload.py +++ b/tornado/autoreload.py @@ -21,6 +21,7 @@ and Google AppEngine. """ import functools +import errno import ioloop import logging import os @@ -41,7 +42,13 @@ def start(io_loop=None, check_time=500): scheduler.start() +_reload_attempted = False + def _reload_on_update(io_loop, modify_times): + global _reload_attempted + if _reload_attempted: + # We already tried to reload and it didn't work, so don't try again. + return for module in sys.modules.values(): path = getattr(module, "__file__", None) if not path: continue @@ -56,9 +63,26 @@ def _reload_on_update(io_loop, modify_times): continue if modify_times[path] != modified: logging.info("%s modified; restarting server", path) + _reload_attempted = True for fd in io_loop._handlers.keys(): try: os.close(fd) except: pass - os.execv(sys.executable, [sys.executable] + sys.argv) + try: + os.execv(sys.executable, [sys.executable] + sys.argv) + except OSError, e: + # Mac OS X versions prior to 10.6 do not support execv in + # a process that contains multiple threads. Instead of + # re-executing in the current process, start a new one + # and cause the current process to exit. This isn't + # ideal since the new process is detached from the parent + # terminal and thus cannot easily be killed with ctrl-C, + # but it's better than not being able to autoreload at + # all. + # Unfortunately the errno returned in this case does not + # appear to be consistent, so we can't easily check for + # this error specifically. + os.spawnv(os.P_NOWAIT, sys.executable, + [sys.executable] + sys.argv) + sys.exit(0)