mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-08 14:41:55 +00:00
preliminary api for language-independent body read another step completed body read language independent implementation ported gevent to the new read/write api ported websockets to the new read/write api removed channels subsystem removed channels subsystem ported lua to the new read/write api fixed post-buffering readline is still broken improved request body readline very difficult test for readline()/read() combo passed other improvements in postbuffering/read/readline ported --http-socket to the new api added X-Forwarded-SSL management removed old api more refactoring ported the RACK plugin to the new api ported psgi plugin to the new api defintely removed clustering simpified ifdel hell simpified ifdef hell removed useless configuration options
3515 lines
81 KiB
C
3515 lines
81 KiB
C
#include "uwsgi_python.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
extern struct uwsgi_python up;
|
|
|
|
PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
int wait_for_specific_signal = 0;
|
|
uint8_t uwsgi_signal = 0;
|
|
int received_signal;
|
|
|
|
wsgi_req->signal_received = -1;
|
|
|
|
if (PyTuple_Size(args) > 0) {
|
|
if (!PyArg_ParseTuple(args, "|B:", &uwsgi_signal)) {
|
|
return NULL;
|
|
}
|
|
wait_for_specific_signal = 1;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL;
|
|
|
|
if (wait_for_specific_signal) {
|
|
received_signal = uwsgi_signal_wait(uwsgi_signal);
|
|
}
|
|
else {
|
|
received_signal = uwsgi_signal_wait(-1);
|
|
}
|
|
|
|
if (received_signal < 0) {
|
|
UWSGI_GET_GIL;
|
|
return PyErr_Format(PyExc_SystemError, "error waiting for signal");
|
|
}
|
|
|
|
wsgi_req->signal_received = received_signal;
|
|
|
|
UWSGI_GET_GIL;
|
|
|
|
return PyString_FromString("");
|
|
}
|
|
|
|
PyObject *py_uwsgi_signal_received(PyObject * self, PyObject * args) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
return PyInt_FromLong(wsgi_req->signal_received);
|
|
}
|
|
|
|
|
|
char *uwsgi_encode_pydict(PyObject * pydict, uint16_t * size) {
|
|
|
|
int i;
|
|
PyObject *zero, *key, *val;
|
|
uint16_t keysize, valsize;
|
|
|
|
|
|
char *buf, *bufptr;
|
|
|
|
PyObject *vars = PyDict_Items(pydict);
|
|
|
|
if (!vars) {
|
|
PyErr_Print();
|
|
return NULL;
|
|
}
|
|
|
|
*size = 0;
|
|
|
|
// calc the packet size
|
|
// try to fallback whenever possible
|
|
for (i = 0; i < PyList_Size(vars); i++) {
|
|
zero = PyList_GetItem(vars, i);
|
|
if (!zero) {
|
|
PyErr_Print();
|
|
continue;
|
|
}
|
|
|
|
if (!PyTuple_Check(zero)) {
|
|
uwsgi_log("invalid python dictionary item\n");
|
|
continue;
|
|
}
|
|
|
|
if (PyTuple_Size(zero) < 2) {
|
|
uwsgi_log("invalid python dictionary item\n");
|
|
continue;
|
|
}
|
|
key = PyTuple_GetItem(zero, 0);
|
|
val = PyTuple_GetItem(zero, 1);
|
|
|
|
if (!PyString_Check(key) || !PyString_Check(val)) {
|
|
continue;
|
|
}
|
|
|
|
|
|
keysize = PyString_Size(key);
|
|
valsize = PyString_Size(val);
|
|
|
|
*size += (keysize + 2 + valsize + 2);
|
|
|
|
// do not DECREF here !!!
|
|
//Py_DECREF(zero);
|
|
}
|
|
|
|
if (*size <= 4) {
|
|
uwsgi_log("empty python dictionary\n");
|
|
return NULL;
|
|
}
|
|
|
|
// remember to free this memory !!!
|
|
buf = malloc(*size);
|
|
if (!buf) {
|
|
uwsgi_error("malloc()");
|
|
return NULL;
|
|
}
|
|
|
|
bufptr = buf;
|
|
|
|
for (i = 0; i < PyList_Size(vars); i++) {
|
|
zero = PyList_GetItem(vars, i);
|
|
if (!zero) {
|
|
PyErr_Print();
|
|
continue;
|
|
}
|
|
|
|
if (!PyTuple_Check(zero)) {
|
|
uwsgi_log("invalid python dictionary item\n");
|
|
Py_DECREF(zero);
|
|
continue;
|
|
}
|
|
|
|
if (PyTuple_Size(zero) < 2) {
|
|
uwsgi_log("invalid python dictionary item\n");
|
|
Py_DECREF(zero);
|
|
continue;
|
|
}
|
|
key = PyTuple_GetItem(zero, 0);
|
|
val = PyTuple_GetItem(zero, 1);
|
|
|
|
|
|
if (!key || !val) {
|
|
PyErr_Print();
|
|
continue;
|
|
}
|
|
|
|
if (!PyString_Check(key) || !PyString_Check(val)) {
|
|
Py_DECREF(zero);
|
|
continue;
|
|
}
|
|
|
|
|
|
keysize = PyString_Size(key);
|
|
valsize = PyString_Size(val);
|
|
if (bufptr + keysize + 2 + valsize + 2 <= buf + *size) {
|
|
|
|
*bufptr++ = (uint8_t) (keysize & 0xff);
|
|
*bufptr++ = (uint8_t) ((keysize >> 8) & 0xff);
|
|
memcpy(bufptr, PyString_AsString(key), keysize);
|
|
bufptr += keysize;
|
|
|
|
*bufptr++ = (uint8_t) (valsize & 0xff);
|
|
*bufptr++ = (uint8_t) ((valsize >> 8) & 0xff);
|
|
memcpy(bufptr, PyString_AsString(val), valsize);
|
|
bufptr += valsize;
|
|
}
|
|
|
|
Py_DECREF(zero);
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_listen_queue(PyObject * self, PyObject * args) {
|
|
|
|
return PyInt_FromLong(uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS]);
|
|
}
|
|
|
|
PyObject *py_uwsgi_close(PyObject * self, PyObject * args) {
|
|
|
|
int fd;
|
|
|
|
if (!PyArg_ParseTuple(args, "i:close", &fd)) {
|
|
return NULL;
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_add_cron(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
int minute, hour, day, month, week;
|
|
|
|
if (!PyArg_ParseTuple(args, "Biiiii:add_cron", &uwsgi_signal, &minute, &hour, &day, &month, &week)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_signal_add_cron(uwsgi_signal, minute, hour, day, month, week)) {
|
|
return PyErr_Format(PyExc_ValueError, "unable to add cron");
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_add_probe(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
int timeout = 0;
|
|
int freq = 0;
|
|
char *probe, *probe_args;
|
|
|
|
if (!PyArg_ParseTuple(args, "Bss|ii:add_probe", &uwsgi_signal, &probe, &probe_args, &timeout, &freq)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_add_probe(uwsgi_signal, probe, probe_args, timeout, freq))
|
|
return PyErr_Format(PyExc_ValueError, "unable to add probe");
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
|
|
PyObject *py_uwsgi_add_timer(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
int secs;
|
|
|
|
if (!PyArg_ParseTuple(args, "Bi:add_timer", &uwsgi_signal, &secs)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_add_timer(uwsgi_signal, secs))
|
|
return PyErr_Format(PyExc_ValueError, "unable to add timer");
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_add_rb_timer(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
int secs;
|
|
int iterations = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "Bi|i:add_rb_timer", &uwsgi_signal, &secs, &iterations)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_signal_add_rb_timer(uwsgi_signal, secs, iterations))
|
|
return PyErr_Format(PyExc_ValueError, "unable to add rb_timer");
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
|
|
PyObject *py_uwsgi_add_file_monitor(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
char *filename;
|
|
|
|
if (!PyArg_ParseTuple(args, "Bs:add_file_monitor", &uwsgi_signal, &filename)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_add_file_monitor(uwsgi_signal, filename))
|
|
return PyErr_Format(PyExc_ValueError, "unable to add file monitor");
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_call(PyObject * self, PyObject * args) {
|
|
|
|
char *func;
|
|
uint16_t size = 0;
|
|
PyObject *py_func;
|
|
int argc = PyTuple_Size(args);
|
|
int i;
|
|
char *argv[256];
|
|
uint16_t argvs[256];
|
|
|
|
// TODO better error reporting
|
|
if (argc < 1)
|
|
goto clear;
|
|
|
|
py_func = PyTuple_GetItem(args, 0);
|
|
|
|
if (!PyString_Check(py_func))
|
|
goto clear;
|
|
|
|
func = PyString_AsString(py_func);
|
|
|
|
for (i = 0; i < (argc - 1); i++) {
|
|
PyObject *py_str = PyTuple_GetItem(args, i + 1);
|
|
if (!PyString_Check(py_str)) {
|
|
goto clear;
|
|
}
|
|
argv[i] = PyString_AsString(py_str);
|
|
argvs[i] = PyString_Size(py_str);
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL;
|
|
// response must always be freed
|
|
char *response = uwsgi_do_rpc(NULL, func, argc - 1, argv, argvs, &size);
|
|
UWSGI_GET_GIL;
|
|
|
|
if (size > 0) {
|
|
PyObject *ret = PyString_FromStringAndSize(response, size);
|
|
free(response);
|
|
return ret;
|
|
}
|
|
|
|
free(response);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
clear:
|
|
|
|
return PyErr_Format(PyExc_ValueError, "unable to call rpc function");
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_rpc_list(PyObject * self, PyObject * args) {
|
|
|
|
int i;
|
|
PyObject *rpc_list = PyTuple_New(uwsgi.shared->rpc_count);
|
|
|
|
for (i = 0; i < uwsgi.shared->rpc_count; i++) {
|
|
if (uwsgi.shared->rpc_table[i].name[0] != 0) {
|
|
PyTuple_SetItem(rpc_list, i, PyString_FromString(uwsgi.shared->rpc_table[i].name));
|
|
}
|
|
}
|
|
|
|
return rpc_list;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
|
|
|
char *node = NULL, *func;
|
|
uint16_t size = 0;
|
|
PyObject *py_node, *py_func;
|
|
|
|
int argc = PyTuple_Size(args);
|
|
char *argv[256];
|
|
uint16_t argvs[256];
|
|
|
|
int i;
|
|
|
|
// TODO better error reporting
|
|
if (argc < 2)
|
|
goto clear;
|
|
|
|
py_node = PyTuple_GetItem(args, 0);
|
|
|
|
if (PyString_Check(py_node)) {
|
|
node = PyString_AsString(py_node);
|
|
}
|
|
|
|
py_func = PyTuple_GetItem(args, 1);
|
|
|
|
if (!PyString_Check(py_func))
|
|
goto clear;
|
|
|
|
func = PyString_AsString(py_func);
|
|
|
|
for (i = 0; i < (argc - 2); i++) {
|
|
PyObject *py_str = PyTuple_GetItem(args, i + 2);
|
|
if (!PyString_Check(py_str))
|
|
goto clear;
|
|
argv[i] = PyString_AsString(py_str);
|
|
argvs[i] = PyString_Size(py_str);
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL;
|
|
char *response = uwsgi_do_rpc(node, func, argc - 2, argv, argvs, &size);
|
|
UWSGI_GET_GIL;
|
|
|
|
if (size > 0) {
|
|
PyObject *ret = PyString_FromStringAndSize(response, size);
|
|
free(response);
|
|
return ret;
|
|
}
|
|
|
|
free(response);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
clear:
|
|
|
|
return PyErr_Format(PyExc_ValueError, "unable to call rpc function");
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_register_rpc(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t argc = 0;
|
|
char *name;
|
|
PyObject *func;
|
|
|
|
if (!PyArg_ParseTuple(args, "sO|B:register_rpc", &name, &func, &argc)) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if (uwsgi_register_rpc(name, 0, argc, func)) {
|
|
return PyErr_Format(PyExc_ValueError, "unable to register rpc function");
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
PyObject *py_uwsgi_signal_registered(PyObject * self, PyObject * args) {
|
|
uint8_t uwsgi_signal;
|
|
|
|
if (!PyArg_ParseTuple(args, "B:signal_registered", &uwsgi_signal)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_signal_registered(uwsgi_signal)) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_i_am_the_lord(PyObject * self, PyObject * args) {
|
|
char *legion_name = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:i_am_the_lord", &legion_name)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_legion_i_am_the_lord(legion_name)) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
Py_INCREF(Py_False);
|
|
return Py_False;
|
|
}
|
|
|
|
PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
char *signal_kind;
|
|
PyObject *handler;
|
|
|
|
if (!PyArg_ParseTuple(args, "BsO:register_signal", &uwsgi_signal, &signal_kind, &handler)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_register_signal(uwsgi_signal, signal_kind, handler, 0)) {
|
|
return PyErr_Format(PyExc_ValueError, "unable to register signal");
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_signal(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t uwsgi_signal;
|
|
char *remote = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "B|s:signal", &uwsgi_signal, &remote)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (remote) {
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("sending signal %d to node %s\n", uwsgi_signal, remote);
|
|
#endif
|
|
int ret = uwsgi_remote_signal_send(remote, uwsgi_signal);
|
|
if (ret == 1) goto clear;
|
|
if (ret == -1)
|
|
return PyErr_Format(PyExc_IOError, "unable to deliver signal %d to node %s", uwsgi_signal, remote);
|
|
if (ret == 0)
|
|
return PyErr_Format(PyExc_ValueError, "node %s rejected signal %d", remote, uwsgi_signal);
|
|
}
|
|
else {
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("sending signal %d to master\n", uwsgi_signal);
|
|
#endif
|
|
uwsgi_signal_send(uwsgi.signal_socket, uwsgi_signal);
|
|
}
|
|
|
|
clear:
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_log_this(PyObject * self, PyObject * args) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
wsgi_req->log_this = 1;
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_get_logvar(PyObject * self, PyObject * args) {
|
|
|
|
char *key = NULL;
|
|
Py_ssize_t keylen = 0;
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
if (!PyArg_ParseTuple(args, "s#:get_logvar", &key, &keylen)) {
|
|
return NULL;
|
|
}
|
|
|
|
struct uwsgi_logvar *lv = uwsgi_logvar_get(wsgi_req, key, keylen);
|
|
|
|
if (lv) {
|
|
return PyString_FromStringAndSize(lv->val, lv->vallen);
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_set_logvar(PyObject * self, PyObject * args) {
|
|
|
|
char *key = NULL;
|
|
Py_ssize_t keylen = 0;
|
|
char *val = NULL;
|
|
Py_ssize_t vallen = 0;
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
if (!PyArg_ParseTuple(args, "s#s#:set_logvar", &key, &keylen, &val, &vallen)) {
|
|
return NULL;
|
|
}
|
|
|
|
uwsgi_logvar_add(wsgi_req, key, keylen, val, vallen);
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_recv_block(PyObject * self, PyObject * args) {
|
|
|
|
char buf[4096];
|
|
char *bufptr;
|
|
ssize_t rlen = 0, len;
|
|
int fd, size, remains, ret, timeout = -1;
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "ii|i:recv_block", &fd, &size, &timeout)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (fd < 0)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
// security check
|
|
if (size > 4096)
|
|
size = 4096;
|
|
|
|
remains = size;
|
|
|
|
bufptr = buf;
|
|
while (remains > 0) {
|
|
uwsgi_log("%d %d %d\n", remains, size, timeout);
|
|
ret = uwsgi_waitfd(fd, timeout);
|
|
if (ret > 0) {
|
|
len = read(fd, bufptr, UMIN(remains, size));
|
|
if (len > 0) {
|
|
bufptr += len;
|
|
rlen += len;
|
|
remains -= len;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
uwsgi_log("error waiting for block data\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
UWSGI_GET_GIL if (rlen == size) {
|
|
return PyString_FromStringAndSize(buf, rlen);
|
|
}
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_recv(PyObject * self, PyObject * args) {
|
|
|
|
int fd, max_size = 4096;
|
|
char buf[4096];
|
|
ssize_t rlen;
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "i|i:recv", &fd, &max_size)) {
|
|
return NULL;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
// security check
|
|
if (max_size > 4096)
|
|
max_size = 4096;
|
|
|
|
rlen = read(fd, buf, max_size);
|
|
|
|
UWSGI_GET_GIL if (rlen > 0) {
|
|
return PyString_FromStringAndSize(buf, rlen);
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_is_connected(PyObject * self, PyObject * args) {
|
|
|
|
int fd, soopt;
|
|
socklen_t solen = sizeof(int);
|
|
|
|
if (!PyArg_ParseTuple(args, "i:is_connected", &fd)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) {
|
|
uwsgi_error("getsockopt()");
|
|
goto clear;
|
|
}
|
|
/* is something bad ? */
|
|
if (soopt)
|
|
goto clear;
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_send(PyObject * self, PyObject * args) {
|
|
|
|
PyObject *data;
|
|
PyObject *arg1, *arg2;
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
int uwsgi_fd = wsgi_req->fd;
|
|
|
|
if (!PyArg_ParseTuple(args, "O|O:send", &arg1, &arg2)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (PyTuple_Size(args) > 1) {
|
|
uwsgi_fd = PyInt_AsLong(arg1);
|
|
data = arg2;
|
|
}
|
|
else {
|
|
data = arg1;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL if (write(uwsgi_fd, PyString_AsString(data), PyString_Size(data)) < 0) {
|
|
uwsgi_error("write()");
|
|
UWSGI_GET_GIL Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_GET_GIL Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_offload_transfer(PyObject * self, PyObject * args) {
|
|
size_t len = 0;
|
|
char *filename = NULL;
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
if (!PyArg_ParseTuple(args, "s|i:offload_transfer", &filename, &len)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (!wsgi_req->socket->can_offload) {
|
|
return PyErr_Format(PyExc_ValueError, "The current socket does not support offloading");
|
|
}
|
|
|
|
if (!wsgi_req->headers_sent) {
|
|
UWSGI_RELEASE_GIL
|
|
if (uwsgi_response_write_headers_do(wsgi_req)) {
|
|
UWSGI_GET_GIL
|
|
return PyErr_Format(PyExc_ValueError, "unable to send headers before offload transfer");
|
|
}
|
|
UWSGI_GET_GIL
|
|
}
|
|
|
|
|
|
UWSGI_RELEASE_GIL
|
|
if (uwsgi_offload_request_sendfile_do(wsgi_req, filename, -1, len)) {
|
|
UWSGI_GET_GIL
|
|
return PyErr_Format(PyExc_ValueError, "unable to offload the request");
|
|
}
|
|
UWSGI_GET_GIL
|
|
|
|
return PyString_FromString("");
|
|
}
|
|
|
|
PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
|
|
|
PyObject *what;
|
|
char *filename;
|
|
size_t chunk = 0;
|
|
off_t pos = 0;
|
|
size_t filesize = 0;
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
int fd = -1;
|
|
|
|
if (!PyArg_ParseTuple(args, "O|iii:sendfile", &what, &chunk, &pos, &filesize)) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if (PyString_Check(what)) {
|
|
|
|
filename = PyString_AsString(what);
|
|
|
|
fd = open(filename, O_RDONLY);
|
|
if (fd < 0) {
|
|
uwsgi_error_open(filename);
|
|
goto clear;
|
|
}
|
|
|
|
}
|
|
#ifdef PYTHREE
|
|
else if (PyUnicode_Check(what)) {
|
|
filename = PyBytes_AsString(PyUnicode_AsASCIIString(what));
|
|
|
|
fd = open(filename, O_RDONLY);
|
|
if (fd < 0) {
|
|
uwsgi_error_open(filename);
|
|
goto clear;
|
|
}
|
|
}
|
|
#endif
|
|
else {
|
|
fd = PyObject_AsFileDescriptor(what);
|
|
if (fd < 0)
|
|
goto clear;
|
|
|
|
// check for mixing file_wrapper and sendfile
|
|
if (fd == wsgi_req->sendfile_fd) {
|
|
Py_INCREF(what);
|
|
}
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
// fd is closed by the following function
|
|
uwsgi_response_sendfile_do(wsgi_req, fd, pos, filesize);
|
|
UWSGI_GET_GIL
|
|
// revert to old values
|
|
uwsgi_py_check_write_errors {
|
|
uwsgi_py_write_exception(wsgi_req);
|
|
return NULL;
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_async_sleep(PyObject * self, PyObject * args) {
|
|
|
|
float timeout;
|
|
int sec_timeout;
|
|
|
|
if (!PyArg_ParseTuple(args, "f:async_sleep", &timeout)) {
|
|
return NULL;
|
|
}
|
|
|
|
sec_timeout = (int) timeout;
|
|
|
|
if (sec_timeout > 0) {
|
|
async_add_timeout(uwsgi.wsgi_req, sec_timeout);
|
|
}
|
|
|
|
return PyString_FromString("");
|
|
}
|
|
|
|
PyObject *py_uwsgi_warning(PyObject * self, PyObject * args) {
|
|
char *message;
|
|
int len;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:set_warning_message", &message)) {
|
|
return NULL;
|
|
}
|
|
|
|
len = strlen(message);
|
|
if (len > 80) {
|
|
uwsgi_log("- warning message must be max 80 chars, it will be truncated -");
|
|
memcpy(uwsgi.shared->warning_message, message, 80);
|
|
uwsgi.shared->warning_message[80] = 0;
|
|
}
|
|
else {
|
|
memcpy(uwsgi.shared->warning_message, message, len);
|
|
uwsgi.shared->warning_message[len] = 0;
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
PyObject *py_uwsgi_log(PyObject * self, PyObject * args) {
|
|
char *logline;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:log", &logline)) {
|
|
return NULL;
|
|
}
|
|
|
|
uwsgi_log("%s\n", logline);
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
PyObject *py_uwsgi_set_user_harakiri(PyObject * self, PyObject * args) {
|
|
int sec = 0;
|
|
if (!PyArg_ParseTuple(args, "i:set_user_harakiri", &sec)) {
|
|
return NULL;
|
|
}
|
|
|
|
set_user_harakiri(sec);
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) {
|
|
if (uwsgi.i_am_a_spooler) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_is_locked(PyObject * self, PyObject * args) {
|
|
|
|
int lock_num = 0;
|
|
|
|
// the spooler cannot lock resources
|
|
if (uwsgi.i_am_a_spooler) {
|
|
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "|i:is_locked", &lock_num)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
|
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
if (uwsgi_lock_check(uwsgi.user_lock[lock_num]) == 0) {
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_False);
|
|
return Py_False;
|
|
}
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
|
|
|
|
int lock_num = 0;
|
|
|
|
// the spooler cannot lock resources
|
|
if (uwsgi.i_am_a_spooler) {
|
|
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "|i:lock", &lock_num)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
|
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_lock(uwsgi.user_lock[lock_num]);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
|
|
|
|
int lock_num = 0;
|
|
|
|
if (uwsgi.i_am_a_spooler) {
|
|
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "|i:unlock", &lock_num)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
|
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
|
|
}
|
|
|
|
uwsgi_unlock(uwsgi.user_lock[lock_num]);
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_connection_fd(PyObject * self, PyObject * args) {
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
return PyInt_FromLong(wsgi_req->fd);
|
|
}
|
|
|
|
PyObject *py_uwsgi_websocket_handshake(PyObject * self, PyObject * args) {
|
|
char *key = NULL;
|
|
Py_ssize_t key_len = 0;
|
|
|
|
char *origin = NULL;
|
|
Py_ssize_t origin_len = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#|s#:websocket_handshake", &key, &key_len, &origin, &origin_len)) {
|
|
return NULL;
|
|
}
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
UWSGI_RELEASE_GIL
|
|
int ret = uwsgi_websocket_handshake(wsgi_req, key, key_len, origin, origin_len);
|
|
UWSGI_GET_GIL
|
|
|
|
if (ret) {
|
|
return PyErr_Format(PyExc_IOError, "unable to complete websocket handshake");
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_websocket_send(PyObject * self, PyObject * args) {
|
|
char *message = NULL;
|
|
Py_ssize_t message_len = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#:websocket_send", &message, &message_len)) {
|
|
return NULL;
|
|
}
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
UWSGI_RELEASE_GIL
|
|
int ret = uwsgi_websocket_send(wsgi_req, message, message_len);
|
|
UWSGI_GET_GIL
|
|
if (ret < 0) {
|
|
return PyErr_Format(PyExc_IOError, "unable to send websocket message");
|
|
}
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_websocket_recv(PyObject * self, PyObject * args) {
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
UWSGI_RELEASE_GIL
|
|
struct uwsgi_buffer *ub = uwsgi_websocket_recv(wsgi_req);
|
|
UWSGI_GET_GIL
|
|
if (!ub) {
|
|
return PyErr_Format(PyExc_IOError, "unable to receive websocket message");
|
|
}
|
|
|
|
PyObject *ret = PyString_FromStringAndSize(ub->buf, ub->pos);
|
|
uwsgi_buffer_destroy(ub);
|
|
return ret;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
|
|
|
|
char *name;
|
|
char *symbol;
|
|
void *sym_ptr_start = NULL;
|
|
void *sym_ptr_end = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:embedded_data", &name)) {
|
|
return NULL;
|
|
}
|
|
|
|
symbol = uwsgi_concat3("_binary_", name, "_start");
|
|
sym_ptr_start = dlsym(RTLD_DEFAULT, symbol);
|
|
free(symbol);
|
|
if (!sym_ptr_start)
|
|
return PyErr_Format(PyExc_ValueError, "unable to find symbol %s", name);
|
|
|
|
|
|
|
|
symbol = uwsgi_concat3("_binary_", name, "_end");
|
|
sym_ptr_end = dlsym(RTLD_DEFAULT, symbol);
|
|
free(symbol);
|
|
if (!sym_ptr_end)
|
|
return PyErr_Format(PyExc_ValueError, "unable to find symbol %s", name);
|
|
|
|
return PyString_FromStringAndSize(sym_ptr_start, sym_ptr_end - sym_ptr_start);
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_setprocname(PyObject * self, PyObject * args) {
|
|
char *name = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:setprocname", &name)) {
|
|
return NULL;
|
|
}
|
|
|
|
uwsgi_set_processname(name);
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_ready(PyObject * self, PyObject * args) {
|
|
|
|
if (ushared->ready) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_in_farm(PyObject * self, PyObject * args) {
|
|
|
|
char *farm_name = NULL;
|
|
int i;
|
|
|
|
if (!PyArg_ParseTuple(args, "|s:in_farm", &farm_name)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi.muleid == 0) goto none;
|
|
|
|
for(i=0;i<uwsgi.farms_cnt;i++) {
|
|
if (!farm_name) {
|
|
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
}
|
|
else {
|
|
if (!strcmp(farm_name, uwsgi.farms[i].name)) {
|
|
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
none:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_farm_msg(PyObject * self, PyObject * args) {
|
|
|
|
char *message = NULL;
|
|
Py_ssize_t message_len = 0;
|
|
char *farm_name = NULL;
|
|
ssize_t len;
|
|
int i;
|
|
|
|
if (!PyArg_ParseTuple(args, "ss#:farm_msg", &farm_name, &message, &message_len)) {
|
|
return NULL;
|
|
}
|
|
|
|
for(i=0;i<uwsgi.farms_cnt;i++) {
|
|
|
|
if (!strcmp(farm_name, uwsgi.farms[i].name)) {
|
|
UWSGI_RELEASE_GIL
|
|
len = write(uwsgi.farms[i].queue_pipe[0], message, message_len);
|
|
UWSGI_GET_GIL
|
|
if (len <= 0) {
|
|
uwsgi_error("write()");
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_mule_msg(PyObject * self, PyObject * args) {
|
|
|
|
char *message = NULL;
|
|
Py_ssize_t message_len = 0;
|
|
PyObject *mule_obj = NULL;
|
|
int fd = -1;
|
|
int mule_id = -1;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#|O:mule_msg", &message, &message_len, &mule_obj)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi.mules_cnt < 1)
|
|
return PyErr_Format(PyExc_ValueError, "no mule configured");
|
|
|
|
if (mule_obj == NULL) {
|
|
UWSGI_RELEASE_GIL
|
|
mule_send_msg(uwsgi.shared->mule_queue_pipe[0], message, message_len);
|
|
UWSGI_GET_GIL
|
|
}
|
|
else {
|
|
if (PyString_Check(mule_obj)) {
|
|
struct uwsgi_farm *uf = get_farm_by_name(PyString_AsString(mule_obj));
|
|
if (uf == NULL) {
|
|
return PyErr_Format(PyExc_ValueError, "unknown farm");
|
|
}
|
|
fd = uf->queue_pipe[0];
|
|
}
|
|
else if (PyInt_Check(mule_obj)) {
|
|
mule_id = PyInt_AsLong(mule_obj);
|
|
if (mule_id < 0 && mule_id > uwsgi.mules_cnt) {
|
|
return PyErr_Format(PyExc_ValueError, "invalid mule number");
|
|
}
|
|
if (mule_id == 0) {
|
|
fd = uwsgi.shared->mule_queue_pipe[0];
|
|
}
|
|
else {
|
|
fd = uwsgi.mules[mule_id-1].queue_pipe[0];
|
|
}
|
|
}
|
|
else {
|
|
return PyErr_Format(PyExc_ValueError, "invalid mule");
|
|
}
|
|
|
|
if (fd > -1) {
|
|
UWSGI_RELEASE_GIL
|
|
mule_send_msg(fd, message, message_len);
|
|
UWSGI_GET_GIL
|
|
}
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_mule_get_msg(PyObject * self, PyObject * args, PyObject *kwargs) {
|
|
|
|
ssize_t len = 0;
|
|
// this buffer is configurable (default 64k)
|
|
char *message;
|
|
PyObject *py_manage_signals = NULL;
|
|
PyObject *py_manage_farms = NULL;
|
|
size_t buffer_size = 65536;
|
|
int timeout = -1;
|
|
int manage_signals = 1, manage_farms = 1;
|
|
|
|
static char *kwlist[] = {"signals", "buffer_size", "timeout", "farms", NULL};
|
|
|
|
if (uwsgi.muleid == 0) {
|
|
return PyErr_Format(PyExc_ValueError, "you can receive mule messages only in a mule !!!");
|
|
}
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii:mule_get_msg", kwlist, &py_manage_signals, &py_manage_farms, &buffer_size, &timeout)) {
|
|
return NULL;
|
|
}
|
|
|
|
// signals and farms are managed by default
|
|
if (py_manage_signals == Py_None || py_manage_signals == Py_False) {
|
|
manage_signals = 0;
|
|
}
|
|
|
|
if (py_manage_farms == Py_None || py_manage_farms == Py_False) {
|
|
manage_farms = 0;
|
|
}
|
|
|
|
message = uwsgi_malloc(buffer_size);
|
|
|
|
UWSGI_RELEASE_GIL;
|
|
len = uwsgi_mule_get_msg(manage_signals, manage_farms, message, buffer_size, timeout) ;
|
|
UWSGI_GET_GIL;
|
|
|
|
if (len < 0) {
|
|
free(message);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *msg = PyString_FromStringAndSize(message, len);
|
|
free(message);
|
|
return msg;
|
|
}
|
|
|
|
PyObject *py_uwsgi_farm_get_msg(PyObject * self, PyObject * args) {
|
|
|
|
ssize_t len = 0;
|
|
// this buffer will be configurable
|
|
char message[65536];
|
|
int i, count = 0, pos = 0, ret;
|
|
struct pollfd *farmpoll;
|
|
|
|
if (uwsgi.muleid == 0) {
|
|
return PyErr_Format(PyExc_ValueError, "you can receive farm messages only in a mule !!!");
|
|
}
|
|
UWSGI_RELEASE_GIL;
|
|
for(i=0;i<uwsgi.farms_cnt;i++) {
|
|
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) count++;
|
|
}
|
|
farmpoll = uwsgi_malloc( sizeof(struct pollfd) * count);
|
|
for(i=0;i<uwsgi.farms_cnt;i++) {
|
|
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
|
|
farmpoll[pos].fd = uwsgi.farms[i].queue_pipe[1];
|
|
farmpoll[pos].events = POLLIN;
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
ret = poll(farmpoll, count, -1);
|
|
if (ret <= 0) {
|
|
uwsgi_error("poll()");
|
|
free(farmpoll);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
for(i=0;i<count;i++) {
|
|
if (farmpoll[i].revents & POLLIN) {
|
|
len = read(farmpoll[i].fd, message, 65536);
|
|
break;
|
|
}
|
|
}
|
|
UWSGI_GET_GIL;
|
|
if (len <= 0) {
|
|
uwsgi_error("read()");
|
|
free(farmpoll);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
free(farmpoll);
|
|
return PyString_FromStringAndSize(message, len);
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_extract(PyObject * self, PyObject * args) {
|
|
|
|
char *name;
|
|
size_t len;
|
|
char *buf;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:extract", &name)) {
|
|
return NULL;
|
|
}
|
|
|
|
buf = uwsgi_open_and_read(name, &len, 0, NULL);
|
|
if (buf && len > 0) {
|
|
return PyString_FromStringAndSize(buf, len);
|
|
}
|
|
if (buf)
|
|
free(buf);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_sharedarea_inclong(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
uint64_t value = 1;
|
|
uint64_t current_value = 0;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "l|l:sharedarea_inclong", &pos, &value)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
memcpy(¤t_value, uwsgi.sharedarea + pos, 8);
|
|
value = current_value + value;
|
|
memcpy(uwsgi.sharedarea + pos, &value, 8);
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
return PyInt_FromLong(value);
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_sharedarea_writelong(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
uint64_t value = 0;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "ll:sharedarea_writelong", &pos, &value)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
memcpy(uwsgi.sharedarea + pos, &value, 8);
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
return PyInt_FromLong(value);
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_sharedarea_write(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
char *value;
|
|
Py_ssize_t value_len = 0;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "ls#:sharedarea_write", &pos, &value, &value_len)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos + value_len >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
memcpy(uwsgi.sharedarea + pos, value, value_len);
|
|
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
return PyInt_FromLong(value_len);
|
|
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_sharedarea_writebyte(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
char value;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "lb:sharedarea_writebyte", &pos, &value)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
uwsgi.sharedarea[pos] = value;
|
|
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
return PyInt_FromLong(value);
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_sharedarea_readlong(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
uint64_t value;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "l:sharedarea_readlong", &pos)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
memcpy(&value, uwsgi.sharedarea + pos, 8);
|
|
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
return PyLong_FromLong(value);
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_sharedarea_readbyte(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "l:sharedarea_readbyte", &pos)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
char value = uwsgi.sharedarea[pos];
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
return PyInt_FromLong(value);
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) {
|
|
uint64_t pos = 0;
|
|
uint64_t len = 1;
|
|
|
|
if (uwsgi.sharedareasize <= 0) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
if (!PyArg_ParseTuple(args, "l|l:sharedarea_read", &pos, &len)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (pos + len >= uwsgi.page_size * uwsgi.sharedareasize) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *ret = PyString_FromStringAndSize(NULL, len);
|
|
#ifdef PYTHREE
|
|
char *storage = PyBytes_AsString(ret);
|
|
#else
|
|
char *storage = PyString_AS_STRING(ret);
|
|
#endif
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
uwsgi_wlock(uwsgi.sa_lock);
|
|
|
|
memcpy(storage, uwsgi.sharedarea + pos, len);
|
|
|
|
uwsgi_rwunlock(uwsgi.sa_lock);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
return ret;
|
|
}
|
|
|
|
PyObject *py_uwsgi_spooler_freq(PyObject * self, PyObject * args) {
|
|
|
|
if (!PyArg_ParseTuple(args, "i", &uwsgi.shared->spooler_frequency)) {
|
|
return NULL;
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_spooler_jobs(PyObject * self, PyObject * args) {
|
|
|
|
DIR *sdir;
|
|
struct dirent *dp;
|
|
char *abs_path;
|
|
struct stat sf_lstat;
|
|
|
|
PyObject *jobslist = PyList_New(0);
|
|
|
|
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
|
|
|
sdir = opendir(uspool->dir);
|
|
|
|
if (sdir) {
|
|
while ((dp = readdir(sdir)) != NULL) {
|
|
if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) {
|
|
abs_path = malloc(strlen(uspool->dir) + 1 + strlen(dp->d_name) + 1);
|
|
if (!abs_path) {
|
|
uwsgi_error("malloc()");
|
|
closedir(sdir);
|
|
goto clear;
|
|
}
|
|
|
|
memset(abs_path, 0, strlen(uspool->dir) + 1 + strlen(dp->d_name) + 1);
|
|
|
|
memcpy(abs_path, uspool->dir, strlen(uspool->dir));
|
|
memcpy(abs_path + strlen(uspool->dir), "/", 1);
|
|
memcpy(abs_path + strlen(uspool->dir) + 1, dp->d_name, strlen(dp->d_name));
|
|
|
|
|
|
if (lstat(abs_path, &sf_lstat)) {
|
|
free(abs_path);
|
|
continue;
|
|
}
|
|
if (!S_ISREG(sf_lstat.st_mode)) {
|
|
free(abs_path);
|
|
continue;
|
|
}
|
|
if (!access(abs_path, R_OK | W_OK)) {
|
|
if (PyList_Append(jobslist, PyString_FromString(abs_path))) {
|
|
PyErr_Print();
|
|
}
|
|
}
|
|
free(abs_path);
|
|
}
|
|
}
|
|
closedir(sdir);
|
|
}
|
|
|
|
clear:
|
|
return jobslist;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
|
|
PyObject *spool_dict, *spool_vars;
|
|
PyObject *zero, *key, *val;
|
|
uint16_t keysize, valsize;
|
|
char *cur_buf;
|
|
int i;
|
|
char spool_filename[1024];
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
char *priority = NULL;
|
|
long numprio = 0;
|
|
time_t at = 0;
|
|
char *body = NULL;
|
|
size_t body_len= 0;
|
|
|
|
// this is a counter for non-request-related tasks (like threads or greenlet)
|
|
static int internal_counter = 0xffff;
|
|
|
|
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
|
|
|
spool_dict = PyTuple_GetItem(args, 0);
|
|
|
|
if (spool_dict) {
|
|
|
|
if (!PyDict_Check(spool_dict)) {
|
|
return PyErr_Format(PyExc_ValueError, "The argument of spooler callable must be a dictionary");
|
|
}
|
|
}
|
|
else {
|
|
// clear the error
|
|
PyErr_Clear();
|
|
spool_dict = kw;
|
|
}
|
|
|
|
|
|
if (!spool_dict) {
|
|
return PyErr_Format(PyExc_ValueError, "The argument of spooler callable must be a dictionary");
|
|
}
|
|
|
|
// TODO if "spooler" is a num, get the spooler by id, otherwise get it by directory
|
|
PyObject *py_spooler = uwsgi_py_dict_get(spool_dict, "spooler");
|
|
if (py_spooler) {
|
|
if (PyString_Check(py_spooler)) {
|
|
uspool = uwsgi_get_spooler_by_name(PyString_AsString(py_spooler));
|
|
if (!uspool) {
|
|
return PyErr_Format(PyExc_ValueError, "Unknown spooler requested");
|
|
}
|
|
}
|
|
}
|
|
|
|
PyObject *pyprio = uwsgi_py_dict_get(spool_dict, "priority");
|
|
if (pyprio) {
|
|
if (PyInt_Check(pyprio)) {
|
|
numprio = PyInt_AsLong(pyprio);
|
|
uwsgi_py_dict_del(spool_dict, "priority");
|
|
}
|
|
}
|
|
|
|
PyObject *pyat = uwsgi_py_dict_get(spool_dict, "at");
|
|
if (pyat) {
|
|
if (PyInt_Check(pyat)) {
|
|
at = (time_t) PyInt_AsLong(pyat);
|
|
uwsgi_py_dict_del(spool_dict, "at");
|
|
}
|
|
else if (PyLong_Check(pyat)) {
|
|
at = (time_t) PyLong_AsLong(pyat);
|
|
uwsgi_py_dict_del(spool_dict, "at");
|
|
}
|
|
else if (PyFloat_Check(pyat)) {
|
|
at = (time_t) PyFloat_AsDouble(pyat);
|
|
uwsgi_py_dict_del(spool_dict, "at");
|
|
}
|
|
}
|
|
|
|
PyObject *pybody = uwsgi_py_dict_get(spool_dict, "body");
|
|
if (pybody) {
|
|
if (PyString_Check(pybody)) {
|
|
body = PyString_AsString(pybody);
|
|
body_len = PyString_Size(pybody);
|
|
uwsgi_py_dict_del(spool_dict, "body");
|
|
}
|
|
}
|
|
|
|
spool_vars = PyDict_Items(spool_dict);
|
|
if (!spool_vars) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
char *spool_buffer = uwsgi_malloc(UMAX16);
|
|
|
|
cur_buf = spool_buffer;
|
|
|
|
for (i = 0; i < PyList_Size(spool_vars); i++) {
|
|
zero = PyList_GetItem(spool_vars, i);
|
|
if (zero) {
|
|
if (PyTuple_Check(zero)) {
|
|
key = PyTuple_GetItem(zero, 0);
|
|
val = PyTuple_GetItem(zero, 1);
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("ob_type %s %s\n", key->ob_type->tp_name, val->ob_type->tp_name);
|
|
#endif
|
|
|
|
if (PyString_Check(key) && PyString_Check(val)) {
|
|
|
|
|
|
keysize = PyString_Size(key);
|
|
valsize = PyString_Size(val);
|
|
if (cur_buf + keysize + 2 + valsize + 2 <= spool_buffer + UMAX16) {
|
|
|
|
*cur_buf++ = (uint8_t) (keysize & 0xff);
|
|
*cur_buf++ = (uint8_t) ((keysize >> 8) & 0xff);
|
|
|
|
memcpy(cur_buf, PyString_AsString(key), keysize);
|
|
cur_buf += keysize;
|
|
|
|
*cur_buf++ = (uint8_t) (valsize & 0xff);
|
|
*cur_buf++ = (uint8_t) ((valsize >> 8) & 0xff);
|
|
|
|
memcpy(cur_buf, PyString_AsString(val), valsize);
|
|
cur_buf += valsize;
|
|
}
|
|
else {
|
|
Py_DECREF(zero);
|
|
free(spool_buffer);
|
|
return PyErr_Format(PyExc_ValueError, "spooler packet cannot be more than %d bytes", UMAX16);
|
|
}
|
|
}
|
|
else {
|
|
Py_DECREF(zero);
|
|
free(spool_buffer);
|
|
return PyErr_Format(PyExc_ValueError, "spooler callable dictionary must contains only strings");
|
|
}
|
|
}
|
|
else {
|
|
free(spool_buffer);
|
|
Py_DECREF(zero);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
}
|
|
else {
|
|
free(spool_buffer);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
}
|
|
|
|
|
|
if (numprio) {
|
|
priority = uwsgi_num2str(numprio);
|
|
}
|
|
|
|
int async_id;
|
|
|
|
if (wsgi_req) {
|
|
async_id = wsgi_req->async_id;
|
|
}
|
|
else {
|
|
// the GIL is protecting this counter...
|
|
async_id = internal_counter;
|
|
internal_counter++;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
i = spool_request(uspool, spool_filename, uwsgi.workers[0].requests + 1, async_id, spool_buffer, cur_buf - spool_buffer, priority, at, body, body_len);
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
if (priority) {
|
|
free(priority);
|
|
}
|
|
|
|
free(spool_buffer);
|
|
|
|
|
|
Py_DECREF(spool_vars);
|
|
|
|
if (i > 0) {
|
|
char *slash = uwsgi_get_last_char(spool_filename, '/');
|
|
if (slash) {
|
|
return PyString_FromString(slash+1);
|
|
}
|
|
return PyString_FromString(spool_filename);
|
|
}
|
|
return PyErr_Format(PyExc_ValueError, "unable to spool job");
|
|
}
|
|
|
|
PyObject *py_uwsgi_spooler_pid(PyObject * self, PyObject * args) {
|
|
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
|
if (!uwsgi.spoolers) return PyInt_FromLong(0);
|
|
return PyInt_FromLong(uspool->pid);
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_get_option(PyObject * self, PyObject * args) {
|
|
int opt_id;
|
|
|
|
if (!PyArg_ParseTuple(args, "i:get_option", &opt_id)) {
|
|
return NULL;
|
|
}
|
|
|
|
return PyInt_FromLong(uwsgi.shared->options[(uint8_t) opt_id]);
|
|
}
|
|
|
|
PyObject *py_uwsgi_set_option(PyObject * self, PyObject * args) {
|
|
int opt_id;
|
|
int value;
|
|
|
|
if (!PyArg_ParseTuple(args, "ii:set_option", &opt_id, &value)) {
|
|
return NULL;
|
|
}
|
|
|
|
uwsgi.shared->options[(uint8_t) opt_id] = (uint32_t) value;
|
|
return PyInt_FromLong(value);
|
|
}
|
|
|
|
PyObject *py_uwsgi_has_hook(PyObject * self, PyObject * args) {
|
|
int modifier1;
|
|
|
|
if (!PyArg_ParseTuple(args, "i:has_hook", &modifier1)) {
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
if (uwsgi.shared->hooks[modifier1] != unconfigured_hook) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
*/
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_connect(PyObject * self, PyObject * args) {
|
|
|
|
char *socket_name = NULL;
|
|
int timeout = 0;
|
|
if (!PyArg_ParseTuple(args, "s|i:connect", &socket_name, &timeout)) {
|
|
return NULL;
|
|
}
|
|
|
|
return PyInt_FromLong(uwsgi_connect(socket_name, timeout, 0));
|
|
}
|
|
|
|
PyObject *py_uwsgi_async_connect(PyObject * self, PyObject * args) {
|
|
|
|
char *socket_name = NULL;
|
|
if (!PyArg_ParseTuple(args, "s:async_connect", &socket_name)) {
|
|
return NULL;
|
|
}
|
|
|
|
return PyInt_FromLong(uwsgi_connect(socket_name, 0, 1));
|
|
}
|
|
|
|
PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
|
|
|
|
PyObject *pyobj = NULL;
|
|
|
|
int uwsgi_fd;
|
|
int modifier1 = 0;
|
|
int modifier2 = 0;
|
|
|
|
char *encoded;
|
|
uint16_t esize = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "iiiO:async_send_message", &uwsgi_fd, &modifier1, &modifier2, &pyobj)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi_fd < 0)
|
|
goto clear;
|
|
|
|
// now check for the type of object to send (fallback to marshal)
|
|
if (PyDict_Check(pyobj)) {
|
|
encoded = uwsgi_encode_pydict(pyobj, &esize);
|
|
if (esize > 0) {
|
|
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
|
|
free(encoded);
|
|
}
|
|
}
|
|
else if (PyString_Check(pyobj)) {
|
|
encoded = PyString_AsString(pyobj);
|
|
esize = PyString_Size(pyobj);
|
|
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
|
|
}
|
|
#ifndef UWSGI_PYPY
|
|
else {
|
|
PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
|
|
if (!marshalled) {
|
|
PyErr_Print();
|
|
goto clear;
|
|
}
|
|
|
|
encoded = PyString_AsString(marshalled);
|
|
esize = PyString_Size(marshalled);
|
|
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
|
|
}
|
|
#endif
|
|
|
|
UWSGI_GET_GIL clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
/* uWSGI masterpid */
|
|
PyObject *py_uwsgi_masterpid(PyObject * self, PyObject * args) {
|
|
if (uwsgi.master_process) {
|
|
return PyInt_FromLong(uwsgi.workers[0].pid);
|
|
}
|
|
return PyInt_FromLong(0);
|
|
}
|
|
|
|
/* uWSGI total_requests */
|
|
PyObject *py_uwsgi_total_requests(PyObject * self, PyObject * args) {
|
|
return PyLong_FromUnsignedLongLong(uwsgi.workers[0].requests);
|
|
}
|
|
|
|
/* uWSGI workers */
|
|
PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
|
|
|
|
PyObject *worker_dict, *apps_dict, *apps_tuple, *zero;
|
|
int i, j;
|
|
struct uwsgi_app *ua;
|
|
|
|
for (i = 0; i < uwsgi.numproc; i++) {
|
|
worker_dict = PyTuple_GetItem(up.workers_tuple, i);
|
|
if (!worker_dict) {
|
|
goto clear;
|
|
}
|
|
|
|
apps_tuple = PyDict_GetItemString(worker_dict, "apps");
|
|
if (apps_tuple) {
|
|
Py_DECREF(apps_tuple);
|
|
}
|
|
|
|
PyDict_Clear(worker_dict);
|
|
|
|
zero = PyInt_FromLong(uwsgi.workers[i + 1].id);
|
|
if (PyDict_SetItemString(worker_dict, "id", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
|
|
zero = PyInt_FromLong(uwsgi.workers[i + 1].pid);
|
|
if (PyDict_SetItemString(worker_dict, "pid", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].requests);
|
|
if (PyDict_SetItemString(worker_dict, "requests", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].delta_requests);
|
|
if (PyDict_SetItemString(worker_dict, "delta_requests", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].signals);
|
|
if (PyDict_SetItemString(worker_dict, "signals", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].exceptions);
|
|
if (PyDict_SetItemString(worker_dict, "exceptions", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
if (uwsgi.workers[i + 1].cheaped) {
|
|
zero = PyString_FromString("cheap");
|
|
}
|
|
else if (uwsgi.workers[i + 1].suspended && !uwsgi.workers[i + 1].busy) {
|
|
zero = PyString_FromString("pause");
|
|
}
|
|
else {
|
|
if (uwsgi.workers[i + 1].sig) {
|
|
zero = PyString_FromFormat("sig%d",uwsgi.workers[i + 1].signum);
|
|
}
|
|
else if (uwsgi.workers[i + 1].busy) {
|
|
zero = PyString_FromString("busy");
|
|
}
|
|
else {
|
|
zero = PyString_FromString("idle");
|
|
}
|
|
}
|
|
if (PyDict_SetItemString(worker_dict, "status", zero)) {
|
|
goto clear;
|
|
}
|
|
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].rss_size);
|
|
if (PyDict_SetItemString(worker_dict, "rss", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].vsz_size);
|
|
if (PyDict_SetItemString(worker_dict, "vsz", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].running_time);
|
|
if (PyDict_SetItemString(worker_dict, "running_time", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromLong(uwsgi.workers[i + 1].last_spawn);
|
|
if (PyDict_SetItemString(worker_dict, "last_spawn", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].respawn_count-1);
|
|
if (PyDict_SetItemString(worker_dict, "respawn_count", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].tx);
|
|
if (PyDict_SetItemString(worker_dict, "tx", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].avg_response_time);
|
|
if (PyDict_SetItemString(worker_dict, "avg_rt", zero)) {
|
|
goto clear;
|
|
}
|
|
Py_DECREF(zero);
|
|
|
|
apps_tuple = PyTuple_New(uwsgi.workers[i+1].apps_cnt);
|
|
|
|
for(j=0;j<uwsgi.workers[i+1].apps_cnt;j++) {
|
|
apps_dict = PyDict_New();
|
|
ua = &uwsgi.workers[i+1].apps[j];
|
|
|
|
zero = PyInt_FromLong(j);
|
|
PyDict_SetItemString(apps_dict, "id", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyInt_FromLong(ua->modifier1);
|
|
PyDict_SetItemString(apps_dict, "modifier1", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyString_FromStringAndSize(ua->mountpoint, ua->mountpoint_len);
|
|
PyDict_SetItemString(apps_dict, "mountpoint", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyInt_FromLong((long) ua->startup_time);
|
|
PyDict_SetItemString(apps_dict, "startup_time", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyInt_FromLong((long)ua->interpreter);
|
|
PyDict_SetItemString(apps_dict, "interpreter", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyInt_FromLong((long)ua->callable);
|
|
PyDict_SetItemString(apps_dict, "callable", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(ua->requests);
|
|
PyDict_SetItemString(apps_dict, "requests", zero);
|
|
Py_DECREF(zero);
|
|
|
|
zero = PyLong_FromUnsignedLongLong(ua->exceptions);
|
|
PyDict_SetItemString(apps_dict, "exceptions", zero);
|
|
Py_DECREF(zero);
|
|
|
|
if (ua->chdir) {
|
|
zero = PyString_FromString(ua->chdir);
|
|
}
|
|
else {
|
|
zero = PyString_FromString("");
|
|
}
|
|
PyDict_SetItemString(apps_dict, "chdir", zero);
|
|
Py_DECREF(zero);
|
|
|
|
PyTuple_SetItem(apps_tuple, j, apps_dict);
|
|
}
|
|
|
|
|
|
PyDict_SetItemString(worker_dict, "apps", apps_tuple);
|
|
|
|
}
|
|
|
|
|
|
Py_INCREF(up.workers_tuple);
|
|
return up.workers_tuple;
|
|
|
|
clear:
|
|
PyErr_Print();
|
|
PyErr_Clear();
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
/* uWSGI reload */
|
|
PyObject *py_uwsgi_reload(PyObject * self, PyObject * args) {
|
|
|
|
if (kill(uwsgi.workers[0].pid, SIGHUP)) {
|
|
uwsgi_error("kill()");
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
/* uWSGI stop */
|
|
PyObject *py_uwsgi_stop(PyObject * self, PyObject * args) {
|
|
|
|
if (kill(uwsgi.workers[0].pid, SIGQUIT)) {
|
|
uwsgi_error("kill()");
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
|
|
/* blocking hint */
|
|
PyObject *py_uwsgi_set_blocking(PyObject * self, PyObject * args) {
|
|
|
|
if (uwsgi.master_process) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_request_id(PyObject * self, PyObject * args) {
|
|
return PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].requests);
|
|
}
|
|
|
|
PyObject *py_uwsgi_worker_id(PyObject * self, PyObject * args) {
|
|
return PyInt_FromLong(uwsgi.mywid);
|
|
}
|
|
|
|
PyObject *py_uwsgi_mule_id(PyObject * self, PyObject * args) {
|
|
return PyInt_FromLong(uwsgi.muleid);
|
|
}
|
|
|
|
PyObject *py_uwsgi_logsize(PyObject * self, PyObject * args) {
|
|
return PyLong_FromUnsignedLongLong(uwsgi.shared->logsize);
|
|
}
|
|
|
|
PyObject *py_uwsgi_mem(PyObject * self, PyObject * args) {
|
|
|
|
uint64_t rss=0, vsz = 0;
|
|
PyObject *ml = PyTuple_New(2);
|
|
|
|
get_memusage(&rss, &vsz);
|
|
|
|
PyTuple_SetItem(ml, 0, PyLong_FromUnsignedLongLong(rss));
|
|
PyTuple_SetItem(ml, 1, PyLong_FromUnsignedLongLong(vsz));
|
|
|
|
return ml;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_cl(PyObject * self, PyObject * args) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
return PyLong_FromUnsignedLongLong(wsgi_req->post_cl);
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_disconnect(PyObject * self, PyObject * args) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("disconnecting worker %d (pid :%d) from session...\n", uwsgi.mywid, uwsgi.mypid);
|
|
#endif
|
|
|
|
if (wsgi_req->socket) {
|
|
wsgi_req->socket->proto_close(wsgi_req);
|
|
}
|
|
wsgi_req->fd_closed = 1;
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
PyObject *py_uwsgi_parse_file(PyObject * self, PyObject * args) {
|
|
|
|
char *filename;
|
|
int fd;
|
|
ssize_t len;
|
|
char *buffer, *ptrbuf, *bufferend, *keybuf;
|
|
uint16_t strsize = 0, keysize = 0;
|
|
|
|
struct uwsgi_header uh;
|
|
PyObject *zero;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:parsefile", &filename)) {
|
|
return NULL;
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
|
|
fd = open(filename, O_RDONLY);
|
|
if (fd < 0) {
|
|
uwsgi_error_open(filename);
|
|
UWSGI_GET_GIL
|
|
goto clear;
|
|
}
|
|
|
|
len = read(fd, &uh, 4);
|
|
if (len != 4) {
|
|
uwsgi_error("read()");
|
|
UWSGI_GET_GIL
|
|
goto clear2;
|
|
}
|
|
|
|
buffer = malloc(uh.pktsize);
|
|
if (!buffer) {
|
|
uwsgi_error("malloc()");
|
|
UWSGI_GET_GIL
|
|
goto clear2;
|
|
}
|
|
len = read(fd, buffer, uh.pktsize);
|
|
if (len != uh.pktsize) {
|
|
uwsgi_error("read()");
|
|
free(buffer);
|
|
UWSGI_GET_GIL
|
|
goto clear2;
|
|
}
|
|
|
|
UWSGI_GET_GIL
|
|
|
|
ptrbuf = buffer;
|
|
bufferend = ptrbuf + uh.pktsize;
|
|
|
|
if (!uh.modifier1 || uh.modifier1 == UWSGI_MODIFIER_SPOOL_REQUEST) {
|
|
zero = PyDict_New();
|
|
|
|
while (ptrbuf < bufferend) {
|
|
if (ptrbuf + 2 < bufferend) {
|
|
memcpy(&strsize, ptrbuf, 2);
|
|
#ifdef __BIG_ENDIAN__
|
|
strsize = uwsgi_swap16(strsize);
|
|
#endif
|
|
/* key cannot be null */
|
|
if (!strsize) {
|
|
uwsgi_log("uwsgi key cannot be null.\n");
|
|
goto clear3;
|
|
}
|
|
|
|
ptrbuf += 2;
|
|
if (ptrbuf + strsize < bufferend) {
|
|
// var key
|
|
keybuf = ptrbuf;
|
|
keysize = strsize;
|
|
ptrbuf += strsize;
|
|
// value can be null (even at the end) so use <=
|
|
if (ptrbuf + 2 <= bufferend) {
|
|
memcpy(&strsize, ptrbuf, 2);
|
|
#ifdef __BIG_ENDIAN__
|
|
strsize = uwsgi_swap16(strsize);
|
|
#endif
|
|
ptrbuf += 2;
|
|
if (ptrbuf + strsize <= bufferend) {
|
|
PyDict_SetItem(zero, PyString_FromStringAndSize(keybuf, keysize), PyString_FromStringAndSize(ptrbuf, strsize));
|
|
ptrbuf += strsize;
|
|
}
|
|
else {
|
|
goto clear3;
|
|
}
|
|
}
|
|
else {
|
|
goto clear3;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
goto clear3;
|
|
}
|
|
}
|
|
|
|
close(fd);
|
|
free(buffer);
|
|
return zero;
|
|
|
|
}
|
|
|
|
free(buffer);
|
|
goto clear2;
|
|
|
|
clear3:
|
|
Py_DECREF(zero);
|
|
free(buffer);
|
|
clear2:
|
|
close(fd);
|
|
clear:
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
|
|
|
|
pid_t grunt_pid;
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
if (uwsgi.grunt) {
|
|
uwsgi_log("spawning a grunt from worker %d (pid :%d)...\n", uwsgi.mywid, uwsgi.mypid);
|
|
}
|
|
else {
|
|
uwsgi_log("grunt support is disabled !!!\n");
|
|
goto clear;
|
|
}
|
|
|
|
// use a normal fork here
|
|
grunt_pid = fork();
|
|
if (grunt_pid < 0) {
|
|
uwsgi_error("fork()");
|
|
goto clear;
|
|
}
|
|
// now i am a grunt, avoid it making mess
|
|
else if (grunt_pid == 0) {
|
|
// it will no more accepts requests
|
|
uwsgi_close_all_sockets();
|
|
// create a new session
|
|
setsid();
|
|
// exit on SIGPIPE
|
|
signal(SIGPIPE, (void *) &end_me);
|
|
// here we create a new worker. Each grunt will race on this datas, so do not rely on them
|
|
uwsgi.mywid = uwsgi.numproc + 1;
|
|
uwsgi.mypid = getpid();
|
|
memset(&uwsgi.workers[uwsgi.mywid], 0, sizeof(struct uwsgi_worker));
|
|
// this is pratically useless...
|
|
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
|
|
// this field will be overwrite after each call
|
|
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
|
|
|
|
// reset the random seed
|
|
uwsgi_python_reset_random_seed();
|
|
// TODO
|
|
// manage thread in grunt processes
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
|
|
// close connection on the original worker
|
|
if (PyTuple_Size(args) == 0) {
|
|
if (wsgi_req->socket) {
|
|
wsgi_req->socket->proto_close(wsgi_req);
|
|
}
|
|
wsgi_req->fd_closed = 1;
|
|
}
|
|
|
|
clear:
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
static PyMethodDef uwsgi_spooler_methods[] = {
|
|
#ifdef PYTHREE
|
|
{"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""},
|
|
{"spool", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""},
|
|
#else
|
|
{"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_KEYWORDS, ""},
|
|
{"spool", (PyCFunction) py_uwsgi_send_spool, METH_KEYWORDS, ""},
|
|
#endif
|
|
{"set_spooler_frequency", py_uwsgi_spooler_freq, METH_VARARGS, ""},
|
|
{"spooler_jobs", py_uwsgi_spooler_jobs, METH_VARARGS, ""},
|
|
{"spooler_pid", py_uwsgi_spooler_pid, METH_VARARGS, ""},
|
|
{NULL, NULL},
|
|
};
|
|
|
|
|
|
PyObject *py_uwsgi_suspend(PyObject * self, PyObject * args) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
if (uwsgi.schedule_to_main) uwsgi.schedule_to_main(wsgi_req);
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
static PyMethodDef uwsgi_advanced_methods[] = {
|
|
{"reload", py_uwsgi_reload, METH_VARARGS, ""},
|
|
{"stop", py_uwsgi_stop, METH_VARARGS, ""},
|
|
{"workers", py_uwsgi_workers, METH_VARARGS, ""},
|
|
{"masterpid", py_uwsgi_masterpid, METH_VARARGS, ""},
|
|
{"total_requests", py_uwsgi_total_requests, METH_VARARGS, ""},
|
|
{"getoption", py_uwsgi_get_option, METH_VARARGS, ""},
|
|
{"get_option", py_uwsgi_get_option, METH_VARARGS, ""},
|
|
{"setoption", py_uwsgi_set_option, METH_VARARGS, ""},
|
|
{"set_option", py_uwsgi_set_option, METH_VARARGS, ""},
|
|
{"sorry_i_need_to_block", py_uwsgi_set_blocking, METH_VARARGS, ""},
|
|
{"request_id", py_uwsgi_request_id, METH_VARARGS, ""},
|
|
{"worker_id", py_uwsgi_worker_id, METH_VARARGS, ""},
|
|
{"mule_id", py_uwsgi_mule_id, METH_VARARGS, ""},
|
|
{"log", py_uwsgi_log, METH_VARARGS, ""},
|
|
{"log_this_request", py_uwsgi_log_this, METH_VARARGS, ""},
|
|
{"set_logvar", py_uwsgi_set_logvar, METH_VARARGS, ""},
|
|
{"get_logvar", py_uwsgi_get_logvar, METH_VARARGS, ""},
|
|
{"disconnect", py_uwsgi_disconnect, METH_VARARGS, ""},
|
|
{"grunt", py_uwsgi_grunt, METH_VARARGS, ""},
|
|
{"lock", py_uwsgi_lock, METH_VARARGS, ""},
|
|
{"is_locked", py_uwsgi_is_locked, METH_VARARGS, ""},
|
|
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
|
|
{"cl", py_uwsgi_cl, METH_VARARGS, ""},
|
|
|
|
{"setprocname", py_uwsgi_setprocname, METH_VARARGS, ""},
|
|
|
|
{"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""},
|
|
|
|
{"register_signal", py_uwsgi_register_signal, METH_VARARGS, ""},
|
|
{"signal", py_uwsgi_signal, METH_VARARGS, ""},
|
|
{"signal_wait", py_uwsgi_signal_wait, METH_VARARGS, ""},
|
|
{"signal_registered", py_uwsgi_signal_registered, METH_VARARGS, ""},
|
|
{"signal_received", py_uwsgi_signal_received, METH_VARARGS, ""},
|
|
{"add_file_monitor", py_uwsgi_add_file_monitor, METH_VARARGS, ""},
|
|
{"add_timer", py_uwsgi_add_timer, METH_VARARGS, ""},
|
|
{"add_probe", py_uwsgi_add_probe, METH_VARARGS, ""},
|
|
{"add_rb_timer", py_uwsgi_add_rb_timer, METH_VARARGS, ""},
|
|
{"add_cron", py_uwsgi_add_cron, METH_VARARGS, ""},
|
|
|
|
{"register_rpc", py_uwsgi_register_rpc, METH_VARARGS, ""},
|
|
{"rpc", py_uwsgi_rpc, METH_VARARGS, ""},
|
|
{"rpc_list", py_uwsgi_rpc_list, METH_VARARGS, ""},
|
|
{"call", py_uwsgi_call, METH_VARARGS, ""},
|
|
{"sendfile", py_uwsgi_advanced_sendfile, METH_VARARGS, ""},
|
|
{"offload_transfer", py_uwsgi_offload_transfer, METH_VARARGS, ""},
|
|
{"set_warning_message", py_uwsgi_warning, METH_VARARGS, ""},
|
|
{"mem", py_uwsgi_mem, METH_VARARGS, ""},
|
|
{"has_hook", py_uwsgi_has_hook, METH_VARARGS, ""},
|
|
{"logsize", py_uwsgi_logsize, METH_VARARGS, ""},
|
|
#ifdef UWSGI_SSL
|
|
{"i_am_the_lord", py_uwsgi_i_am_the_lord, METH_VARARGS, ""},
|
|
#endif
|
|
{"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""},
|
|
{"async_connect", py_uwsgi_async_connect, METH_VARARGS, ""},
|
|
{"async_send_message", py_uwsgi_async_send_message, METH_VARARGS, ""},
|
|
|
|
{"green_schedule", py_uwsgi_suspend, METH_VARARGS, ""},
|
|
{"suspend", py_uwsgi_suspend, METH_VARARGS, ""},
|
|
{"wait_fd_read", py_eventfd_read, METH_VARARGS, ""},
|
|
{"wait_fd_write", py_eventfd_write, METH_VARARGS, ""},
|
|
|
|
{"connect", py_uwsgi_connect, METH_VARARGS, ""},
|
|
{"connection_fd", py_uwsgi_connection_fd, METH_VARARGS, ""},
|
|
{"is_connected", py_uwsgi_is_connected, METH_VARARGS, ""},
|
|
{"send", py_uwsgi_send, METH_VARARGS, ""},
|
|
{"recv", py_uwsgi_recv, METH_VARARGS, ""},
|
|
{"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""},
|
|
{"close", py_uwsgi_close, METH_VARARGS, ""},
|
|
{"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""},
|
|
|
|
{"parsefile", py_uwsgi_parse_file, METH_VARARGS, ""},
|
|
{"embedded_data", py_uwsgi_embedded_data, METH_VARARGS, ""},
|
|
{"extract", py_uwsgi_extract, METH_VARARGS, ""},
|
|
|
|
{"mule_msg", py_uwsgi_mule_msg, METH_VARARGS, ""},
|
|
{"farm_msg", py_uwsgi_farm_msg, METH_VARARGS, ""},
|
|
{"mule_get_msg", (PyCFunction) py_uwsgi_mule_get_msg, METH_VARARGS|METH_KEYWORDS, ""},
|
|
{"farm_get_msg", py_uwsgi_farm_get_msg, METH_VARARGS, ""},
|
|
{"in_farm", py_uwsgi_in_farm, METH_VARARGS, ""},
|
|
|
|
{"ready", py_uwsgi_ready, METH_VARARGS, ""},
|
|
|
|
{"set_user_harakiri", py_uwsgi_set_user_harakiri, METH_VARARGS, ""},
|
|
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
|
|
|
|
{"websocket_recv", py_uwsgi_websocket_recv, METH_VARARGS, ""},
|
|
{"websocket_send", py_uwsgi_websocket_send, METH_VARARGS, ""},
|
|
{"websocket_handshake", py_uwsgi_websocket_handshake, METH_VARARGS, ""},
|
|
|
|
{NULL, NULL},
|
|
};
|
|
|
|
|
|
static PyMethodDef uwsgi_sa_methods[] = {
|
|
{"sharedarea_read", py_uwsgi_sharedarea_read, METH_VARARGS, ""},
|
|
{"sharedarea_write", py_uwsgi_sharedarea_write, METH_VARARGS, ""},
|
|
{"sharedarea_readbyte", py_uwsgi_sharedarea_readbyte, METH_VARARGS, ""},
|
|
{"sharedarea_writebyte", py_uwsgi_sharedarea_writebyte, METH_VARARGS, ""},
|
|
{"sharedarea_readlong", py_uwsgi_sharedarea_readlong, METH_VARARGS, ""},
|
|
{"sharedarea_writelong", py_uwsgi_sharedarea_writelong, METH_VARARGS, ""},
|
|
{"sharedarea_inclong", py_uwsgi_sharedarea_inclong, METH_VARARGS, ""},
|
|
{NULL, NULL},
|
|
};
|
|
|
|
PyObject *py_uwsgi_cache_clear(PyObject * self, PyObject * args) {
|
|
|
|
uint64_t i;
|
|
// skip the first slot
|
|
for (i = 1; i < uwsgi.caches->max_items; i++) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.caches->lock);
|
|
uwsgi_cache_del(NULL, 0, i, 0);
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_cache_del(PyObject * self, PyObject * args) {
|
|
|
|
char *key;
|
|
Py_ssize_t keylen = 0;
|
|
char *remote = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#|s:cache_del", &key, &keylen, &remote)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (remote && strlen(remote) > 0) {
|
|
UWSGI_RELEASE_GIL
|
|
//uwsgi_simple_send_string(remote, 111, 2, key, keylen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
|
UWSGI_GET_GIL
|
|
}
|
|
else if (uwsgi.caches) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.caches->lock);
|
|
if (uwsgi_cache_del(key, keylen, 0, 0)) {
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_cache_set(PyObject * self, PyObject * args) {
|
|
|
|
char *key;
|
|
char *value;
|
|
Py_ssize_t vallen = 0;
|
|
Py_ssize_t keylen = 0;
|
|
char *remote = NULL;
|
|
|
|
uint64_t expires = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#s#|is:cache_set", &key, &keylen, &value, &vallen, &expires, &remote)) {
|
|
return NULL;
|
|
}
|
|
|
|
if ((uint64_t)vallen > uwsgi.caches->blocksize) {
|
|
return PyErr_Format(PyExc_ValueError, "uWSGI cache items size must be < %llu, requested %llu bytes", (unsigned long long)uwsgi.caches->blocksize, (unsigned long long) vallen);
|
|
}
|
|
|
|
if (remote && strlen(remote) > 0) {
|
|
UWSGI_RELEASE_GIL
|
|
//uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
|
UWSGI_GET_GIL
|
|
}
|
|
else if (uwsgi.caches) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.caches->lock);
|
|
if (uwsgi_cache_set(key, keylen, value, vallen, expires, 0)) {
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_cache_update(PyObject * self, PyObject * args) {
|
|
|
|
char *key;
|
|
char *value;
|
|
Py_ssize_t vallen = 0;
|
|
Py_ssize_t keylen = 0;
|
|
char *remote = NULL;
|
|
|
|
uint64_t expires = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#s#|is:cache_update", &key, &keylen, &value, &vallen, &expires, &remote)) {
|
|
return NULL;
|
|
}
|
|
|
|
if ((uint64_t)vallen > uwsgi.caches->blocksize) {
|
|
return PyErr_Format(PyExc_ValueError, "uWSGI cache items size must be < %llu, requested %llu bytes", (unsigned long long)uwsgi.caches->blocksize, (unsigned long long) vallen);
|
|
}
|
|
|
|
if (remote && strlen(remote) > 0) {
|
|
UWSGI_RELEASE_GIL
|
|
//uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
|
UWSGI_GET_GIL
|
|
}
|
|
else if (uwsgi.caches) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.caches->lock);
|
|
if (uwsgi_cache_set(key, keylen, value, vallen, expires, UWSGI_CACHE_FLAG_UPDATE)) {
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *py_uwsgi_cache_exists(PyObject * self, PyObject * args) {
|
|
|
|
char *key;
|
|
Py_ssize_t keylen = 0;
|
|
char *remote = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#|s:cache_exists", &key, &keylen, &remote)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (remote && strlen(remote) > 0) {
|
|
// TODO FIX THIS !!!
|
|
UWSGI_RELEASE_GIL
|
|
//uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
|
UWSGI_GET_GIL
|
|
/*
|
|
if (valsize > 0) {
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
*/
|
|
}
|
|
else if (uwsgi.caches) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_rlock(uwsgi.caches->lock);
|
|
if (uwsgi_cache_exists(key, keylen)) {
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
}
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
|
|
|
|
Py_ssize_t msglen = 0;
|
|
char *message ;
|
|
PyObject *res;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#:queue_push", &message, &msglen)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi.queue_size) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.queue_lock);
|
|
if (uwsgi_queue_push(message, msglen)) {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_True);
|
|
res = Py_True;
|
|
}
|
|
else {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
res = Py_None;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_queue_set(PyObject * self, PyObject * args) {
|
|
|
|
Py_ssize_t msglen = 0;
|
|
uint64_t pos = 0;
|
|
char *message ;
|
|
PyObject *res;
|
|
|
|
if (!PyArg_ParseTuple(args, "ls#:queue_set", &pos, &message, &msglen)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi.queue_size) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.queue_lock);
|
|
if (uwsgi_queue_set(pos, message, msglen)) {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_True);
|
|
res = Py_True;
|
|
}
|
|
else {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
res = Py_None;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_queue_slot(PyObject * self, PyObject * args) {
|
|
|
|
return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pos);
|
|
}
|
|
|
|
PyObject *py_uwsgi_queue_pull_slot(PyObject * self, PyObject * args) {
|
|
|
|
return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pull_pos);
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_queue_pull(PyObject * self, PyObject * args) {
|
|
|
|
char *message;
|
|
uint64_t size;
|
|
PyObject *res;
|
|
char *storage;
|
|
|
|
if (uwsgi.queue_size) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.queue_lock);
|
|
|
|
message = uwsgi_queue_pull(&size);
|
|
|
|
if (!message || size == 0) {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
storage = uwsgi_malloc(size);
|
|
memcpy(storage, message, size);
|
|
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
res = PyString_FromStringAndSize(storage, size);
|
|
free(storage);
|
|
return res;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
PyObject *py_uwsgi_queue_pop(PyObject * self, PyObject * args) {
|
|
|
|
char *message;
|
|
uint64_t size;
|
|
PyObject *res;
|
|
char *storage;
|
|
|
|
if (uwsgi.queue_size) {
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.queue_lock);
|
|
|
|
message = uwsgi_queue_pop(&size);
|
|
if (!message || size == 0) {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
storage = uwsgi_malloc(size);
|
|
memcpy(storage, message, size);
|
|
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
res = PyString_FromStringAndSize(storage, size);
|
|
free(storage);
|
|
return res;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
|
|
|
|
long index = 0;
|
|
uint64_t size = 0;
|
|
char *message;
|
|
PyObject *res;
|
|
char *storage;
|
|
|
|
if (!PyArg_ParseTuple(args, "l:queue_get", &index)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi.queue_size) {
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_rlock(uwsgi.queue_lock);
|
|
|
|
message = uwsgi_queue_get(index, &size);
|
|
if (!message || size == 0) {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
storage = uwsgi_malloc(size);
|
|
memcpy(storage, message, size);
|
|
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
res = PyString_FromStringAndSize(storage, size);
|
|
free(storage);
|
|
return res;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
|
|
|
|
long i, num = 0;
|
|
uint64_t size = 0;
|
|
char *message;
|
|
PyObject *res = NULL;
|
|
uint64_t base;
|
|
char *storage;
|
|
|
|
if (!PyArg_ParseTuple(args, "|l:queue_last", &num)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (uwsgi.queue_size) {
|
|
|
|
if (num > 0) {
|
|
res = PyList_New(0);
|
|
}
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_rlock(uwsgi.queue_lock);
|
|
|
|
if (uwsgi.queue_header->pos > 0) {
|
|
base = uwsgi.queue_header->pos-1;
|
|
}
|
|
else {
|
|
base = uwsgi.queue_size-1;
|
|
}
|
|
|
|
if (num == 0) {
|
|
message = uwsgi_queue_get(base, &size);
|
|
if (!message || size == 0) {
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
storage = uwsgi_malloc(size);
|
|
memcpy(storage, message, size);
|
|
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
res = PyString_FromStringAndSize(storage, size);
|
|
free(storage);
|
|
return res;
|
|
}
|
|
|
|
if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
|
|
|
|
char **queue_items = uwsgi_malloc(sizeof(char *) * num);
|
|
uint64_t *queue_items_size = uwsgi_malloc(sizeof(uint64_t) * num);
|
|
long item_pos = 0;
|
|
while(num) {
|
|
message = uwsgi_queue_get(base, &size);
|
|
if (!message || size == 0) {
|
|
queue_items[item_pos] = NULL;
|
|
queue_items_size[item_pos] = 0;
|
|
}
|
|
else {
|
|
queue_items[item_pos] = uwsgi_malloc(size);
|
|
memcpy(queue_items[item_pos], message, size);
|
|
queue_items_size[item_pos] = size;
|
|
}
|
|
item_pos++;
|
|
if (base > 0) {
|
|
base--;
|
|
}
|
|
else {
|
|
base = uwsgi.queue_size-1;
|
|
}
|
|
num--;
|
|
}
|
|
|
|
uwsgi_rwunlock(uwsgi.queue_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
for(i=0;i<item_pos;i++) {
|
|
if (queue_items[i]) {
|
|
PyObject *zero = PyString_FromStringAndSize(queue_items[i], queue_items_size[i]);
|
|
PyList_Append(res, zero);
|
|
Py_DECREF(zero);
|
|
free(queue_items[i]);
|
|
}
|
|
else {
|
|
Py_INCREF(Py_None);
|
|
PyList_Append(res, Py_None);
|
|
}
|
|
}
|
|
free(queue_items);
|
|
free(queue_items_size);
|
|
return res;
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
|
|
PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
|
|
|
char *key;
|
|
uint64_t valsize;
|
|
//uint16_t valsize16;
|
|
Py_ssize_t keylen = 0;
|
|
char *value = NULL;
|
|
char *remote = NULL;
|
|
//char buffer[0xffff];
|
|
PyObject *ret;
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
struct timeval tv, tv2;
|
|
#endif
|
|
|
|
if (!PyArg_ParseTuple(args, "s#|s:cache_get", &key, &keylen, &remote)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (remote && strlen(remote) > 0) {
|
|
UWSGI_RELEASE_GIL
|
|
//uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize16, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
|
UWSGI_GET_GIL
|
|
/*
|
|
if (valsize16 > 0) {
|
|
value = buffer;
|
|
valsize = valsize16;
|
|
}
|
|
*/
|
|
}
|
|
else if (uwsgi.caches) {
|
|
#ifdef UWSGI_DEBUG
|
|
gettimeofday(&tv, NULL);
|
|
#endif
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_rlock(uwsgi.caches->lock);
|
|
value = uwsgi_cache_get(key, keylen, &valsize);
|
|
if (!value) {
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
char *storage = uwsgi_malloc(valsize);
|
|
#ifdef UWSGI_DEBUG
|
|
gettimeofday(&tv2, NULL);
|
|
if ((tv2.tv_sec* (1000*1000) + tv2.tv_usec) - (tv.tv_sec* (1000*1000) + tv.tv_usec) > 30000) {
|
|
uwsgi_log("[slow] cache get done in %d microseconds (%llu bytes value)\n", (tv2.tv_sec* (1000*1000) + tv2.tv_usec) - (tv.tv_sec* (1000*1000) + tv.tv_usec), (unsigned long long) valsize);
|
|
}
|
|
#endif
|
|
memcpy(storage, value, valsize);
|
|
uwsgi_rwunlock(uwsgi.caches->lock);
|
|
UWSGI_GET_GIL
|
|
ret = PyString_FromStringAndSize(storage, valsize);
|
|
free(storage);
|
|
return ret;
|
|
}
|
|
|
|
if (value) {
|
|
return PyString_FromStringAndSize(value, valsize);
|
|
}
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
}
|
|
|
|
static PyMethodDef uwsgi_cache_methods[] = {
|
|
{"cache_get", py_uwsgi_cache_get, METH_VARARGS, ""},
|
|
{"cache_set", py_uwsgi_cache_set, METH_VARARGS, ""},
|
|
{"cache_update", py_uwsgi_cache_update, METH_VARARGS, ""},
|
|
{"cache_del", py_uwsgi_cache_del, METH_VARARGS, ""},
|
|
{"cache_exists", py_uwsgi_cache_exists, METH_VARARGS, ""},
|
|
{"cache_clear", py_uwsgi_cache_clear, METH_VARARGS, ""},
|
|
{NULL, NULL},
|
|
};
|
|
|
|
static PyMethodDef uwsgi_queue_methods[] = {
|
|
{"queue_get", py_uwsgi_queue_get, METH_VARARGS, ""},
|
|
{"queue_set", py_uwsgi_queue_set, METH_VARARGS, ""},
|
|
{"queue_last", py_uwsgi_queue_last, METH_VARARGS, ""},
|
|
{"queue_push", py_uwsgi_queue_push, METH_VARARGS, ""},
|
|
{"queue_pull", py_uwsgi_queue_pull, METH_VARARGS, ""},
|
|
{"queue_pop", py_uwsgi_queue_pop, METH_VARARGS, ""},
|
|
{"queue_slot", py_uwsgi_queue_slot, METH_VARARGS, ""},
|
|
{"queue_pull_slot", py_uwsgi_queue_pull_slot, METH_VARARGS, ""},
|
|
{NULL, NULL},
|
|
};
|
|
|
|
|
|
|
|
void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) {
|
|
PyMethodDef *uwsgi_function;
|
|
PyObject *uwsgi_module_dict;
|
|
|
|
uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
|
|
if (!uwsgi_module_dict) {
|
|
uwsgi_log("could not get uwsgi module __dict__\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (uwsgi_function = uwsgi_spooler_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
|
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
|
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
|
|
Py_DECREF(func);
|
|
}
|
|
}
|
|
|
|
void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) {
|
|
PyMethodDef *uwsgi_function;
|
|
PyObject *uwsgi_module_dict;
|
|
|
|
uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
|
|
if (!uwsgi_module_dict) {
|
|
uwsgi_log("could not get uwsgi module __dict__\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (uwsgi_function = uwsgi_advanced_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
|
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
|
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
|
|
Py_DECREF(func);
|
|
}
|
|
|
|
}
|
|
|
|
void init_uwsgi_module_cache(PyObject * current_uwsgi_module) {
|
|
PyMethodDef *uwsgi_function;
|
|
PyObject *uwsgi_module_dict;
|
|
|
|
uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
|
|
if (!uwsgi_module_dict) {
|
|
uwsgi_log("could not get uwsgi module __dict__\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (uwsgi_function = uwsgi_cache_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
|
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
|
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
|
|
Py_DECREF(func);
|
|
}
|
|
}
|
|
|
|
void init_uwsgi_module_queue(PyObject * current_uwsgi_module) {
|
|
PyMethodDef *uwsgi_function;
|
|
PyObject *uwsgi_module_dict;
|
|
|
|
uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
|
|
if (!uwsgi_module_dict) {
|
|
uwsgi_log("could not get uwsgi module __dict__\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (uwsgi_function = uwsgi_queue_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
|
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
|
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
|
|
Py_DECREF(func);
|
|
}
|
|
|
|
PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyLong_FromUnsignedLongLong(uwsgi.queue_size));
|
|
}
|
|
|
|
|
|
void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
|
|
PyMethodDef *uwsgi_function;
|
|
PyObject *uwsgi_module_dict;
|
|
|
|
uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
|
|
if (!uwsgi_module_dict) {
|
|
uwsgi_log("could not get uwsgi module __dict__\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (uwsgi_function = uwsgi_sa_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
|
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
|
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
|
|
Py_DECREF(func);
|
|
}
|
|
}
|
|
|
|
PyObject *py_snmp_set_counter32(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint32_t oid_val = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_set_counter32", &oid_num, &oid_val)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_set_counter64(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint64_t oid_val = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "bK:snmp_set_counter64", &oid_num, &oid_val)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_set_gauge(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint32_t oid_val = 0;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_set_gauge", &oid_num, &oid_val)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_incr_counter32(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint32_t oid_val = 1;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter32", &oid_num, &oid_val)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "b:snmp_incr_counter32", &oid_num)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_incr_counter64(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint64_t oid_val = 1;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter64", &oid_num, &oid_val)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "b:snmp_incr_counter64", &oid_num)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_incr_gauge(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint64_t oid_val = 1;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_incr_gauge", &oid_num, &oid_val)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "b:snmp_incr_gauge", &oid_num)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_decr_counter32(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint32_t oid_val = 1;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter32", &oid_num, &oid_val)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "b:snmp_incr_counter32", &oid_num)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_decr_counter64(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint64_t oid_val = 1;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter64", &oid_num, &oid_val)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "b:snmp_incr_counter64", &oid_num)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_decr_gauge(PyObject * self, PyObject * args) {
|
|
|
|
uint8_t oid_num;
|
|
uint64_t oid_val = 1;
|
|
|
|
if (!PyArg_ParseTuple(args, "bI:snmp_incr_gauge", &oid_num, &oid_val)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "b:snmp_incr_gauge", &oid_num)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (oid_num > 100 || oid_num < 1)
|
|
goto clear;
|
|
|
|
UWSGI_RELEASE_GIL
|
|
uwsgi_wlock(uwsgi.snmp_lock);
|
|
|
|
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
|
|
uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val;
|
|
|
|
uwsgi_rwunlock(uwsgi.snmp_lock);
|
|
UWSGI_GET_GIL
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
clear:
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject *py_snmp_set_community(PyObject * self, PyObject * args) {
|
|
|
|
char *snmp_community;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:snmp_set_community", &snmp_community)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (strlen(snmp_community) > 72) {
|
|
uwsgi_log( "*** warning the supplied SNMP community string will be truncated to 72 chars ***\n");
|
|
memcpy(uwsgi.shared->snmp_community, snmp_community, 72);
|
|
}
|
|
else {
|
|
memcpy(uwsgi.shared->snmp_community, snmp_community, strlen(snmp_community) + 1);
|
|
}
|
|
|
|
Py_INCREF(Py_True);
|
|
return Py_True;
|
|
|
|
}
|
|
|
|
|
|
static PyMethodDef uwsgi_snmp_methods[] = {
|
|
{"snmp_set_counter32", py_snmp_set_counter32, METH_VARARGS, ""},
|
|
{"snmp_set_counter64", py_snmp_set_counter64, METH_VARARGS, ""},
|
|
{"snmp_set_gauge", py_snmp_set_gauge, METH_VARARGS, ""},
|
|
{"snmp_incr_counter32", py_snmp_incr_counter32, METH_VARARGS, ""},
|
|
{"snmp_incr_counter64", py_snmp_incr_counter64, METH_VARARGS, ""},
|
|
{"snmp_incr_gauge", py_snmp_incr_gauge, METH_VARARGS, ""},
|
|
{"snmp_decr_counter32", py_snmp_decr_counter32, METH_VARARGS, ""},
|
|
{"snmp_decr_counter64", py_snmp_decr_counter64, METH_VARARGS, ""},
|
|
{"snmp_decr_gauge", py_snmp_decr_gauge, METH_VARARGS, ""},
|
|
{"snmp_set_community", py_snmp_set_community, METH_VARARGS, ""},
|
|
{NULL, NULL},
|
|
};
|
|
|
|
void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) {
|
|
|
|
PyMethodDef *uwsgi_function;
|
|
|
|
PyObject *uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
|
|
if (!uwsgi_module_dict) {
|
|
uwsgi_log("could not get uwsgi module __dict__\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (uwsgi_function = uwsgi_snmp_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
|
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
|
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
|
|
Py_DECREF(func);
|
|
}
|
|
|
|
uwsgi_log( "SNMP python functions initialized.\n");
|
|
}
|