mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Better fix for error on restart
Now both single instance and listener mutexes are explicitly released before launching child process, so the child process has no need to wait for the parent process to die.
This commit is contained in:
parent
fc77917e9c
commit
f15e144e2a
@ -30,6 +30,7 @@ from calibre.utils.lock import SingleInstance
|
|||||||
from calibre.utils.monotonic import monotonic
|
from calibre.utils.monotonic import monotonic
|
||||||
from polyglot.builtins import as_bytes, environ_item, range, unicode_type
|
from polyglot.builtins import as_bytes, environ_item, range, unicode_type
|
||||||
|
|
||||||
|
after_quit_actions = {'debug_on_restart': False, 'restart_after_quit': False}
|
||||||
if iswindows:
|
if iswindows:
|
||||||
winutil = plugins['winutil'][0]
|
winutil = plugins['winutil'][0]
|
||||||
|
|
||||||
@ -353,27 +354,18 @@ class GuiRunner(QObject):
|
|||||||
self.initialize_db()
|
self.initialize_db()
|
||||||
|
|
||||||
|
|
||||||
def set_restarting_env_var():
|
|
||||||
if iswindows:
|
|
||||||
ctime = winutil.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)
|
||||||
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'))
|
||||||
|
|
||||||
|
|
||||||
def run_gui(opts, args, listener, app, gui_debug=None):
|
def run_gui(opts, args, listener, app, gui_debug=None):
|
||||||
with SingleInstance('db') as si:
|
with listener, SingleInstance('db') as si:
|
||||||
if not si:
|
if not si:
|
||||||
ext = '.exe' if iswindows else ''
|
ext = '.exe' if iswindows else ''
|
||||||
error_dialog(None, _('Cannot start calibre'), _(
|
error_dialog(None, _('Cannot start calibre'), _(
|
||||||
@ -404,31 +396,8 @@ def run_gui_(opts, args, listener, app, gui_debug=None):
|
|||||||
from calibre.gui2.wizard import wizard
|
from calibre.gui2.wizard import wizard
|
||||||
wizard().exec_()
|
wizard().exec_()
|
||||||
if getattr(runner.main, 'restart_after_quit', False):
|
if getattr(runner.main, 'restart_after_quit', False):
|
||||||
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
|
after_quit_actions['restart_after_quit'] = True
|
||||||
if getattr(runner.main, 'debug_on_restart', False) or gui_debug is not None:
|
after_quit_actions['debug_on_restart'] = getattr(runner.main, 'debug_on_restart', False) or gui_debug is not None
|
||||||
run_in_debug_mode()
|
|
||||||
else:
|
|
||||||
if hasattr(sys, 'frameworks_dir'):
|
|
||||||
app = os.path.dirname(os.path.dirname(os.path.realpath(sys.frameworks_dir)))
|
|
||||||
from calibre.debug import run_calibre_debug
|
|
||||||
prints('Restarting with:', app)
|
|
||||||
run_calibre_debug('-c', 'import sys, os, time; time.sleep(3); os.execlp("open", "open", sys.argv[-1])', app)
|
|
||||||
else:
|
|
||||||
import subprocess
|
|
||||||
set_restarting_env_var()
|
|
||||||
if iswindows:
|
|
||||||
winutil.prepare_for_restart()
|
|
||||||
if hasattr(sys, 'run_local'):
|
|
||||||
cmd = [sys.run_local]
|
|
||||||
if DEBUG:
|
|
||||||
cmd += ['calibre-debug', '-g']
|
|
||||||
else:
|
|
||||||
cmd.append('calibre')
|
|
||||||
else:
|
|
||||||
args = ['-g'] if os.path.splitext(e)[0].endswith('-debug') else []
|
|
||||||
cmd = [e] + args
|
|
||||||
prints('Restarting with:', ' '.join(cmd))
|
|
||||||
subprocess.Popen(cmd)
|
|
||||||
else:
|
else:
|
||||||
if iswindows:
|
if iswindows:
|
||||||
try:
|
try:
|
||||||
@ -436,7 +405,6 @@ def run_gui_(opts, args, listener, app, gui_debug=None):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if getattr(runner.main, 'gui_debug', None) is not None:
|
if getattr(runner.main, 'gui_debug', None) is not None:
|
||||||
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
|
|
||||||
debugfile = runner.main.gui_debug
|
debugfile = runner.main.gui_debug
|
||||||
from calibre.gui2 import open_local_file
|
from calibre.gui2 import open_local_file
|
||||||
if iswindows:
|
if iswindows:
|
||||||
@ -527,30 +495,36 @@ 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):
|
def restart_after_quit():
|
||||||
ppid = int(ppid)
|
|
||||||
if iswindows:
|
if iswindows:
|
||||||
|
# detach the stdout/stderr/stdin handles
|
||||||
def parent_done():
|
winutil.prepare_for_restart()
|
||||||
try:
|
if after_quit_actions['debug_on_restart']:
|
||||||
ctime = winutil.get_process_times(os.getppid())[0]
|
run_in_debug_mode()
|
||||||
except Exception:
|
return
|
||||||
return True
|
if hasattr(sys, 'frameworks_dir'):
|
||||||
return ctime > ppid
|
app = os.path.dirname(os.path.dirname(os.path.realpath(sys.frameworks_dir)))
|
||||||
|
from calibre.debug import run_calibre_debug
|
||||||
|
prints('Restarting with:', app)
|
||||||
|
run_calibre_debug('-c', 'import sys, os, time; time.sleep(3); os.execlp("open", "open", sys.argv[-1])', app)
|
||||||
else:
|
else:
|
||||||
def parent_done():
|
import subprocess
|
||||||
return os.getppid() != ppid
|
if hasattr(sys, 'run_local'):
|
||||||
|
cmd = [sys.run_local]
|
||||||
st = time.monotonic()
|
if DEBUG:
|
||||||
while not parent_done() and time.monotonic() - st < max_wait:
|
cmd += ['calibre-debug', '-g']
|
||||||
time.sleep(0.1)
|
else:
|
||||||
|
cmd.append('calibre')
|
||||||
|
else:
|
||||||
|
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
|
||||||
|
cmd = [e]
|
||||||
|
if os.path.splitext(e)[0].endswith('-debug'):
|
||||||
|
cmd.append('-g')
|
||||||
|
prints('Restarting with:', ' '.join(cmd))
|
||||||
|
subprocess.Popen(cmd)
|
||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
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:
|
if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ:
|
||||||
windows_repair()
|
windows_repair()
|
||||||
return 0
|
return 0
|
||||||
@ -567,6 +541,8 @@ def main(args=sys.argv):
|
|||||||
if si and opts.shutdown_running_calibre:
|
if si and opts.shutdown_running_calibre:
|
||||||
return 0
|
return 0
|
||||||
run_main(app, opts, args, gui_debug, si)
|
run_main(app, opts, args, gui_debug, si)
|
||||||
|
if after_quit_actions['restart_after_quit']:
|
||||||
|
restart_after_quit()
|
||||||
|
|
||||||
|
|
||||||
def run_main(app, opts, args, gui_debug, si):
|
def run_main(app, opts, args, gui_debug, si):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user