From 534ff245f2cbca07686d769af64aeb815f3f93ed Mon Sep 17 00:00:00 2001 From: "roberto@maverick64" Date: Sat, 5 Feb 2011 15:16:22 +0100 Subject: [PATCH] new Erlang subsystem --- buildconf/default.ini | 1 - erlang.c | 727 --------------------------------- gateway.c | 27 ++ master.c | 7 + plugins/erlang/erlang.c | 401 ++++++++++++++++++ plugins/erlang/erlang.h | 17 + plugins/erlang/uwsgiplugin.py | 7 + plugins/pyerl/pyerl.c | 135 ++++++ plugins/pyerl/uwsgiplugin.py | 8 + plugins/python/python_plugin.c | 75 ++-- plugins/python/uwsgi_python.h | 2 + socket.c | 10 +- utils.c | 10 + uwsgi.c | 39 +- uwsgi.h | 31 +- uwsgiconfig.py | 6 - 16 files changed, 680 insertions(+), 823 deletions(-) delete mode 100644 erlang.c create mode 100644 plugins/erlang/erlang.c create mode 100644 plugins/erlang/erlang.h create mode 100644 plugins/erlang/uwsgiplugin.py create mode 100644 plugins/pyerl/pyerl.c create mode 100644 plugins/pyerl/uwsgiplugin.py diff --git a/buildconf/default.ini b/buildconf/default.ini index af8197a9..9e1a6dde 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -4,7 +4,6 @@ ini = true yaml = true snmp = true sctp = false -erlang = false spooler = true embedded = true udp = true diff --git a/erlang.c b/erlang.c deleted file mode 100644 index 7ae9dd3f..00000000 --- a/erlang.c +++ /dev/null @@ -1,727 +0,0 @@ -#ifdef UWSGI_ERLANG - -#include "uwsgi.h" - -extern struct uwsgi_server uwsgi; - -static void erlang_log(void); - -/* -PyObject *py_erlang_connect(PyObject * self, PyObject * args) { - - char *erlang_node; - int fd; - - - if (!PyArg_ParseTuple(args, "s:erlang_connect", &erlang_node)) { - return NULL; - } - - UWSGI_SET_BLOCKING; - fd = erl_connect(erlang_node); - UWSGI_UNSET_BLOCKING; - return PyInt_FromLong(fd); -} - -PyObject *py_erlang_recv_message(PyObject * self, PyObject * args) { - int erfd; - struct pollfd erpoll; - ErlMessage emsg; - PyObject *pyer = NULL; - unsigned char erlang_buffer[8192]; - int eret; - int timeout = uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]; - - if (!PyArg_ParseTuple(args, "i|i:erlang_recv_message", &erfd, &timeout)) { - return NULL; - } - - if (erfd < 0) { - goto clear; - } - - erpoll.fd = erfd; - erpoll.events = POLLIN; - cycle: - memset(&emsg, 0, sizeof(ErlMessage)); - UWSGI_SET_BLOCKING; - if (timeout > 0) { - eret = poll(&erpoll, 1, timeout * 1000); - if (eret < 0) { - uwsgi_error("poll()"); - goto clear; - } - else if (eret == 0) { - goto clear; - } - } - if (erl_receive_msg(erfd, erlang_buffer, 8192, &emsg) == ERL_MSG) { - if (emsg.type == ERL_TICK) { - goto cycle; - } - if (emsg.msg) { - pyer = eterm_to_py(emsg.msg); - } - if (emsg.msg) { - erl_free_compound(emsg.msg); - } - if (emsg.to) { - erl_free_compound(emsg.to); - } - if (emsg.from) { - erl_free_compound(emsg.from); - } - if (!pyer) { - goto clear; - } - UWSGI_UNSET_BLOCKING; - return pyer; - } - - clear: - UWSGI_UNSET_BLOCKING; - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject *py_erlang_send_message(PyObject * self, PyObject * args) { - - ETERM *pymessage; - ETERM *pid; - int erfd; - PyObject *ermessage, *erdest, *zero; - - int er_number, er_serial, er_creation; - char *er_node; - - if (!PyArg_ParseTuple(args, "iOO|i:erlang_send_message", &erfd, &erdest, &ermessage)) { - return NULL; - } - - if (erfd < 0) { - goto clear; - } - - if (!PyString_Check(erdest) && !PyDict_Check(erdest)) { - goto clear; - } - - pymessage = py_to_eterm(ermessage); - if (!pymessage) { - goto clear; - } - - - if (PyString_Check(erdest)) { - if (!erl_reg_send(erfd, PyString_AsString(erdest), pymessage)) { - erl_err_msg("erl_reg_send()"); - goto clear2; - } - } - else if (PyDict_Check(erdest)) { - zero = PyDict_GetItemString(erdest, "node"); - if (!zero) { - goto clear2; - } - if (!PyString_Check(zero)) { - goto clear2; - } - er_node = PyString_AsString(zero); - - zero = PyDict_GetItemString(erdest, "number"); - if (!zero) { - goto clear2; - } - if (!PyInt_Check(zero)) { - goto clear2; - } - er_number = PyInt_AsLong(zero); - - zero = PyDict_GetItemString(erdest, "serial"); - if (!zero) { - goto clear2; - } - if (!PyInt_Check(zero)) { - goto clear2; - } - er_serial = PyInt_AsLong(zero); - - zero = PyDict_GetItemString(erdest, "creation"); - if (!zero) { - goto clear2; - } - if (!PyInt_Check(zero)) { - goto clear2; - } - er_creation = PyInt_AsLong(zero); - - pid = erl_mk_pid((const char *) er_node, er_number, er_serial, er_creation); - - if (!pid) { - goto clear2; - } - - if (!erl_send(erfd, pid, pymessage)) { - erl_err_msg("erl_send()"); - erl_free_term(pid); - goto clear2; - } - - erl_free_term(pid); - } - else { - goto clear; - } - - erl_free_compound(pymessage); - - Py_INCREF(Py_True); - return Py_True; - - clear2: - erl_free_compound(pymessage); - clear: - PyErr_Print(); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject *py_erlang_rpc(PyObject * self, PyObject * args) { - - int fd, timeout = uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]; - char *emod, *efun; - PyObject *eargs, *pyer = NULL; - ETERM *pyargs, *rex; - ErlMessage emsg; - int eret; - - if (!PyArg_ParseTuple(args, "issO|i:erlang_rpc", &fd, &emod, &efun, &eargs, &timeout)) { - return NULL; - } - - if (fd < 0) { - goto clear; - } - - pyargs = py_to_eterm(eargs); - if (!pyargs) { - goto clear; - } - - - if (erl_rpc_to(fd, emod, efun, pyargs)) { - erl_err_msg("erl_rpc_to()"); - goto clear2; - } - - - cycle: - memset(&emsg, 0, sizeof(ErlMessage)); - UWSGI_SET_BLOCKING; - eret = erl_rpc_from(fd, timeout * 1000, &emsg); - if (eret == ERL_TICK) { - goto cycle; - } - else if (eret == ERL_MSG) { - if (emsg.msg) { - if (ERL_IS_TUPLE(emsg.msg)) { - rex = erl_element(1, emsg.msg); - if (!rex) { - goto clear2; - } - if (!strncmp("rex", ERL_ATOM_PTR(rex), ERL_ATOM_SIZE(rex))) { - erl_free_term(rex); - rex = erl_element(2, emsg.msg); - if (!rex) { - goto clear2; - } - pyer = eterm_to_py(rex); - erl_free_term(rex); - } - else { - erl_free_term(rex); - } - } - } - if (emsg.msg) { - erl_free_compound(emsg.msg); - } - if (emsg.to) { - erl_free_compound(emsg.to); - } - if (emsg.from) { - erl_free_compound(emsg.from); - } - if (!pyer) { - goto clear2; - } - erl_free_compound(pyargs); - UWSGI_UNSET_BLOCKING; - return pyer; - } - else { - erl_err_msg("erl_rpc_from()"); - } - - clear2: - UWSGI_UNSET_BLOCKING; - erl_free_compound(pyargs); - - clear: - Py_INCREF(Py_None); - return Py_None; -} - -PyObject *py_erlang_close(PyObject * self, PyObject * args) { - - int fd; - - if (!PyArg_ParseTuple(args, "i:erlang_close", &fd)) { - return NULL; - } - - - if (fd >= 0) { - erl_close_connection(fd); - } - - Py_INCREF(Py_True); - return Py_True; -} - -static PyMethodDef uwsgi_erlang_methods[] = { - {"erlang_connect", py_erlang_connect, METH_VARARGS, ""}, - {"erlang_send_message", py_erlang_send_message, METH_VARARGS, ""}, - {"erlang_recv_message", py_erlang_recv_message, METH_VARARGS, ""}, - {"erlang_rpc", py_erlang_rpc, METH_VARARGS, ""}, - {"erlang_close", py_erlang_close, METH_VARARGS, ""}, - {NULL, NULL}, -}; - -*/ - -int init_erlang(char *nodename, char *cookie) { - - struct sockaddr_in e_addr; - - char *ip; - char *node; - int efd; - int rlen; - char *cookiefile; - char *cookiehome; - char cookievalue[128]; - int cookiefd; - - - //PyMethodDef *uwsgi_function; - - - ip = strchr(nodename, '@'); - - if (ip == NULL) { - uwsgi_log( "*** invalid erlang node name ***\n"); - return -1; - } - - uwsgi_log("using cookie %s\n", cookie); - if (cookie == NULL) { - // get the cookie from the home - cookiehome = getenv("HOME"); - if (!cookiehome) { - uwsgi_log( "unable to get erlang cookie from your home.\n"); - return -1; - } - cookiefile = malloc(strlen(cookiehome) + 1 + strlen(".erlang.cookie") + 1); - if (!cookiefile) { - uwsgi_error("malloc()"); - } - cookiefile[0] = 0; - strcat(cookiefile, cookiehome); - strcat(cookiefile, "/.erlang.cookie"); - - cookiefd = open(cookiefile, O_RDONLY); - if (cookiefd < 0) { - uwsgi_error("open()"); - free(cookiefile); - return -1; - } - - memset(cookievalue, 0, 128); - if (read(cookiefd, cookievalue, 127) < 1) { - uwsgi_log( "invalid cookie found in %s\n", cookiefile); - close(cookiefd); - free(cookiefile); - return -1; - } - cookie = cookievalue; - close(cookiefd); - free(cookiefile); - } - - node = malloc((ip - nodename) + 1); - if (node == NULL) { - uwsgi_error("malloc()"); - return -1; - } - memset(node, 0, (ip - nodename) + 1); - memcpy(node, nodename, ip - nodename); - - erl_init(NULL, 0); - - if (erl_connect_xinit(ip + 1, node, nodename, NULL, cookie, 0) == -1) { - uwsgi_log( "*** unable to initialize erlang c-node ***\n"); - return -1; - } - - efd = socket(AF_INET, SOCK_STREAM, 0); - if (efd < 0) { - uwsgi_error("socket()"); - return -1; - } - - - memset(&e_addr, 0, sizeof(struct sockaddr_in)); - e_addr.sin_family = AF_INET; - e_addr.sin_addr.s_addr = inet_addr(ip + 1); - - rlen = 1; - if (setsockopt(efd, SOL_SOCKET, SO_REUSEADDR, &rlen, sizeof(rlen))) { - uwsgi_error("setsockopt()"); - close(efd); - return -1; - } - - if (bind(efd, (struct sockaddr *) &e_addr, sizeof(struct sockaddr_in)) < 0) { - uwsgi_error("bind()"); - close(efd); - return -1; - } - - rlen = sizeof(struct sockaddr_in); - if (getsockname(efd, (struct sockaddr *) &e_addr, (socklen_t *) & rlen)) { - uwsgi_error("getsockname()"); - close(efd); - return -1; - } - - if (listen(efd, uwsgi.listen_queue)) { - uwsgi_error("listen()"); - close(efd); - return -1; - } - - if (erl_publish(ntohs(e_addr.sin_port)) < 0) { - uwsgi_log( "*** unable to subscribe with EPMD ***\n"); - close(efd); - return -1; - } - - uwsgi_log( "Erlang C-Node initialized on port %d you can access it with name %s\n", ntohs(e_addr.sin_port), nodename); - -/* - for (uwsgi_function = uwsgi_erlang_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) { - PyObject *func = PyCFunction_New(uwsgi_function, NULL); - PyDict_SetItemString(uwsgi.embedded_dict, uwsgi_function->ml_name, func); - Py_DECREF(func); - } -*/ - - return efd; - -} - -/* -ETERM *py_to_eterm(PyObject * pobj) { - int i; - int count; - PyObject *pobj2; - ETERM *eobj = NULL; - ETERM *eobj2 = NULL; - ETERM **eobj3; - - if (pobj == NULL) { - return erl_mk_empty_list(); - } - - if (PyString_Check(pobj)) { - eobj = erl_mk_atom(PyString_AsString(pobj)); - } - else if (PyInt_Check(pobj)) { - eobj = erl_mk_int(PyInt_AsLong(pobj)); - } - else if (PyList_Check(pobj)) { - eobj = erl_mk_empty_list(); - for (i = PyList_Size(pobj) - 1; i >= 0; i--) { - pobj2 = PyList_GetItem(pobj, i); - eobj2 = py_to_eterm(pobj2); - eobj = erl_cons(eobj2, eobj); - } - } - else if (PyDict_Check(pobj)) { - // a pid - char *er_node; - int er_number, er_serial, er_creation; - pobj2 = PyDict_GetItemString(pobj, "node"); - if (!pobj2) { - PyErr_Print(); - goto clear; - } - if (!PyString_Check(pobj2)) { - goto clear; - } - er_node = PyString_AsString(pobj2); - - pobj2 = PyDict_GetItemString(pobj, "number"); - if (!pobj2) { - PyErr_Print(); - goto clear; - } - if (!PyInt_Check(pobj2)) { - goto clear; - } - er_number = PyInt_AsLong(pobj2); - - pobj2 = PyDict_GetItemString(pobj, "serial"); - if (!pobj2) { - PyErr_Print(); - goto clear; - } - if (!PyInt_Check(pobj2)) { - goto clear; - } - er_serial = PyInt_AsLong(pobj2); - - pobj2 = PyDict_GetItemString(pobj, "creation"); - if (!pobj2) { - PyErr_Print(); - goto clear; - } - if (!PyInt_Check(pobj2)) { - goto clear; - } - er_creation = PyInt_AsLong(pobj2); - - eobj = erl_mk_pid(er_node, er_number, er_serial, er_creation); - } - else if (PyTuple_Check(pobj)) { - count = PyTuple_Size(pobj); - eobj3 = malloc(sizeof(ETERM *) * count); - for (i = 0; i < count; i++) { - pobj2 = PyTuple_GetItem(pobj, i); - if (!pobj2) { - break; - } - eobj3[i] = py_to_eterm(pobj2); - } - eobj = erl_mk_tuple(eobj3, count); - free(eobj3); - } - else { - uwsgi_log( "UNMANAGED PYTHON TYPE: %s\n", pobj->ob_type->tp_name); - } - - clear: - if (eobj == NULL) { - return erl_mk_empty_list(); - } - - return eobj; -} - -PyObject *eterm_to_py(ETERM * obj) { - int i; - int count; - ETERM *obj2; - PyObject *eobj = NULL; - - if (obj == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - - switch (ERL_TYPE(obj)) { - - case ERL_CONS: - case ERL_NIL: - count = erl_length(obj); - eobj = PyList_New(0); - for (i = 0; i < count; i++) { - obj2 = erl_hd(obj); - PyList_Append(eobj, eterm_to_py(obj2)); - obj = erl_tl(obj); - } - break; - case ERL_TUPLE: - eobj = PyTuple_New(erl_size(obj)); - for (i = 1; i <= erl_size(obj); i++) { - obj2 = erl_element(i, obj); - PyTuple_SetItem(eobj, i - 1, eterm_to_py(obj2)); - } - break; - case ERL_ATOM: - eobj = PyString_FromStringAndSize(ERL_ATOM_PTR(obj), ERL_ATOM_SIZE(obj)); - break; - case ERL_INTEGER: - eobj = PyInt_FromLong(ERL_INT_VALUE(obj)); - break; - case ERL_BINARY: - uwsgi_log( "FOUND A BINARY %.*s\n", ERL_BIN_SIZE(obj), ERL_BIN_PTR(obj)); - break; - case ERL_PID: - eobj = PyDict_New(); - if (PyDict_SetItemString(eobj, "node", PyString_FromString(ERL_PID_NODE(obj)))) { - PyErr_Print(); - break; - } - if (PyDict_SetItemString(eobj, "number", PyInt_FromLong(ERL_PID_NUMBER(obj)))) { - PyErr_Print(); - break; - } - if (PyDict_SetItemString(eobj, "serial", PyInt_FromLong(ERL_PID_SERIAL(obj)))) { - PyErr_Print(); - break; - } - if (PyDict_SetItemString(eobj, "creation", PyInt_FromLong(ERL_PID_CREATION(obj)))) { - PyErr_Print(); - break; - } - default: - uwsgi_log( "UNMANAGED ETERM TYPE: %d\n", ERL_TYPE(obj)); - break; - - } - - if (eobj == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - - return eobj; -} -*/ - -void erlang_loop(struct wsgi_request *wsgi_req) { - - ErlConnect econn; - ErlMessage em; - unsigned char buffer[4096]; - //ETERM *eresponse; - -/* - PyObject *callable = PyDict_GetItemString(uwsgi.embedded_dict, "erlang_func"); - if (!callable) { - PyErr_Print(); - uwsgi_log( "- you have not defined a uwsgi.erlang_func callable, Erlang message manager will be disabled until you define it -\n"); - } - - PyObject *pargs = PyTuple_New(1); - if (!pargs) { - PyErr_Print(); - uwsgi_log( "- error preparing arg tuple for uwsgi.erlang_func callable, Erlang message manager will be disabled -\n"); - } - -*/ - - while (uwsgi.workers[uwsgi.mywid].manage_next_request) { - - uwsgi_log("entering erlang cycle\n"); - - UWSGI_CLEAR_STATUS; - - wsgi_req->poll.fd = erl_accept(uwsgi.erlangfd, &econn); - - uwsgi_log("accepted %d\n", wsgi_req->poll.fd); - - if (wsgi_req->poll.fd >= 0) { - - UWSGI_SET_ERLANGING; - for (;;) { - uwsgi_log("receive message\n"); - if (erl_receive_msg(wsgi_req->poll.fd, buffer, 4096, &em) == ERL_MSG) { - - uwsgi_log("message received\n"); - if (em.type == ERL_TICK) - continue; - - /* - if (!callable) { - callable = PyDict_GetItemString(uwsgi.embedded_dict, "erlang_func"); - } - - if (!callable) { - uwsgi_log( "- you still have not defined a uwsgi.erlang_func callable, Erlang message rejected -\n"); - } - - PyObject *zero = eterm_to_py(em.msg); - - */ - uwsgi_log("received object %d\n", ERL_TYPE(em.msg)); - if (em.msg) { - erl_free_compound(em.msg); - } - if (em.to) { - erl_free_compound(em.to); - } - - /* - if (!zero) { - PyErr_Print(); - continue; - } - - if (PyTuple_SetItem(pargs, 0, zero)) { - PyErr_Print(); - continue; - } - - PyObject *erlang_result = PyEval_CallObject(callable, pargs); - - //Py_DECREF(zero); - - if (erlang_result) { - eresponse = py_to_eterm(erlang_result); - if (eresponse) { - erl_send(wsgi_req->poll.fd, em.from, eresponse); - erl_free_compound(eresponse); - } - Py_DECREF(erlang_result); - } - - */ - if (em.from) { - erl_free_compound(em.from); - } - - uwsgi.workers[0].requests++; - uwsgi.workers[uwsgi.mywid].requests++; - if (uwsgi.shared->options[UWSGI_OPTION_LOGGING]) - erlang_log(); - } - else { - uwsgi_log("oooops\n"); - break; - } - } - erl_close_connection(wsgi_req->poll.fd); - - UWSGI_UNSET_ERLANGING; - } - } -} - -static void erlang_log() { - if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG]) { - get_memusage(); - } - else { - uwsgi.workers[uwsgi.mywid].rss_size = 0; - uwsgi.workers[uwsgi.mywid].vsz_size = 0; - } - uwsgi_log( "[Erlang worker %d pid %d] request %llu done {rss: %llu vsz: %llu}\n", uwsgi.mywid, uwsgi.mypid, uwsgi.workers[uwsgi.mywid].requests, uwsgi.workers[uwsgi.mywid].rss_size, uwsgi.workers[uwsgi.mywid].vsz_size); -} - -#else -#warning "*** Erlang support is disabled ***" -#endif diff --git a/gateway.c b/gateway.c index 479b30a9..db50b14d 100644 --- a/gateway.c +++ b/gateway.c @@ -2,6 +2,33 @@ extern struct uwsgi_server uwsgi; +struct uwsgi_gateway *register_fat_gateway(char *name, void (*loop)(void)) { + + struct uwsgi_gateway *ug; + int num=1,i; + + if (uwsgi.gateways_cnt >= MAX_GATEWAYS) { + uwsgi_log("you can register max %d gateways\n", MAX_GATEWAYS); + return NULL; + } + + for(i=0;ipid = 0; + ug->name = name; + ug->loop = loop; + ug->num = num; + + uwsgi.gateways_cnt++; + + return ug; +} + struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) { pid_t gw_pid; diff --git a/master.c b/master.c index af2a5694..0cc1150a 100644 --- a/master.c +++ b/master.c @@ -223,6 +223,13 @@ void master_loop(char **argv, char **environ) { */ + // spawn fat gateways + for(i=0;i= uwsgi.numproc && uwsgi.to_hell) { diff --git a/plugins/erlang/erlang.c b/plugins/erlang/erlang.c new file mode 100644 index 00000000..b0ffda9c --- /dev/null +++ b/plugins/erlang/erlang.c @@ -0,0 +1,401 @@ +#include "uwsgi.h" +#include "erlang.h" + +extern struct uwsgi_server uwsgi; +struct uwsgi_erlang uerl; + +struct option erlang_options[] = { + {"erlang", required_argument, 0, LONG_ARGS_ERLANG}, + {"erlang-cookie", required_argument, 0, LONG_ARGS_ERLANG_COOKIE}, + {0, 0, 0, 0}, +}; + + +void dump_eterm(ei_x_buff *x) { + + int etype, esize, arity; + long long num; + char *atom; + int i; + char *binary; + long bin_size; + double fnum; + + ei_get_type(x->buff, &x->index, &etype, &esize); + uwsgi_log("etype: %d/%c esize: %d\n", etype, etype, esize); + + switch(etype) { + case ERL_SMALL_INTEGER_EXT: + case ERL_INTEGER_EXT: + case ERL_SMALL_BIG_EXT: + case ERL_LARGE_BIG_EXT: + ei_decode_longlong(x->buff, &x->index, &num); + uwsgi_log("num: %lu\n", num); + break; + case ERL_FLOAT_EXT: + ei_decode_double(x->buff, &x->index, &fnum); + uwsgi_log("float: %f\n", fnum); + break; + case ERL_STRING_EXT: + atom = uwsgi_malloc(esize+1); + ei_decode_string(x->buff, &x->index, atom); + uwsgi_log("string: %s\n", atom); + free(atom); + break; + case ERL_ATOM_EXT: + atom = uwsgi_malloc(esize+1); + ei_decode_atom(x->buff, &x->index, atom); + uwsgi_log("atom: %s\n", atom); + free(atom); + break; + case ERL_SMALL_TUPLE_EXT: + case ERL_LARGE_TUPLE_EXT: + ei_decode_tuple_header(x->buff, &x->index, &arity); + for(i=0;ibuff, &x->index, &arity); + if (arity == 0) { + uwsgi_log("nil value\n"); + break; + } + for(i=0;ibuff, &x->index, binary, &bin_size); + uwsgi_log("binary data of %d bytes\n", bin_size); + free(binary); + break; + default: + uwsgi_log("ignored...\n"); + ei_skip_term(x->buff, &x->index); + break; + + + + } + + +} + +void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) { + + int etype, esize; + int arity; + + char *gen_call; + char *module; + char *call; + char buffer[0xffff]; + + char *argv[0xff] ; + int argc; + uint16_t ret; + ei_x_buff xr; + + erlang_ref eref; + + ei_get_type(x->buff, &x->index, &etype, &esize); + + uwsgi_log("%d %c %c %c\n", etype, etype, ERL_SMALL_TUPLE_EXT, ERL_LARGE_TUPLE_EXT); + if (etype != ERL_SMALL_TUPLE_EXT && etype != ERL_LARGE_TUPLE_EXT) return; + + uwsgi_log("decode tuple\n"); + ei_decode_tuple_header(x->buff, &x->index, &arity); + + uwsgi_log("rpc arity %d\n", arity); + if (arity != 3) return ; + + ei_get_type(x->buff, &x->index, &etype, &esize); + + uwsgi_log("%d %c\n", etype, etype); + + if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ; + + gen_call = uwsgi_malloc(esize); + + if (etype == ERL_ATOM_EXT) { + ei_decode_atom(x->buff, &x->index, gen_call); + } + else { + ei_decode_string(x->buff, &x->index, gen_call); + } + + uwsgi_log("gen call = %s\n", gen_call); + + ei_get_type(x->buff, &x->index, &etype, &esize); + + if (etype != ERL_SMALL_TUPLE_EXT) return ; + + ei_decode_tuple_header(x->buff, &x->index, &arity); + if (arity != 2) return ; + + ei_get_type(x->buff, &x->index, &etype, &esize); + ei_skip_term(x->buff, &x->index); + uwsgi_log("skip0 %d %c\n", etype, etype); + ei_get_type(x->buff, &x->index, &etype, &esize); + uwsgi_log("skip1 %d %c\n", etype, etype); + ei_decode_ref(x->buff, &x->index, &eref); + + ei_get_type(x->buff, &x->index, &etype, &esize); + uwsgi_log("%d %c\n", etype, etype); + + module = uwsgi_malloc(esize); + + if (etype == ERL_ATOM_EXT) { + ei_decode_atom(x->buff, &x->index, module); + } + else { + ei_decode_string(x->buff, &x->index, module); + } + + ei_get_type(x->buff, &x->index, &etype, &esize); + + uwsgi_log("%d %c\n", etype, etype); + + if (etype != ERL_SMALL_TUPLE_EXT) return ; + + ei_decode_tuple_header(x->buff, &x->index, &arity); + + uwsgi_log("arity: %d\n", arity); + if (arity != 5) return ; + + ei_get_type(x->buff, &x->index, &etype, &esize); + uwsgi_log("%d %c\n", etype, etype); + + char *method = uwsgi_malloc(esize); + + if (etype == ERL_ATOM_EXT) { + ei_decode_atom(x->buff, &x->index, method); + } + else { + ei_decode_string(x->buff, &x->index, method); + } + + if (strcmp(method, "call")) return; + + ei_get_type(x->buff, &x->index, &etype, &esize); + uwsgi_log("%d %c\n", etype, etype); + + if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ; + + module = uwsgi_malloc(esize); + + if (etype == ERL_ATOM_EXT) { + ei_decode_atom(x->buff, &x->index, module); + } + else { + ei_decode_string(x->buff, &x->index, module); + } + + ei_get_type(x->buff, &x->index, &etype, &esize); + + if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ; + + call = uwsgi_malloc(esize); + + if (etype == ERL_ATOM_EXT) { + ei_decode_atom(x->buff, &x->index, call); + } + else { + ei_decode_string(x->buff, &x->index, call); + } + + uwsgi_log("RPC %s %s\n", module, call); + + ei_get_type(x->buff, &x->index, &etype, &esize); + + if (etype == ERL_ATOM_EXT) { + argc = 1; + argv[0] = uwsgi_malloc(esize+1); + ei_decode_atom(x->buff, &x->index, argv[0]); + } + else if (etype == ERL_STRING_EXT) { + argc = 1; + argv[0] = uwsgi_malloc(esize+1); + ei_decode_string(x->buff, &x->index, argv[0]); + } + + ret = uwsgi_rpc(call, argc, argv, buffer); + + uwsgi_log("buffer: %.*s\n", ret, buffer); + + ei_x_new_with_version(&xr); + + ei_x_encode_tuple_header(&xr, 2); + //ei_x_encode_atom(&xr, "rex"); + ei_x_encode_ref(&xr, &eref); + ei_x_encode_string_len(&xr, buffer, ret); + + uwsgi_log("ei_send to %d %s %d %d %d: %d %d\n", fd, from->node, from->num , from->serial, from->creation, xr.index, ei_send(fd, from, xr.buff, xr.index)); + //uwsgi_log("ei_send to %d %s %d %d %d: %d %d\n", fd, from->node, from->num , from->serial, from->creation, xr.index, ei_reg_send(&uerl.cnode, fd, "rex", xr.buff, xr.index)); + + +} + +void erlang_loop() { + + ErlConnect econn; + //ErlMessage em; + erlang_msg em; + int fd; + + int eversion; + + ei_x_buff x, xr; + + ei_x_new(&x); + ei_x_new(&xr); + + + /* + int fd0 = ei_connect(&uerl.cnode, "anothernode@maverick64"); + uwsgi_log("fd0: %d\n", fd0); + + ei_x_encode_list_header(&x, 0); + + ei_rpc_to(&uerl.cnode, fd0, "erlang", "node", x.buff, x.index); + + ei_rpc_from(&uerl.cnode, fd0, 10000, &em, &xr); + + uwsgi_log("From: %s To: %s RegName: %s\n", em.from.node, em.to.node, em.toname); + + xr.index = 0; + ei_decode_version(xr.buff, &xr.index, &eversion); + uwsgi_log("eversion: %d\n", eversion); + + dump_eterm(&xr); + */ + + for(;;) { + + fd = ei_accept(&uerl.cnode, uerl.fd, &econn); + + if (fd >= 0) { + + for (;;) { + if (ei_xreceive_msg(fd, &em, &x) == ERL_MSG) { + + if (em.msgtype == ERL_TICK) + continue; + + uwsgi_log("From: %s To: %s RegName: %s\n", em.from.node, em.to.node, em.toname); + + + + x.index = 0; + ei_decode_version(x.buff, &x.index, &eversion); + uwsgi_log("eversion: %d\n", eversion); + + if (!strcmp(em.toname, "rex")) { + uwsgi_erlang_rpc(fd, &em.from, &x); + } + else { + dump_eterm(&x); + } + + + +/* + + if (em.msgtype) { + dump_erl_obj(em.msg); + erl_free_compound(em.msg); + } + if (em.to) { + uwsgi_log("*** TO ***\n"); + dump_erl_obj(em.to); + erl_free_compound(em.to); + } + + if (em.from) { + uwsgi_log("*** FROM ***\n"); + dump_erl_obj(em.from); + erl_free_compound(em.from); + } +*/ + + } + else { + break; + } + } + + close(fd); + + } + } +} + +int erlang_init() { + + char *host; + struct sockaddr_in sin; + socklen_t slen = sizeof(struct sockaddr_in); + + if (uerl.name) { + + uwsgi.master_process = 1; + + host = strchr(uerl.name, '@'); + + if (!host) { + if (ei_connect_init(&uerl.cnode, uerl.name, uerl.cookie, 0) < 0) { + uwsgi_log("unable to initialize erlang connection\n"); + exit(1); + } + } + + uerl.fd = bind_to_tcp("", uwsgi.listen_queue, NULL); + if (uerl.fd < 0) { + exit(1); + } + + if (getsockname(uerl.fd, (struct sockaddr *) &sin, &slen)) { + uwsgi_error("getsockname()"); + exit(1); + } + + if (ei_publish(&uerl.cnode, ntohs(sin.sin_port)) < 0) { + uwsgi_log( "*** unable to subscribe with EPMD ***\n"); + exit(1); + } + + uwsgi_log("Erlang C-Node %s registered on port %d\n", ei_thisnodename(&uerl.cnode), ntohs(sin.sin_port)); + + if (register_fat_gateway("erlang", erlang_loop) == NULL) { + uwsgi_log("unable to register the erlang gateway\n"); + exit(1); + } + } + + return 0; +} + +int erlang_opt(int i, char *optarg) { + + switch(i) { + case LONG_ARGS_ERLANG: + uerl.name = optarg; + return 1; + case LONG_ARGS_ERLANG_COOKIE: + uerl.cookie = optarg; + return 1; + } + return 0; +} + + +struct uwsgi_plugin erlang_plugin = { + + .options = erlang_options, + .manage_opt = erlang_opt, + .init = erlang_init, +}; + diff --git a/plugins/erlang/erlang.h b/plugins/erlang/erlang.h new file mode 100644 index 00000000..7817a4b2 --- /dev/null +++ b/plugins/erlang/erlang.h @@ -0,0 +1,17 @@ +#include + +#define LONG_ARGS_ERLANG 17012 +#define LONG_ARGS_ERLANG_COOKIE 17013 + + +struct uwsgi_erlang { + + ei_cnode cnode; + char *name; + char *cookie; + + int fd; + +}; + + diff --git a/plugins/erlang/uwsgiplugin.py b/plugins/erlang/uwsgiplugin.py new file mode 100644 index 00000000..2797e4a6 --- /dev/null +++ b/plugins/erlang/uwsgiplugin.py @@ -0,0 +1,7 @@ + +NAME='erlang' +CFLAGS = [] +LDFLAGS = [] +LIBS = ['-lei'] + +GCC_LIST = ['erlang'] diff --git a/plugins/pyerl/pyerl.c b/plugins/pyerl/pyerl.c new file mode 100644 index 00000000..cf86313c --- /dev/null +++ b/plugins/pyerl/pyerl.c @@ -0,0 +1,135 @@ +#include "../erlang/erlang.h" +#include "../python/uwsgi_python.h" + +extern struct uwsgi_server uwsgi; +extern struct uwsgi_erlang uerl; +extern struct uwsgi_python up; + +ei_cnode *pyerl_cnode; + +PyObject *pyerl_connect(PyObject * self, PyObject * args) { + + Py_INCREF(Py_None); + return Py_None; +} + +int py_to_erl(PyObject *, ei_x_buff*); + +PyObject *pyerl_simple_send(PyObject * self, PyObject * args) { + + char *node; + char *reg; + PyObject *pobj; + ei_x_buff x; + int fd; + + if (!PyArg_ParseTuple(args, "ssO:erlang_simple_send", &node, ®, &pobj)) { + return NULL; + } + + fd = ei_connect(pyerl_cnode, node); + + if (fd < 0) { + return PyErr_Format(PyExc_ValueError, "Unable to connect to erlang node %s", node); + } + + ei_x_new_with_version(&x); + + if (py_to_erl(pobj, &x) < 0) { + ei_x_free(&x); + return PyErr_Format(PyExc_ValueError, "Unsupported object in Python->Erlang translation"); + } + + + ei_reg_send(pyerl_cnode, fd, reg, x.buff, x.index); + + close(fd); + + ei_x_free(&x); + + Py_INCREF(Py_None); + return Py_None; +} + + +static PyMethodDef uwsgi_pyerl_methods[] = { + {"erlang_connect", pyerl_connect, METH_VARARGS, ""}, + {"erlang_simple_send", pyerl_simple_send, METH_VARARGS, ""}, + {NULL, NULL}, +}; + +void py_erl_init_functions() { + + PyMethodDef *uwsgi_function; + + for (uwsgi_function = uwsgi_pyerl_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) { + PyObject *func = PyCFunction_New(uwsgi_function, NULL); + PyDict_SetItemString(up.embedded_dict, uwsgi_function->ml_name, func); + Py_DECREF(func); + } + +} + +int py_to_erl(PyObject *pobj, ei_x_buff *x) { + int i; + PyObject *pobj2; + + if (pobj == NULL || pobj == Py_None) { + ei_x_encode_empty_list(x); + } + else if (PyString_Check(pobj)) { + ei_x_encode_string(x, PyString_AsString(pobj)); + } + else if (PyInt_Check(pobj)) { + ei_x_encode_long(x, PyInt_AsLong(pobj)); + } + else if (PyList_Check(pobj)) { + ei_x_encode_list_header(x, PyList_Size(pobj)); + for (i = 0; i < PyList_Size(pobj); i++) { + pobj2 = PyList_GetItem(pobj, i); + if (py_to_erl(pobj2, x) < 0) return -1; + } + ei_x_encode_empty_list(x); + } + else if (PyTuple_Check(pobj)) { + ei_x_encode_tuple_header(x, PyTuple_Size(pobj)); + for (i = 0; i < PyTuple_Size(pobj); i++) { + pobj2 = PyTuple_GetItem(pobj, i); + if (py_to_erl(pobj2, x) < 0) return -1; + } + } + else { + return -1; + } + + return x->index; +} + + + +void pyerl_init() { + + up.extension = py_erl_init_functions; + + if (!uerl.name) { + pyerl_cnode = uwsgi_malloc(sizeof(ei_cnode)); + memset(pyerl_cnode, 0, sizeof(ei_cnode)); + if (ei_connect_init(pyerl_cnode, "uwsgi", NULL, 0) < 0) { + uwsgi_log("unable to initialize erlang connection\n"); + exit(1); + } + uwsgi_log("Erlang C-Node name: %s\n",ei_thisnodename(pyerl_cnode)); + } + else { + pyerl_cnode = &uerl.cnode; + } + + uwsgi_log("enabled Python<->Erlang bridge\n"); + +} + +struct uwsgi_plugin pyerl_plugin = { + + .post_init = pyerl_init, +}; + diff --git a/plugins/pyerl/uwsgiplugin.py b/plugins/pyerl/uwsgiplugin.py new file mode 100644 index 00000000..161d7223 --- /dev/null +++ b/plugins/pyerl/uwsgiplugin.py @@ -0,0 +1,8 @@ +from distutils import sysconfig + +NAME='pyerl' +CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)] +LDFLAGS = [] +LIBS = [] + +GCC_LIST = ['pyerl'] diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index ad8eda49..df854066 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -91,39 +91,6 @@ int uwsgi_python_init() { uwsgi_log("Python main interpreter initialized at %p\n", up.main_thread); - init_pyargv(); -#ifdef UWSGI_MINTERPRETERS - init_uwsgi_embedded_module(); -#endif - - if (up.test_module != NULL) { - if (PyImport_ImportModule(up.test_module)) { - exit(0); - } - exit(1); - } - - init_uwsgi_vars(); - - // setup app loaders -#ifdef UWSGI_MINTERPRETERS - up.loaders[LOADER_DYN] = uwsgi_dyn_loader; -#endif - up.loaders[LOADER_UWSGI] = uwsgi_uwsgi_loader; - up.loaders[LOADER_FILE] = uwsgi_file_loader; - up.loaders[LOADER_PASTE] = uwsgi_paste_loader; - up.loaders[LOADER_EVAL] = uwsgi_eval_loader; - up.loaders[LOADER_MOUNT] = uwsgi_mount_loader; - up.loaders[LOADER_CALLABLE] = uwsgi_callable_loader; - up.loaders[LOADER_STRING_CALLABLE] = uwsgi_string_callable_loader; - - // by default set a fake GIL (little impact on performance) - up.gil_get = gil_fake_get; - up.gil_release = gil_fake_release; - - up.swap_ts = simple_swap_ts; - up.reset_ts = simple_reset_ts; - return 1; } @@ -451,10 +418,14 @@ void init_uwsgi_embedded_module() { PyErr_Print(); exit(1); } + +/* if (PyDict_SetItemString(up.embedded_dict, "KIND_ERLANG", PyInt_FromLong(KIND_ERLANG))) { PyErr_Print(); exit(1); } +*/ + if (PyDict_SetItemString(up.embedded_dict, "KIND_PROXY", PyInt_FromLong(KIND_PROXY))) { PyErr_Print(); exit(1); @@ -578,6 +549,10 @@ void init_uwsgi_embedded_module() { } init_uwsgi_module_cache(new_uwsgi_module); + + if (up.extension) { + up.extension(); + } } #endif @@ -690,6 +665,40 @@ int uwsgi_python_mount_app(char *mountpoint, char *app) { void uwsgi_python_init_apps() { + init_pyargv(); +#ifdef UWSGI_MINTERPRETERS + init_uwsgi_embedded_module(); +#endif + + if (up.test_module != NULL) { + if (PyImport_ImportModule(up.test_module)) { + exit(0); + } + exit(1); + } + + init_uwsgi_vars(); + + // setup app loaders +#ifdef UWSGI_MINTERPRETERS + up.loaders[LOADER_DYN] = uwsgi_dyn_loader; +#endif + up.loaders[LOADER_UWSGI] = uwsgi_uwsgi_loader; + up.loaders[LOADER_FILE] = uwsgi_file_loader; + up.loaders[LOADER_PASTE] = uwsgi_paste_loader; + up.loaders[LOADER_EVAL] = uwsgi_eval_loader; + up.loaders[LOADER_MOUNT] = uwsgi_mount_loader; + up.loaders[LOADER_CALLABLE] = uwsgi_callable_loader; + up.loaders[LOADER_STRING_CALLABLE] = uwsgi_string_callable_loader; + + // by default set a fake GIL (little impact on performance) + up.gil_get = gil_fake_get; + up.gil_release = gil_fake_release; + + up.swap_ts = simple_swap_ts; + up.reset_ts = simple_reset_ts; + + if (up.wsgi_config != NULL) { init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, up.main_thread); } diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index e4296179..99faef57 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -126,6 +126,8 @@ struct uwsgi_python { char *pymodule_alias[MAX_PYMODULE_ALIAS]; int pymodule_alias_cnt; + + void (*extension)(void); }; diff --git a/socket.c b/socket.c index 4b1f13fb..2b441613 100644 --- a/socket.c +++ b/socket.c @@ -370,11 +370,13 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) { struct sockaddr_in uws_addr; int reuse = 1; - tcp_port[0] = 0; memset(&uws_addr, 0, sizeof(struct sockaddr_in)); uws_addr.sin_family = AF_INET; - uws_addr.sin_port = htons(atoi(tcp_port + 1)); + if (tcp_port) { + tcp_port[0] = 0; + uws_addr.sin_port = htons(atoi(tcp_port + 1)); + } serverfd = socket(AF_INET, SOCK_STREAM, 0); if (serverfd < 0) { @@ -427,8 +429,8 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) { exit(1); } - - tcp_port[0] = ':'; + + if (tcp_port) tcp_port[0] = ':'; return serverfd; } diff --git a/utils.c b/utils.c index fb2d0c53..5cbb0192 100644 --- a/utils.c +++ b/utils.c @@ -1542,3 +1542,13 @@ int is_unix(char *socket_name, int len) { return 1; } + +int is_a_number(char *what) { + int i; + + for(i=0;i<(int)strlen(what);i++) { + if (!isdigit(what[i])) return 0; + } + + return 1; +} diff --git a/uwsgi.c b/uwsgi.c index 85173216..cbc2878e 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -1333,8 +1333,8 @@ int uwsgi_start(void *v_argv) { } - // initialize request plugin only if workers are available - if (uwsgi.sockets_cnt) { + // initialize request plugin only if workers or master are available + if (uwsgi.sockets_cnt || uwsgi.master_process) { for (i = 0; i < 0xFF; i++) { if (uwsgi.p[i]->init) { uwsgi.p[i]->init(); @@ -1343,6 +1343,19 @@ int uwsgi_start(void *v_argv) { } + /* gp/plugin initialization */ + for(i =0; i < uwsgi.gp_cnt; i++) { + if (uwsgi.gp[i]->post_init) { + uwsgi.gp[i]->post_init(); + } + } + + for(i =0; i < 0xff; i++) { + if (uwsgi.p[i]->post_init) { + uwsgi.p[i]->post_init(); + } + } + uwsgi.current_wsgi_req = simple_current_wsgi_req; @@ -1486,13 +1499,6 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100 uwsgi_rawlog(" ***\n"); -#ifdef UWSGI_ERLANG - if (uwsgi.erlang_node) { - uwsgi.erlang_nodes = 1; - uwsgi.erlangfd = init_erlang(uwsgi.erlang_node, uwsgi.erlang_cookie); - } -#endif - #ifdef UWSGI_SNMP if (uwsgi.snmp) { //snmp_init(); @@ -1506,7 +1512,6 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100 } } - /*parse xml for tags */ #ifdef UWSGI_XML if (uwsgi.xml_round2 && uwsgi.xml_config != NULL) { @@ -1683,20 +1688,6 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100 } } -#ifdef UWSGI_ERLANG - if (uwsgi.erlang_nodes > 0) { - if (uwsgi.numproc <= uwsgi.erlang_nodes) { - uwsgi_log("You do not have enough worker for Erlang. Please respawn with at least %d processes.\n", uwsgi.erlang_nodes + 1); - } else if (uwsgi.mywid > (uwsgi.numproc - uwsgi.erlang_nodes)) { - uwsgi_log("Erlang mode enabled for worker %d.\n", uwsgi.mywid); - erlang_loop(uwsgi.wsgi_req); - //NEVER HERE - exit(1); - } - } - close(uwsgi.erlangfd); -#endif - #ifdef UWSGI_ASYNC uwsgi.async_running = -1; #endif diff --git a/uwsgi.h b/uwsgi.h index 3d7c70dc..a2485765 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -258,8 +258,6 @@ struct uwsgi_opt { #define LONG_ARGS_LIMIT_AS 17009 #define LONG_ARGS_UDP 17010 #define LONG_ARGS_WSGI_FILE 17011 -#define LONG_ARGS_ERLANG 17012 -#define LONG_ARGS_ERLANG_COOKIE 17013 #define LONG_ARGS_BINARY_PATH 17014 #define LONG_ARGS_PROXY 17015 #define LONG_ARGS_PROXY_NODE 17016 @@ -345,11 +343,6 @@ struct uwsgi_opt { #define UWSGI_SET_LOCKING uwsgi.workers[uwsgi.mywid].status |= UWSGI_STATUS_LOCKING #define UWSGI_UNSET_LOCKING uwsgi.workers[uwsgi.mywid].status ^= UWSGI_STATUS_LOCKING -#define UWSGI_STATUS_ERLANGING 1 << 3 -#define UWSGI_IS_ERLANGING uwsgi.workers[uwsgi.mywid].status & UWSGI_STATUS_ERLANGING -#define UWSGI_SET_ERLANGING uwsgi.workers[uwsgi.mywid].status |= UWSGI_STATUS_ERLANGING -#define UWSGI_UNSET_ERLANGING uwsgi.workers[uwsgi.mywid].status ^= UWSGI_STATUS_ERLANGING - #ifdef __linux__ #include #elif __sun__ @@ -426,6 +419,7 @@ struct uwsgi_plugin { uint8_t modifier1; void *data; int (*init) (void); + void (*post_init) (void); void (*post_fork) (void); struct option *options; const char *short_options; @@ -751,11 +745,6 @@ struct uwsgi_server { char *spool_dir; #endif -#ifdef UWSGI_ERLANG - char *erlang_node; - char *erlang_cookie; -#endif - #ifdef UWSGI_NAGIOS int nagios; #endif @@ -850,11 +839,6 @@ struct uwsgi_server { struct uwsgi_app apps[MAX_APPS]; -#ifdef UWSGI_ERLANG - int erlang_nodes; - int erlangfd; -#endif - int no_orphans; char *chdir; @@ -959,7 +943,6 @@ struct uwsgi_lb_group { #define KIND_WORKER 1 #define KIND_EVENT 2 #define KIND_SPOOLER 3 -#define KIND_ERLANG 4 #define KIND_PROXY 5 #define KIND_MASTER 6 @@ -1173,16 +1156,6 @@ int uwsgi_parse_vars(struct wsgi_request *); int uwsgi_enqueue_message(char *, int, uint8_t, uint8_t, char *, int, int); -#ifdef UWSGI_ERLANG - -#include -#include - -int init_erlang(char *, char *); -void erlang_loop(struct wsgi_request *); - -#endif - void manage_opt(int, char *); void uwsgi_cluster_add_node(struct uwsgi_cluster_node *, int); @@ -1429,6 +1402,7 @@ int uwsgi_parse_array(char *, uint16_t, char **, uint8_t *); void log_syslog(char *); struct uwsgi_gateway *register_gateway(char *, void (*)(void)); +struct uwsgi_gateway *register_fat_gateway(char *, void (*)(void)); void gateway_respawn(int); char *uwsgi_open_and_read(char *, int *, int, char *[]); @@ -1465,3 +1439,4 @@ int uwsgi_simple_send_string2(char *, uint8_t, uint8_t, char *, uint16_t, char * int uwsgi_simple_send_string(char *, uint8_t, uint8_t, char *, uint16_t, int); int is_unix(char *, int); +int is_a_number(char *); diff --git a/uwsgiconfig.py b/uwsgiconfig.py index de823582..a65e2353 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -420,12 +420,6 @@ class uConf(object): self.gcc_list.append('xmlconf') - if self.get('erlang'): - self.depends_on("erlang", ['embedded']) - self.cflags.append("-DUWSGI_ERLANG") - self.libs.append(os.environ['ERLANG_LDFLAGS']) - self.gcc_list.append('erlang') - if self.get('plugin_dir'): self.cflags.append('-DUWSGI_PLUGIN_DIR=\\"%s\\"' % self.get('plugin_dir'))