From 5bb7f02921dbf35d05f776c640c63f6ad3f2d378 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Tue, 10 Dec 2013 07:33:45 +0100 Subject: [PATCH] added memoryview wrapper for sharedarea and locking api --- core/sharedarea.c | 34 +++++++++++-- plugins/python/uwsgi_pymodule.c | 86 +++++++++++++++++++++++++++++++++ uwsgi.h | 3 ++ 3 files changed, 119 insertions(+), 4 deletions(-) diff --git a/core/sharedarea.c b/core/sharedarea.c index 680ed0e4..dcb91d2e 100644 --- a/core/sharedarea.c +++ b/core/sharedarea.c @@ -26,6 +26,28 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_get_by_id(int id, uint64_t pos) { return sa; } +int uwsgi_sharedarea_rlock(int id) { + struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0); + if (!sa) return -1; + uwsgi_rlock(sa->lock); + return 0; +} + +int uwsgi_sharedarea_wlock(int id) { + struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0); + if (!sa) return -1; + uwsgi_wlock(sa->lock); + return 0; +} + +int uwsgi_sharedarea_unlock(int id) { + struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0); + if (!sa) return -1; + uwsgi_rwunlock(sa->lock); + return 0; +} + + int64_t uwsgi_sharedarea_read(int id, uint64_t pos, char *blob, uint64_t len) { struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos); if (!sa) return -1; @@ -51,7 +73,8 @@ int uwsgi_sharedarea_write(int id, uint64_t pos, char *blob, uint64_t len) { } int uwsgi_sharedarea_read64(int id, uint64_t pos, int64_t *value) { - return uwsgi_sharedarea_read(id, pos, (char *) value, 8); + int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 8); + return rlen == 8 ? 0 : -1; } int uwsgi_sharedarea_write64(int id, uint64_t pos, int64_t *value) { @@ -59,7 +82,8 @@ int uwsgi_sharedarea_write64(int id, uint64_t pos, int64_t *value) { } int uwsgi_sharedarea_read8(int id, uint64_t pos, int8_t *value) { - return uwsgi_sharedarea_read(id, pos, (char *) value, 1); + int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 1); + return rlen == 1 ? 0 : -1; } int uwsgi_sharedarea_write8(int id, uint64_t pos, int8_t *value) { @@ -67,7 +91,8 @@ int uwsgi_sharedarea_write8(int id, uint64_t pos, int8_t *value) { } int uwsgi_sharedarea_read16(int id, uint64_t pos, int16_t *value) { - return uwsgi_sharedarea_read(id, pos, (char *) value, 2); + int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 2); + return rlen == 2 ? 0 : -1; } int uwsgi_sharedarea_write16(int id, uint64_t pos, int16_t *value) { @@ -76,7 +101,8 @@ int uwsgi_sharedarea_write16(int id, uint64_t pos, int16_t *value) { int uwsgi_sharedarea_read32(int id, uint64_t pos, int32_t *value) { - return uwsgi_sharedarea_read(id, pos, (char *) value, 4); + int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 4); + return rlen == 4 ? 0 : -1; } int uwsgi_sharedarea_write32(int id, uint64_t pos, int32_t *value) { diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index a717532d..c87a1c15 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1512,6 +1512,69 @@ PyObject *py_uwsgi_sharedarea_write(PyObject * self, PyObject * args) { return Py_None; } +PyObject *py_uwsgi_sharedarea_rlock(PyObject * self, PyObject * args) { + int id; + + if (!PyArg_ParseTuple(args, "i:sharedarea_rlock", &id)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_rlock(id); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_rlock()"); + } + + Py_INCREF(Py_None); + return Py_None; + +} + +PyObject *py_uwsgi_sharedarea_wlock(PyObject * self, PyObject * args) { + int id; + + if (!PyArg_ParseTuple(args, "i:sharedarea_wlock", &id)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_wlock(id); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_wlock()"); + } + + Py_INCREF(Py_None); + return Py_None; + +} + +PyObject *py_uwsgi_sharedarea_unlock(PyObject * self, PyObject * args) { + int id; + + if (!PyArg_ParseTuple(args, "i:sharedarea_unlock", &id)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_unlock(id); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_unlock()"); + } + + Py_INCREF(Py_None); + return Py_None; + +} + + + + PyObject *py_uwsgi_sharedarea_write8(PyObject * self, PyObject * args) { int id; uint64_t pos = 0; @@ -1614,6 +1677,23 @@ PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) { return ret; } +#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER) +PyObject *py_uwsgi_sharedarea_memoryview(PyObject * self, PyObject * args) { + int id; + if (!PyArg_ParseTuple(args, "i:sharedarea_memoryview", &id)) { + return NULL; + } + struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0); + if (!sa) { + return PyErr_Format(PyExc_ValueError, "cannot get a memoryview object from sharedarea %d", id); + } + Py_buffer info; + if (PyBuffer_FillInfo(&info, NULL, sa->area, sa->max_pos+1, 0, PyBUF_CONTIG) < 0) + return PyErr_Format(PyExc_ValueError, "cannot get a memoryview object from sharedarea %d", id); + return PyMemoryView_FromBuffer(&info); +} +#endif + PyObject *py_uwsgi_spooler_freq(PyObject * self, PyObject * args) { if (!PyArg_ParseTuple(args, "i", &uwsgi.shared->spooler_frequency)) { @@ -2498,6 +2578,12 @@ static PyMethodDef uwsgi_sa_methods[] = { {"sharedarea_write64", py_uwsgi_sharedarea_write64, METH_VARARGS, ""}, {"sharedarea_inclong", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""}, {"sharedarea_inc64", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""}, + {"sharedarea_rlock", py_uwsgi_sharedarea_rlock, METH_VARARGS, ""}, + {"sharedarea_wlock", py_uwsgi_sharedarea_wlock, METH_VARARGS, ""}, + {"sharedarea_unlock", py_uwsgi_sharedarea_unlock, METH_VARARGS, ""}, +#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER) + {"sharedarea_memoryview", py_uwsgi_sharedarea_memoryview, METH_VARARGS, ""}, +#endif {NULL, NULL}, }; diff --git a/uwsgi.h b/uwsgi.h index d15dbc66..bffc6152 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -4602,6 +4602,9 @@ int uwsgi_sharedarea_dec16(int, uint64_t, int16_t); int uwsgi_sharedarea_dec32(int, uint64_t, int32_t); int uwsgi_sharedarea_dec64(int, uint64_t, int64_t); int uwsgi_sharedarea_wait(int, int, int); +int uwsgi_sharedarea_unlock(int); +int uwsgi_sharedarea_rlock(int); +int uwsgi_sharedarea_wlock(int); struct uwsgi_sharedarea *uwsgi_sharedarea_get_by_id(int, uint64_t); int uwsgi_websocket_send_from_sharedarea(struct wsgi_request *, int, uint64_t, uint64_t);