mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Implement database locking (needs to be debugged on windows and OSX)
This commit is contained in:
parent
3af3b9c3d4
commit
8d46e046d4
@ -43,6 +43,8 @@ from libprs500.gui2.dialogs.lrf_single import LRFSingleDialog
|
||||
from libprs500.gui2.dialogs.password import PasswordDialog
|
||||
from libprs500.gui2.lrf_renderer.main import file_renderer
|
||||
from libprs500.gui2.lrf_renderer.main import option_parser as lrfviewerop
|
||||
from libprs500.library.database import DatabaseLocked
|
||||
|
||||
|
||||
class Main(MainWindow, Ui_MainWindow):
|
||||
|
||||
@ -715,7 +717,12 @@ def main(args=sys.argv):
|
||||
QCoreApplication.setOrganizationName(ORG_NAME)
|
||||
QCoreApplication.setApplicationName(APP_UID)
|
||||
initialize_file_icon_provider()
|
||||
main = Main()
|
||||
try:
|
||||
main = Main()
|
||||
except DatabaseLocked, err:
|
||||
QMessageBox.critical(None, 'Cannot Start '+__appname__,
|
||||
'Another program is using the database. Perhaps %s is already running?'%(__appname__,))
|
||||
return 1
|
||||
sys.excepthook = main.unhandled_exception
|
||||
return app.exec_()
|
||||
return 0
|
||||
|
@ -35,9 +35,42 @@ class Concatenate(object):
|
||||
return self.ans[:-len(self.sep)]
|
||||
return self.ans
|
||||
|
||||
_lock_file = None
|
||||
class DatabaseLocked(Exception):
|
||||
pass
|
||||
|
||||
def _lock(path):
|
||||
path = os.path.join(os.path.dirname(path), '.'+os.path.basename(path)+'.lock')
|
||||
global _lock_file
|
||||
if _lock_file is not None:
|
||||
raise DatabaseLocked('Database already locked in this instance.')
|
||||
try:
|
||||
_lock_file = open(path, 'wb')
|
||||
except IOError:
|
||||
raise DatabaseLocked('Database in use by another instance')
|
||||
try:
|
||||
import fcntl, errno
|
||||
try:
|
||||
fcntl.lockf(_lock_file.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB)
|
||||
except IOError, err:
|
||||
_lock_file = None
|
||||
if err.errno in (errno.EACCES, errno.EAGAIN):
|
||||
raise DatabaseLocked('Database in use by another instance')
|
||||
except ImportError:
|
||||
try:
|
||||
import msvcrt
|
||||
try:
|
||||
msvcrt.locking(_lock_file.fileno(), msvcrt.LK_NBLCK, 1)
|
||||
except IOError:
|
||||
_lock_file = None
|
||||
raise DatabaseLocked('Database in use by another instance')
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def _connect(path):
|
||||
if isinstance(path, unicode):
|
||||
path = path.encode('utf-8')
|
||||
_lock(path)
|
||||
conn = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)
|
||||
conn.row_factory = lambda cursor, row : list(row)
|
||||
conn.create_aggregate('concat', 1, Concatenate)
|
||||
@ -621,6 +654,12 @@ class LibraryDatabase(object):
|
||||
conn.execute('pragma user_version=2')
|
||||
conn.commit()
|
||||
|
||||
def __del__(self):
|
||||
global _lock_file
|
||||
import os
|
||||
if _lock_file is not None and os.path.exists(_lock_file):
|
||||
os.unlink(_lock_file)
|
||||
|
||||
def __init__(self, dbpath):
|
||||
self.dbpath = dbpath
|
||||
self.conn = _connect(dbpath)
|
||||
|
Loading…
x
Reference in New Issue
Block a user