From: Kirill Smelkov <[email protected]>

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: [email protected]
Signed-off-by: Kirill Smelkov <[email protected]>
---
 lib/tdb/pytdb.c                |   27 +++++++++++++++++++++++++++
 lib/tdb/python/tests/simple.py |   12 ++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/lib/tdb/pytdb.c b/lib/tdb/pytdb.c
index c2ba661..f5cb307 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 = NULL;
@@ -165,6 +176,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;
@@ -373,6 +396,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 18180e1..eb7fd17 100644
--- a/lib/tdb/python/tests/simple.py
+++ b/lib/tdb/python/tests/simple.py
@@ -66,6 +66,18 @@ class SimpleTdbTests(TestCase):
         self.tdb.read_lock_all()
         self.tdb.read_unlock_all()
 
+    def test_lockall_nonblock(self):
+        locked = False
+        while not locked:
+            locked = self.tdb.lock_all_nonblock()
+        self.tdb.unlock_all()
+
+    def test_lockall_read_nonblock(self):
+        locked = False
+        while not locked:
+            locked = self.tdb.read_lock_all_nonblock()
+        self.tdb.read_unlock_all()
+
     def test_reopen(self):
         self.tdb.reopen()
 
-- 
1.7.3.1.50.g1e633



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to