commit:     f73e60a7df4dfe91bc43fd0bb9cbb481fe9dc294
Author:     Devan Franchini <twitch153 <AT> gentoo <DOT> org>
AuthorDate: Wed May 13 19:59:13 2015 +0000
Commit:     Devan Franchini <twitch153 <AT> gentoo <DOT> org>
CommitDate: Wed May 13 19:59:13 2015 +0000
URL:        https://gitweb.gentoo.org/proj/layman.git/commit/?id=f73e60a7

flocker.py: Adds file locking utility class

 layman/flocker.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/layman/flocker.py b/layman/flocker.py
new file mode 100644
index 0000000..d40925d
--- /dev/null
+++ b/layman/flocker.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File:       flocker.py
+#
+#             Handles all file locking.
+#
+# Copyright:
+#             (c) 2015 Devan Franchini
+#             Distributed under the terms of the GNU General Public License v2
+#
+# Author(s):
+#             Michał Górny <[email protected]>
+#             Devan Franchini <[email protected]>
+#
+
+#===============================================================================
+#
+# Dependencies
+#
+#-------------------------------------------------------------------------------
+import fcntl
+
+from layman.compatibility import fileopen
+
+
+class FileLocker(object):
+
+    def __init__(self):
+        self.files = {}
+        self.locked = set()
+
+
+    def lock_file(self, path, exclusive=False):
+        '''Lock the file located at path.'''
+        file_mode = 'r'
+        lock_mode = fcntl.LOCK_SH
+
+        if exclusive:
+            file_mode = 'w+'
+            lock_mode = fcntl.LOCK_EX
+
+        assert path not in self.locked
+
+        self.locked.add(path)
+        fcntl.flock(self.get_file(path, file_mode).fileno(), lock_mode)
+
+
+    def unlock_file(self, path):
+        '''Unlock the file located at path.'''
+        assert path in self.locked
+
+        fcntl.flock(self.get_file(path).fileno(), fcntl.LOCK_UN)
+        self.locked.discard(path)
+
+
+    def get_file(self, path, mode='r'):
+        '''Obtains file object for given path'''
+        assert mode in ('r', 'w+')
+
+        if path not in self.files:
+            self.files[path] = fileopen(path, mode)
+
+        f = self.files[path]
+        f.seek(0)
+
+        return f

Reply via email to