diff --git a/core/sharedarea.c b/core/sharedarea.c index 0a14a680..1593b739 100644 --- a/core/sharedarea.c +++ b/core/sharedarea.c @@ -26,16 +26,16 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_get_by_id(int id, uint64_t pos) { return sa; } -int uwsgi_sharedarea_read(int id, uint64_t pos, char *blob, uint64_t len) { +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; if (pos + len > sa->max_pos + 1) return -1; - if (len == 0) len = (sa->max_pos + 1) - pos; + if (len == 0) len = sa->honour_used ? sa->used-pos : (sa->max_pos + 1) - pos; uwsgi_rlock(sa->lock); memcpy(blob, sa->area + pos, len); sa->hits++; uwsgi_rwunlock(sa->lock); - return 0; + return len; } int uwsgi_sharedarea_write(int id, uint64_t pos, char *blob, uint64_t len) { diff --git a/core/websockets.c b/core/websockets.c index bdb8ad12..e03df308 100644 --- a/core/websockets.c +++ b/core/websockets.c @@ -83,7 +83,9 @@ static int uwsgi_websocket_send_do(struct wsgi_request *wsgi_req, char *msg, siz static int uwsgi_websocket_send_from_sharedarea_do(struct wsgi_request *wsgi_req, int id, uint64_t pos, uint64_t len, uint8_t opcode) { struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos); if (!sa) return -1; - if (!len) len = ((sa->max_pos+1)-pos); + if (!len) { + len = sa->honour_used ? sa->used-pos : ((sa->max_pos+1)-pos); + } uwsgi_rlock(sa->lock); sa->hits++; struct uwsgi_buffer *ub = uwsgi_websocket_message(wsgi_req, sa->area, len, opcode); diff --git a/plugins/psgi/uwsgi_plmodule.c b/plugins/psgi/uwsgi_plmodule.c index 3de0a253..1ad10647 100644 --- a/plugins/psgi/uwsgi_plmodule.c +++ b/plugins/psgi/uwsgi_plmodule.c @@ -775,14 +775,15 @@ XS(XS_sharedarea_read) { } char *buf = uwsgi_malloc(len); - if (uwsgi_sharedarea_read(id, pos, buf, len)) { + int64_t rlen = uwsgi_sharedarea_read(id, pos, buf, len); + if (rlen < 0) { free(buf); croak("unable to read from sharedarea %d", id); XSRETURN_UNDEF; } ST(0) = sv_newmortal(); - sv_usepvn(ST(0), buf,len); + sv_usepvn(ST(0), buf, rlen); XSRETURN(1); } diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index aa819d84..a717532d 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1600,14 +1600,17 @@ PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) { #endif UWSGI_RELEASE_GIL - int r = uwsgi_sharedarea_read(id, pos, storage, len); + int64_t rlen = uwsgi_sharedarea_read(id, pos, storage, len); UWSGI_GET_GIL - if (r) { + if (rlen < 0) { Py_DECREF(ret); return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read()"); } + // HACK: we are safe as rlen can only be lower or equal to len + Py_SIZE(ret) = rlen; + return ret; } diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index fdf8e97e..ce4a54ba 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -30,6 +30,12 @@ #define PYTHREE #endif +#if (PY_VERSION_HEX < 0x02060000) +#ifndef Py_SIZE +#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) +#endif +#endif + #define UWSGI_GET_GIL up.gil_get(); #define UWSGI_RELEASE_GIL up.gil_release(); diff --git a/uwsgi.h b/uwsgi.h index 3366efd1..ffe522aa 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -720,6 +720,8 @@ struct uwsgi_sharedarea { uint64_t max_pos; uint64_t updates; uint64_t hits; + uint8_t honour_used; + uint64_t used; }; // maintain alignment here !!! @@ -4567,7 +4569,7 @@ void uwsgi_sharedareas_init(); struct uwsgi_sharedarea *uwsgi_sharedarea_init(int); struct uwsgi_sharedarea *uwsgi_sharedarea_init_ptr(char *, uint64_t); -int uwsgi_sharedarea_read(int, uint64_t, char *, uint64_t); +int64_t uwsgi_sharedarea_read(int, uint64_t, char *, uint64_t); int uwsgi_sharedarea_write(int, uint64_t, char *, uint64_t); int uwsgi_sharedarea_read64(int, uint64_t, int64_t *); int uwsgi_sharedarea_write64(int, uint64_t, int64_t *);