diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index a0fa608fae..e0ee88296f 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -353,12 +353,20 @@ class GuiRunner(QObject): self.initialize_db() +def set_restarting_env_var(): + if iswindows: + ctime = plugins['winutil'][0].get_process_times(None)[0] + os.environ['CALIBRE_RESTARTING_FROM_GUI'] = str(ctime) + else: + os.environ['CALIBRE_RESTARTING_FROM_GUI'] = str(os.getpid()) + + def run_in_debug_mode(): from calibre.debug import run_calibre_debug import tempfile, subprocess fd, logpath = tempfile.mkstemp('.txt') os.close(fd) - os.environ['CALIBRE_RESTARTING_FROM_GUI'] = environ_item('1') + set_restarting_env_var() run_calibre_debug( '--gui-debug', logpath, stdout=lopen(logpath, 'wb'), stderr=subprocess.STDOUT, stdin=lopen(os.devnull, 'rb')) @@ -403,8 +411,8 @@ def run_gui(opts, args, listener, app, gui_debug=None): run_calibre_debug('-c', 'import sys, os, time; time.sleep(3); os.execlp("open", "open", sys.argv[-1])', app) else: import subprocess - os.environ['CALIBRE_RESTARTING_FROM_GUI'] = environ_item('1') - if iswindows and hasattr(winutil, 'prepare_for_restart'): + set_restarting_env_var() + if iswindows: winutil.prepare_for_restart() if hasattr(sys, 'run_local'): cmd = [sys.run_local] @@ -514,9 +522,31 @@ def create_listener(): return Listener(address=gui_socket_address()) +def wait_for_parent_to_die(ppid, max_wait=10): + ppid = int(ppid) + if iswindows: + get_process_times = plugins['winutil'][0].get_process_times + + def parent_done(): + try: + ctime = get_process_times(os.getppid())[0] + except Exception: + return True + return ctime > ppid + + else: + def parent_done(): + return os.getppid() != ppid + + st = time.monotonic() + while not parent_done() and time.monotonic() - st < max_wait: + time.sleep(0.1) + + def main(args=sys.argv): - if os.environ.pop('CALIBRE_RESTARTING_FROM_GUI', None) == environ_item('1'): - time.sleep(2) # give the parent process time to cleanup and close + ppid = os.environ.pop('CALIBRE_RESTARTING_FROM_GUI', None) + if ppid is not None: + wait_for_parent_to_die(ppid) if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ: windows_repair() return 0