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]

