[PATCH 3/3] UIDMaps: correctly protect from concurrent writes

Łukasz Żarnowiecki dolohow at outlook.com
Tue Jul 5 22:38:14 BST 2016


> --- 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():

Not necessary parenthesis.

> +                    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