[PATCH 04/14] pytdb: Add support for tdb_lockall_nonblock() & tdb_lockall_read_nonblock()

Kirill Smelkov kirr at landau.phys.spbu.ru
Sun Sep 19 03:53:22 MDT 2010


From: Kirill Smelkov <kirr at mns.spb.ru>

The API is a bit different from tdb_lockall() & friends -- we return
True or False depending on whether lock was taken (and raise on errors).

It's better to put boilerplate code which implements return/raise logic
into macro, becase it is needed twise here, and also we'll need it soon
for tdb_chainlock_nonblock() soon.

NOTE

Py_RETURN_TRUE / Py_RETURN_FALSE were introduced in Python 2.4, so
if we need to support older Pythons, we can always hand-write it as we
did with Py_RETURN_NONE.

Or if we support only Python >= 2.4, we should kill our own #define for
Py_RETURN_NONE.

Cc: 597386 at bugs.debian.org
Signed-off-by: Kirill Smelkov <kirr at mns.spb.ru>
---
 lib/tdb/pytdb.c                |   27 +++++++++++++++++++++++++++
 lib/tdb/python/tests/simple.py |   10 ++++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/lib/tdb/pytdb.c b/lib/tdb/pytdb.c
index e50615f..11f3648 100644
--- a/lib/tdb/pytdb.c
+++ b/lib/tdb/pytdb.c
@@ -75,6 +75,17 @@ static PyObject *PyString_FromTDB_DATA(TDB_DATA data)
 		return NULL; \
 	}
 
+/* after lock_*_nonblock(), return True|False or raise */
+#define	PyTdb_LOCK_NONBLOCK_RET_OR_RAISE(ret, tdb) do { \
+	if (ret != 0) { \
+		if (tdb_error(self->ctx) == TDB_ERR_LOCK && errno == EAGAIN) \
+			Py_RETURN_FALSE; \
+		PyErr_SetTDBError(self->ctx); \
+		return NULL; \
+	} \
+	Py_RETURN_TRUE; \
+} while (0)
+
 static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
 	char *name;
@@ -154,6 +165,18 @@ static PyObject *obj_unlockall_read(PyTdbObject *self)
 	Py_RETURN_NONE;
 }
 
+static PyObject *obj_lockall_nonblock(PyTdbObject *self)
+{
+	int ret = tdb_lockall_nonblock(self->ctx);
+	PyTdb_LOCK_NONBLOCK_RET_OR_RAISE(ret, self->ctx);
+}
+
+static PyObject *obj_lockall_read_nonblock(PyTdbObject *self)
+{
+	int ret = tdb_lockall_read_nonblock(self->ctx);
+	PyTdb_LOCK_NONBLOCK_RET_OR_RAISE(ret, self->ctx);
+}
+
 static PyObject *obj_close(PyTdbObject *self)
 {
 	int ret;
@@ -347,6 +370,10 @@ static PyMethodDef tdb_object_methods[] = {
 	{ "unlock_all", (PyCFunction)obj_unlockall, METH_NOARGS, NULL },
 	{ "read_lock_all", (PyCFunction)obj_lockall_read, METH_NOARGS, NULL },
 	{ "read_unlock_all", (PyCFunction)obj_unlockall_read, METH_NOARGS, NULL },
+	{ "lock_all_nonblock", (PyCFunction)obj_lockall_nonblock, METH_NOARGS,
+		"S.lock_all_nonblock() -> True|False" },
+	{ "read_lock_all_nonblock", (PyCFunction)obj_lockall_read_nonblock, METH_NOARGS,
+		"S.read_lock_all_nonblock() -> True|False" },
 	{ "close", (PyCFunction)obj_close, METH_NOARGS, NULL },
 	{ "get", (PyCFunction)obj_get, METH_VARARGS, "S.get(key) -> value\n"
 		"Fetch a value." },
diff --git a/lib/tdb/python/tests/simple.py b/lib/tdb/python/tests/simple.py
index 258a486..70a03b8 100644
--- a/lib/tdb/python/tests/simple.py
+++ b/lib/tdb/python/tests/simple.py
@@ -64,6 +64,16 @@ class SimpleTdbTests(TestCase):
         self.tdb.read_lock_all()
         self.tdb.read_unlock_all()
 
+    def test_lockall_nonblock(self):
+        locked = self.tdb.lock_all_nonblock()
+        if locked:
+            self.tdb.unlock_all()
+
+    def test_lockall_read_nonblock(self):
+        locked = self.tdb.read_lock_all_nonblock()
+        if locked:
+            self.tdb.read_unlock_all()
+
     def test_reopen(self):
         self.tdb.reopen()
 
-- 
1.7.3.rc2


More information about the samba-technical mailing list