[PATCH 3/3] UIDMaps: correctly protect from concurrent writes
Nicolas Sebrecht
nicolas.s-dev at laposte.net
Tue Jun 28 14:48:02 BST 2016
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev at laposte.net>
---
offlineimap/folder/UIDMaps.py | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/offlineimap/folder/UIDMaps.py b/offlineimap/folder/UIDMaps.py
index 038284c..980adfb 100644
--- a/offlineimap/folder/UIDMaps.py
+++ b/offlineimap/folder/UIDMaps.py
@@ -78,10 +78,19 @@ class MappedIMAPFolder(IMAPFolder):
def _savemaps(self):
mapfilename = self._getmapfilename()
- with open(mapfilename + ".tmp", 'wt') as mapfilefd:
- for (key, value) in self.diskl2r.items():
- mapfilefd.write("%d:%d\n"% (key, value))
- os.rename(mapfilename + '.tmp', mapfilename)
+ mapfilenamelock = "%s.lock"% mapfilename
+ with open(mapfilenamelock, 'w') as mapfilelock:
+ # The "account" lock already prevents from multiple access by
+ # different processes. However, we still need to protect for
+ # multiple access from different threads.
+ try:
+ fnctl.lockf(mapfilelock, fnctl.LOCK_EX) # Blocks until acquired.
+ except NameError:
+ pass # Windows...
+ with open(mapfilename, 'wt') as mapfilefd:
+ for (key, value) in self.diskl2r.items():
+ mapfilefd.write("%d:%d\n"% (key, value))
+ # The lock is released when the file descriptor ends.
def _uidlist(self, mapping, items):
try:
--
2.7.4
More information about the OfflineIMAP-project
mailing list