sqlite: close the database when no more threads need access
It's required to have more than one connection to the database for the maxconnections configuration option to work with threads. However, connection.close() is closing all the connections. Only close the connection when no more thread need it. Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/350 Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
parent
6d0dba0d86
commit
e753766284
@ -41,6 +41,9 @@ class LocalStatusSQLiteFolder(BaseFolder):
|
|||||||
|
|
||||||
# Current version of our db format.
|
# Current version of our db format.
|
||||||
cur_version = 2
|
cur_version = 2
|
||||||
|
# Keep track on how many threads need access to the database.
|
||||||
|
threads_open_count = 0
|
||||||
|
threads_open_lock = Lock()
|
||||||
|
|
||||||
def __init__(self, name, repository):
|
def __init__(self, name, repository):
|
||||||
self.sep = '.' # Needs to be set before super.__init__()
|
self.sep = '.' # Needs to be set before super.__init__()
|
||||||
@ -62,16 +65,21 @@ class LocalStatusSQLiteFolder(BaseFolder):
|
|||||||
self.connection = None
|
self.connection = None
|
||||||
|
|
||||||
def openfiles(self):
|
def openfiles(self):
|
||||||
|
# Protect the creation/upgrade of database accross threads.
|
||||||
|
with LocalStatusSQLiteFolder.threads_open_lock:
|
||||||
# Try to establish connection, no need for threadsafety in __init__.
|
# Try to establish connection, no need for threadsafety in __init__.
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.connection = sqlite.connect(self.filename, check_same_thread=False)
|
self.connection = sqlite.connect(self.filename,
|
||||||
|
check_same_thread=False)
|
||||||
|
LocalStatusSQLiteFolder.threads_open_count += 1
|
||||||
except sqlite.OperationalError as e:
|
except sqlite.OperationalError as e:
|
||||||
# Operation had failed.
|
# Operation had failed.
|
||||||
six.reraise(UserWarning,
|
six.reraise(UserWarning,
|
||||||
UserWarning(
|
UserWarning(
|
||||||
"cannot open database file '%s': %s.\nYou might"
|
"cannot open database file '%s': %s.\nYou might"
|
||||||
"want to check the rights to that file and if it "
|
" want to check the rights to that file and if "
|
||||||
"cleanly opens with the 'sqlite<3>' command."%
|
"it cleanly opens with the 'sqlite<3>' command"%
|
||||||
(self.filename, e)),
|
(self.filename, e)),
|
||||||
exc_info()[2])
|
exc_info()[2])
|
||||||
|
|
||||||
@ -159,8 +167,8 @@ class LocalStatusSQLiteFolder(BaseFolder):
|
|||||||
def __upgrade_db(self, from_ver):
|
def __upgrade_db(self, from_ver):
|
||||||
"""Upgrade the sqlite format from version 'from_ver' to current"""
|
"""Upgrade the sqlite format from version 'from_ver' to current"""
|
||||||
|
|
||||||
if hasattr(self, 'connection'):
|
if self.connection is not None:
|
||||||
self.connection.close() #close old connections first
|
self.connection.close() # Close old connections first.
|
||||||
self.connection = sqlite.connect(self.filename,
|
self.connection = sqlite.connect(self.filename,
|
||||||
check_same_thread=False)
|
check_same_thread=False)
|
||||||
|
|
||||||
@ -185,8 +193,8 @@ class LocalStatusSQLiteFolder(BaseFolder):
|
|||||||
|
|
||||||
self.connection must point to the opened and valid SQlite
|
self.connection must point to the opened and valid SQlite
|
||||||
database connection."""
|
database connection."""
|
||||||
self.ui._msg('Creating new Local Status db for %s:%s' \
|
self.ui._msg('Creating new Local Status db for %s:%s'%
|
||||||
% (self.repository, self))
|
(self.repository, self))
|
||||||
self.connection.executescript("""
|
self.connection.executescript("""
|
||||||
CREATE TABLE metadata (key VARCHAR(50) PRIMARY KEY, value VARCHAR(128));
|
CREATE TABLE metadata (key VARCHAR(50) PRIMARY KEY, value VARCHAR(128));
|
||||||
INSERT INTO metadata VALUES('db_version', '2');
|
INSERT INTO metadata VALUES('db_version', '2');
|
||||||
@ -229,6 +237,9 @@ class LocalStatusSQLiteFolder(BaseFolder):
|
|||||||
self.messagelist[uid]['mtime'] = row[2]
|
self.messagelist[uid]['mtime'] = row[2]
|
||||||
|
|
||||||
def closefiles(self):
|
def closefiles(self):
|
||||||
|
with LocalStatusSQLiteFolder.threads_open_lock:
|
||||||
|
LocalStatusSQLiteFolder.threads_open_count -= 1
|
||||||
|
if self.threads_open_count < 1:
|
||||||
try:
|
try:
|
||||||
self.connection.close()
|
self.connection.close()
|
||||||
except:
|
except:
|
||||||
|
Loading…
Reference in New Issue
Block a user