When restarting detect actual parent process death instead of sleeping for two seconds

This should hopefully fix the issue with restarts not working on some
Windows machines because the parent process takes longer than two
seconds to die.
This commit is contained in:
Kovid Goyal 2020-10-09 22:53:21 +05:30
parent d103b29f96
commit fdae87aa6e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -353,12 +353,20 @@ class GuiRunner(QObject):
self.initialize_db() 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(): def run_in_debug_mode():
from calibre.debug import run_calibre_debug from calibre.debug import run_calibre_debug
import tempfile, subprocess import tempfile, subprocess
fd, logpath = tempfile.mkstemp('.txt') fd, logpath = tempfile.mkstemp('.txt')
os.close(fd) os.close(fd)
os.environ['CALIBRE_RESTARTING_FROM_GUI'] = environ_item('1') set_restarting_env_var()
run_calibre_debug( run_calibre_debug(
'--gui-debug', logpath, stdout=lopen(logpath, 'wb'), '--gui-debug', logpath, stdout=lopen(logpath, 'wb'),
stderr=subprocess.STDOUT, stdin=lopen(os.devnull, 'rb')) 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) run_calibre_debug('-c', 'import sys, os, time; time.sleep(3); os.execlp("open", "open", sys.argv[-1])', app)
else: else:
import subprocess import subprocess
os.environ['CALIBRE_RESTARTING_FROM_GUI'] = environ_item('1') set_restarting_env_var()
if iswindows and hasattr(winutil, 'prepare_for_restart'): if iswindows:
winutil.prepare_for_restart() winutil.prepare_for_restart()
if hasattr(sys, 'run_local'): if hasattr(sys, 'run_local'):
cmd = [sys.run_local] cmd = [sys.run_local]
@ -514,9 +522,31 @@ def create_listener():
return Listener(address=gui_socket_address()) 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): def main(args=sys.argv):
if os.environ.pop('CALIBRE_RESTARTING_FROM_GUI', None) == environ_item('1'): ppid = os.environ.pop('CALIBRE_RESTARTING_FROM_GUI', None)
time.sleep(2) # give the parent process time to cleanup and close if ppid is not None:
wait_for_parent_to_die(ppid)
if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ: if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ:
windows_repair() windows_repair()
return 0 return 0