From f8aea31f40ea9d29b5863e671c9d29d506e36cf8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 19 Dec 2014 13:28:59 +0530 Subject: [PATCH] Make singleinstance() more robust on OS X It now handles EINTR and also does not hide all errors in opening the file or calling lockf() An error is now reported to the user in a nice error dialog before aborting startup. --- src/calibre/gui2/main.py | 10 ++++++++-- src/calibre/utils/lock.py | 11 +++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 33fadccda1..830d81c358 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -459,8 +459,14 @@ def main(args=sys.argv): app, opts, args = init_qt(args) except AbortInit: return 1 - from calibre.utils.lock import singleinstance - si = singleinstance(singleinstance_name) + try: + from calibre.utils.lock import singleinstance + si = singleinstance(singleinstance_name) + except Exception: + error_dialog(None, _('Cannot start calibre'), _( + 'Failed to start calibre, single instance locking failed. Click "Show Details" for more information'), + det_msg=traceback.format_exc(), show=True) + return 1 if si and opts.shutdown_running_calibre: return 0 if si: diff --git a/src/calibre/utils/lock.py b/src/calibre/utils/lock.py index 964c721145..336f5bb1b3 100644 --- a/src/calibre/utils/lock.py +++ b/src/calibre/utils/lock.py @@ -233,12 +233,15 @@ else: @param name: The name to lock. @type name: string ''' + from calibre.utils.ipc import eintr_retry_call path = singleinstance_path(name) + f = open(path, 'w') try: - f = open(path, 'w') - fcntl.lockf(f.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) + eintr_retry_call(fcntl.lockf, f.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) atexit.register(_clean_lock_file, f) return True - except EnvironmentError: - pass + except IOError as err: + if err.errno == errno.EAGAIN: + return False + raise return False