Change in vdsm[master]: Add ResourceLocker
alitke at redhat.com
alitke at redhat.com
Mon Jul 13 19:45:56 UTC 2015
Adam Litke has uploaded a new change for review.
Change subject: Add ResourceLocker
......................................................................
Add ResourceLocker
Change-Id: I29589889efd39920d72979e89405ff6cf36b803b
Signed-off-by: Adam Litke <alitke at redhat.com>
---
A tests/resourcelocker_tests.py
M vdsm.spec.in
M vdsm/storage/Makefile.am
A vdsm/storage/resourceLocker.py
4 files changed, 125 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/43554/1
diff --git a/tests/resourcelocker_tests.py b/tests/resourcelocker_tests.py
new file mode 100644
index 0000000..0ba7461
--- /dev/null
+++ b/tests/resourcelocker_tests.py
@@ -0,0 +1,53 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import uuid
+import threading
+
+from testlib import VdsmTestCase
+
+from storage.resourceLocker import ResourceLocker, LOCK_CACHE_SIZE
+
+
+class ResourceLockerTests(VdsmTestCase):
+ def test_lock_cache(self):
+ def worker(res):
+ locker.acquireResource(res, False)
+ event.set()
+
+ locker = ResourceLocker()
+ event = threading.Event()
+ nr_resources = LOCK_CACHE_SIZE + 1
+ uuid_list = [str(uuid.uuid4()) for _ in range(nr_resources)]
+
+ t = threading.Thread(target=worker, args=(uuid_list[0],))
+ t.daemon = True
+ t.start()
+ event.wait()
+
+ for res in uuid_list[1:]:
+ locker.acquireResource(res, False)
+ locker.releaseResource(res)
+ t.join()
+
+ # The first resource is still in use
+ self.assertIn(uuid_list[0], locker._resources)
+ self.assertNotIn(uuid_list[1], locker._resources)
+
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 966a974..4ba9812 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -930,6 +930,7 @@
%{_datadir}/%{vdsm_name}/storage/persistentDict.py*
%{_datadir}/%{vdsm_name}/storage/resourceFactories.py*
%{_datadir}/%{vdsm_name}/storage/remoteFileHandler.py*
+%{_datadir}/%{vdsm_name}/storage/resourceLocker.py*
%{_datadir}/%{vdsm_name}/storage/resourceManager.py*
%{_datadir}/%{vdsm_name}/storage/clusterlock.py*
%{_datadir}/%{vdsm_name}/storage/sdc.py*
diff --git a/vdsm/storage/Makefile.am b/vdsm/storage/Makefile.am
index 4ebe0a2..a4ec93a 100644
--- a/vdsm/storage/Makefile.am
+++ b/vdsm/storage/Makefile.am
@@ -54,6 +54,7 @@
persistentDict.py \
remoteFileHandler.py \
resourceFactories.py \
+ resourceLocker.py \
resourceManager.py \
sdc.py \
sd.py \
diff --git a/vdsm/storage/resourceLocker.py b/vdsm/storage/resourceLocker.py
new file mode 100644
index 0000000..f6d2403
--- /dev/null
+++ b/vdsm/storage/resourceLocker.py
@@ -0,0 +1,70 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import logging
+import threading
+from contextlib import contextmanager
+from collections import OrderedDict
+
+from storage.misc import RWLock
+
+LOCK_CACHE_SIZE = 50
+
+
+class ResourceLocker(object):
+ log = logging.getLogger('sdm.ResourceLocker')
+
+ def __init__(self):
+ self._lock = threading.Lock()
+ self._resources = OrderedDict()
+
+ def acquireResource(self, res, exclusive):
+ with self._lock:
+ if len(self._resources) >= LOCK_CACHE_SIZE:
+ self._drop_cached_lock()
+ if res not in self._resources:
+ self._resources[res] = RWLock()
+ self._resources[res].acquire(exclusive)
+
+ def releaseResource(self, res):
+ with self._lock:
+ self._resources[res].release()
+
+ @contextmanager
+ def lockResource(self, res, exclusive):
+ self.acquireResource(res, exclusive)
+ try:
+ yield
+ finally:
+ self.releaseResource(res)
+
+ def _drop_cached_lock(self):
+ for res, lock in self._resources.iteritems():
+ if lock.acquire(exclusive=True, block=False):
+ try:
+ self.log.debug("Forgetting lock for resource %s", res)
+ del self._resources[res]
+ return
+ finally:
+ lock.release()
+ self.log.debug("No free locks found")
+
+
+locker = ResourceLocker()
--
To view, visit https://gerrit.ovirt.org/43554
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I29589889efd39920d72979e89405ff6cf36b803b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke at redhat.com>
More information about the vdsm-patches
mailing list