diff --git a/core/sharedarea.c b/core/sharedarea.c index fcb94ce8..cfbbba93 100644 --- a/core/sharedarea.c +++ b/core/sharedarea.c @@ -269,6 +269,27 @@ static struct uwsgi_sharedarea *announce_sa(struct uwsgi_sharedarea *sa) { return sa; } + +struct uwsgi_sharedarea *uwsgi_sharedarea_init_fd(int fd, uint64_t len, off_t offset) { + int id = uwsgi_sharedarea_new_id(); + uwsgi.sharedareas[id] = uwsgi_calloc_shared(sizeof(struct uwsgi_sharedarea)); + uwsgi.sharedareas[id]->area = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset); + if (uwsgi.sharedareas[id]->area == MAP_FAILED) { + uwsgi_error("uwsgi_sharedarea_init_fd()/mmap()"); + exit(1); + } + uwsgi.sharedareas[id]->id = id; + uwsgi.sharedareas[id]->fd = fd; + uwsgi.sharedareas[id]->pages = len / uwsgi.page_size; + if (len % uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++; + uwsgi.sharedareas[id]->max_pos = len-1; + char *id_str = uwsgi_num2str(id); + uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str)); + free(id_str); + return announce_sa(uwsgi.sharedareas[id]); +} + + struct uwsgi_sharedarea *uwsgi_sharedarea_init(int pages) { int id = uwsgi_sharedarea_new_id(); uwsgi.sharedareas[id] = uwsgi_calloc_shared(uwsgi.page_size * (pages + 1)); @@ -304,24 +325,41 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_init_keyval(char *arg) { char *s_fd = NULL; char *s_ptr = NULL; char *s_size = NULL; + char *s_offset = NULL; if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=', "pages", &s_pages, "file", &s_file, "fd", &s_fd, "ptr", &s_ptr, "size", &s_size, + "offset", &s_offset, NULL)) { uwsgi_log("invalid sharedarea keyval syntax\n"); exit(1); } uint64_t len = 0; + off_t offset = 0; int pages = 0; if (s_size) { - len = uwsgi_n64(s_size); + if (strlen(s_size) > 2 && s_size[0] == '0' && s_size[1] == 'x') { + len = strtoul(s_size+2, NULL, 16); + } + else { + len = uwsgi_n64(s_size); + } pages = len / uwsgi.page_size; if (len % uwsgi.page_size != 0) pages++; } + + if (s_offset) { + if (strlen(s_offset) > 2 && s_offset[0] == '0' && s_offset[1] == 'x') { + offset = strtoul(s_offset+2, NULL, 16); + } + else { + offset = uwsgi_n64(s_offset); + } + } if (s_pages) { pages = atoi(s_pages); @@ -329,27 +367,43 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_init_keyval(char *arg) { char *area = NULL; struct uwsgi_sharedarea *sa = NULL; + + int fd = -1; if (s_file) { + fd = open(s_file, O_RDWR|O_SYNC); + if (fd < 0) { + uwsgi_error_open(s_file); + exit(1); + } } else if (s_fd) { + fd = atoi(s_fd); } else if (s_ptr) { } if (pages) { - if (!area) { - sa = uwsgi_sharedarea_init(pages); + if (fd > -1) { + sa = uwsgi_sharedarea_init_fd(fd, len, offset); + } + else if (area) { + sa = uwsgi_sharedarea_init_ptr(area, len); } else { - uwsgi_sharedarea_init_ptr(area, len); + sa = uwsgi_sharedarea_init(pages); } } + else { + uwsgi_log("you need to set a size for a sharedarea !!! [%s]\n", arg); + exit(1); + } if (s_pages) free(s_pages); if (s_file) free(s_file); if (s_fd) free(s_fd); if (s_ptr) free(s_ptr); if (s_size) free(s_size); + if (s_offset) free(s_offset); return sa; } diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 08e69678..fb0bfd6d 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1426,7 +1426,7 @@ PyObject *py_uwsgi_sharedarea_inc64(PyObject * self, PyObject * args) { uint64_t pos = 0; int64_t value = 1; - if (!PyArg_ParseTuple(args, "il|l:sharedarea_inc64", &id, &pos, &value)) { + if (!PyArg_ParseTuple(args, "iL|l:sharedarea_inc64", &id, &pos, &value)) { return NULL; } @@ -1443,12 +1443,56 @@ PyObject *py_uwsgi_sharedarea_inc64(PyObject * self, PyObject * args) { } +PyObject *py_uwsgi_sharedarea_write32(PyObject * self, PyObject * args) { + int id; + uint64_t pos = 0; + int32_t value = 0; + + if (!PyArg_ParseTuple(args, "iLI:sharedarea_write32", &id, &pos, &value)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_write32(id, pos, &value); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write32()"); + } + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_uwsgi_sharedarea_write16(PyObject * self, PyObject * args) { + int id; + uint64_t pos = 0; + int16_t value = 0; + + if (!PyArg_ParseTuple(args, "iLI:sharedarea_write16", &id, &pos, &value)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_write16(id, pos, &value); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write16()"); + } + + Py_INCREF(Py_None); + return Py_None; +} + + + PyObject *py_uwsgi_sharedarea_write64(PyObject * self, PyObject * args) { int id; uint64_t pos = 0; int64_t value = 0; - if (!PyArg_ParseTuple(args, "ill:sharedarea_write64", &id, &pos, &value)) { + if (!PyArg_ParseTuple(args, "iLL:sharedarea_write64", &id, &pos, &value)) { return NULL; } @@ -1470,7 +1514,7 @@ PyObject *py_uwsgi_sharedarea_write(PyObject * self, PyObject * args) { char *value; Py_ssize_t value_len = 0; - if (!PyArg_ParseTuple(args, "ils#:sharedarea_write", &id, &pos, &value, &value_len)) { + if (!PyArg_ParseTuple(args, "iLs#:sharedarea_write", &id, &pos, &value, &value_len)) { return NULL; } @@ -1570,7 +1614,7 @@ PyObject *py_uwsgi_sharedarea_write8(PyObject * self, PyObject * args) { uint64_t pos = 0; int8_t value; - if (!PyArg_ParseTuple(args, "ilb:sharedarea_write8", &id, &pos, &value)) { + if (!PyArg_ParseTuple(args, "iLb:sharedarea_write8", &id, &pos, &value)) { return NULL; } @@ -1592,7 +1636,7 @@ PyObject *py_uwsgi_sharedarea_read64(PyObject * self, PyObject * args) { uint64_t pos = 0; int64_t value; - if (!PyArg_ParseTuple(args, "il:sharedarea_read64", &id, &pos)) { + if (!PyArg_ParseTuple(args, "iL:sharedarea_read64", &id, &pos)) { return NULL; } @@ -1608,12 +1652,55 @@ PyObject *py_uwsgi_sharedarea_read64(PyObject * self, PyObject * args) { } +PyObject *py_uwsgi_sharedarea_read32(PyObject * self, PyObject * args) { + int id; + uint64_t pos = 0; + int32_t value; + + if (!PyArg_ParseTuple(args, "iL:sharedarea_read32", &id, &pos)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_read32(id, pos, &value); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read32()"); + } + + return PyInt_FromLong(value); + +} + +PyObject *py_uwsgi_sharedarea_read16(PyObject * self, PyObject * args) { + int id; + uint64_t pos = 0; + int16_t value; + + if (!PyArg_ParseTuple(args, "iL:sharedarea_read16", &id, &pos)) { + return NULL; + } + + UWSGI_RELEASE_GIL + int ret = uwsgi_sharedarea_read16(id, pos, &value); + UWSGI_GET_GIL + + if (ret) { + return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read16()"); + } + + return PyInt_FromLong(value); + +} + + PyObject *py_uwsgi_sharedarea_read8(PyObject * self, PyObject * args) { int id; uint64_t pos = 0; int8_t byte; - if (!PyArg_ParseTuple(args, "il:sharedarea_read8", &id, &pos)) { + if (!PyArg_ParseTuple(args, "iL:sharedarea_read8", &id, &pos)) { return NULL; } @@ -1633,7 +1720,7 @@ PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) { uint64_t pos = 0; uint64_t len = 0; - if (!PyArg_ParseTuple(args, "il|l:sharedarea_read", &id, &pos, &len)) { + if (!PyArg_ParseTuple(args, "iL|L:sharedarea_read", &id, &pos, &len)) { return NULL; } @@ -2459,6 +2546,10 @@ static PyMethodDef uwsgi_sa_methods[] = { {"sharedarea_writelong", py_uwsgi_sharedarea_write64, METH_VARARGS, ""}, {"sharedarea_read64", py_uwsgi_sharedarea_read64, METH_VARARGS, ""}, {"sharedarea_write64", py_uwsgi_sharedarea_write64, METH_VARARGS, ""}, + {"sharedarea_read32", py_uwsgi_sharedarea_read32, METH_VARARGS, ""}, + {"sharedarea_write32", py_uwsgi_sharedarea_write32, METH_VARARGS, ""}, + {"sharedarea_read16", py_uwsgi_sharedarea_read16, METH_VARARGS, ""}, + {"sharedarea_write16", py_uwsgi_sharedarea_write16, 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, ""}, diff --git a/uwsgi.h b/uwsgi.h index eb9b6ca5..30f80640 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -4734,6 +4734,7 @@ void uwsgi_sharedareas_init(); struct uwsgi_sharedarea *uwsgi_sharedarea_init(int); struct uwsgi_sharedarea *uwsgi_sharedarea_init_ptr(char *, uint64_t); +struct uwsgi_sharedarea *uwsgi_sharedarea_init_fd(int, uint64_t, off_t); int64_t uwsgi_sharedarea_read(int, uint64_t, char *, uint64_t); int uwsgi_sharedarea_write(int, uint64_t, char *, uint64_t);