Nir Soffer has uploaded a new change for review.
Change subject: rwlock: Add simpler RWLock supporting acquire timeout
......................................................................
rwlock: Add simpler RWLock supporting acquire timeout
We have RWLock implementation in storage.misc, used for by the resource
manager. We want to simplify the resource manager, which is way too
complex to understand or maintain.
Patch
https://gerrit.ovirt.org/42773 suggests to add a non-blocking
acquire to the current RWLock, needed for the new simple lock manager.
However, adding more code to the current RWLock is not a good idea.
Instead, this patch replace the current implementation with a simpler
one.
This implementation does not support recursive locking; I'm not sure we
need this, and usually having a recursive lock is a design smell. We
will add it later only if required.
Change-Id: I2466c137c89598772fb46347eb02195916883cac
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M debian/vdsm-python.install
M lib/vdsm/Makefile.am
A lib/vdsm/rwlock.py
M tests/rwlock_test.py
M vdsm.spec.in
5 files changed, 95 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/08/42908/1
diff --git a/debian/vdsm-python.install b/debian/vdsm-python.install
index 57d5033..3047d9f 100644
--- a/debian/vdsm-python.install
+++ b/debian/vdsm-python.install
@@ -28,6 +28,7 @@
./usr/lib/python2.7/dist-packages/vdsm/pthread.py
./usr/lib/python2.7/dist-packages/vdsm/qemuimg.py
./usr/lib/python2.7/dist-packages/vdsm/response.py
+./usr/lib/python2.7/dist-packages/vdsm/rwlock.py
./usr/lib/python2.7/dist-packages/vdsm/schedule.py
./usr/lib/python2.7/dist-packages/vdsm/sslutils.py
./usr/lib/python2.7/dist-packages/vdsm/tool/__init__.py
diff --git a/lib/vdsm/Makefile.am b/lib/vdsm/Makefile.am
index 95e236f..45cef02 100644
--- a/lib/vdsm/Makefile.am
+++ b/lib/vdsm/Makefile.am
@@ -38,6 +38,7 @@
pthread.py \
qemuimg.py \
response.py \
+ rwlock.py \
schedule.py \
sslutils.py \
sysctl.py \
diff --git a/lib/vdsm/rwlock.py b/lib/vdsm/rwlock.py
new file mode 100644
index 0000000..900d91d
--- /dev/null
+++ b/lib/vdsm/rwlock.py
@@ -0,0 +1,91 @@
+#
+# 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
+#
+
+from __future__ import absolute_import
+import threading
+
+
+class RWLock(object):
+
+ def __init__(self):
+ self._lock = threading.Lock()
+ self._waiters = []
+ self._readers = set()
+ self._writer = None
+
+ def acquireWrite(self):
+ with self._lock:
+ if self._writer or self._readers or self._waiters:
+ self._wait(True)
+ self._writer = threading.current_thread()
+
+ def acquireRead(self):
+ with self._lock:
+ if self._writer or self._waiters:
+ self._wait(False)
+ self._readers.add(threading.current_thread())
+
+ def release(self):
+ me = threading.current_thread()
+ with self._lock:
+ if self._writer:
+ if self._writer is not me:
+ raise RuntimeError("Thread %s attempted to release a "
+ "write lock held by thread %s"
+ % (me, self._writer))
+ self._writer = None
+ else:
+ if me not in self._readers:
+ raise RuntimeError("Thread %s attempted to release a "
+ "read lock it does not hold"
+ % (me,))
+ self._readers.remove(me)
+ if self._waiters:
+ self._wakeup_waiter()
+
+ def _wait(self, wants_write):
+ waiter = Waiter(wants_write)
+ self._waiters.append(waiter)
+ try:
+ self._lock.release()
+ try:
+ waiter.wait()
+ finally:
+ self._lock.acquire()
+ finally:
+ self._waiters.remove(waiter)
+
+ def _wakeup_waiter(self):
+ if self._readers and self._waiters[0].wants_write:
+ return
+ self._waiters[0].wakeup()
+
+
+class Waiter(object):
+
+ def __init__(self, wants_write):
+ self.wants_write = wants_write
+ self._event = threading.Event()
+
+ def wait(self):
+ self._event.wait()
+
+ def wakeup(self):
+ self._event.set()
diff --git a/tests/rwlock_test.py b/tests/rwlock_test.py
index 80d04f1..e67e27a 100644
--- a/tests/rwlock_test.py
+++ b/tests/rwlock_test.py
@@ -25,7 +25,7 @@
from testlib import VdsmTestCase
from testValidation import slowtest, stresstest
-from storage.misc import RWLock
+from vdsm.rwlock import RWLock
class RWLockTests(VdsmTestCase):
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 2b41835..35a9670 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1263,6 +1263,7 @@
%{python_sitelib}/%{vdsm_name}/pthread.py*
%{python_sitelib}/%{vdsm_name}/qemuimg.py*
%{python_sitelib}/%{vdsm_name}/response.py*
+%{python_sitelib}/%{vdsm_name}/rwlock.py*
%{python_sitelib}/%{vdsm_name}/netconfpersistence.py*
%{python_sitelib}/%{vdsm_name}/schedule.py*
%{python_sitelib}/%{vdsm_name}/sslutils.py*
--
To view, visit
https://gerrit.ovirt.org/42908
To unsubscribe, visit
https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2466c137c89598772fb46347eb02195916883cac
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>