backport: sqlite: properly serialize operations on the databases

1. There is one database per folder and sqlite requires to serialize the
writings. Instead of locking at LocalStatusSQLiteFolder object level, introduce
a new DatabaseFileLock object which is shared across threads. This fixes the
concurrent writes issues that some users might experience by duplications or
flags restored to the previous state.

2. Close the database only when we are sure no other threads will use the
connection on a *per-file* basis. Previous fix 677afb8d8f is wrong
because the same lock is shared for all the databases.

Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/350
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht
2016-07-25 14:39:11 +02:00
parent 41fdd4ee78
commit 038a433f69
3 changed files with 72 additions and 43 deletions

View File

@ -91,6 +91,11 @@ class LocalStatusRepository(BaseRepository):
# Create an empty StatusFolder
folder = self._instanciatefolder(foldername)
# First delete any existing data to make sure we won't consider obsolete
# data. This might happen if the user removed the folder (maildir) and
# it is re-created afterwards.
folder.purge()
folder.openfiles()
folder.save()
folder.closefiles()