[PATCH 02/14] pytdb: Add support for tdb_lockall_nonblock() & tdb_lockall_read_nonblock()
Kirill Smelkov
kirr at landau.phys.spbu.ru
Sat Oct 2 07:43:41 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 | 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
More information about the samba-technical
mailing list