Files
uwsgi/plugins/python/uwsgi_pymodule.c
T
Unbit d4130dbc4b first round of protocol parsers optimizations
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
2013-02-03 10:38:13 +01:00

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(&current_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");
}