diff --git a/buildconf/default.ini b/buildconf/default.ini index 7ee7e857..1d1a1f29 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -4,10 +4,10 @@ ini = true snmp = true sctp = false erlang = false -spooler = false -embedded = false +spooler = true +embedded = true udp = true -multicast = false +multicast = true threading = true sendfile = true nagios = true diff --git a/master.c b/master.c index 2a260207..7e24c546 100644 --- a/master.c +++ b/master.c @@ -368,7 +368,7 @@ void master_loop(char **argv, char **environ) { if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { if (diedpid == uwsgi.shared->spooler_pid) { uwsgi_log( "OOOPS the spooler is no more...trying respawn...\n"); - uwsgi.shared->spooler_pid = spooler_start(uwsgi.embedded_dict); + uwsgi.shared->spooler_pid = spooler_start(); continue; } } diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 7008e081..3458877d 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -94,6 +94,11 @@ int uwsgi_python_init() { up.main_thread = PyThreadState_Get(); + +#ifdef UWSGI_MINTERPRETERS + init_uwsgi_embedded_module(); +#endif + if (up.test_module != NULL) { if (PyImport_ImportModule(up.test_module)) { exit(0); @@ -375,11 +380,11 @@ void init_uwsgi_embedded_module() { int i; /* initialize for stats */ - uwsgi.workers_tuple = PyTuple_New(uwsgi.numproc); + up.workers_tuple = PyTuple_New(uwsgi.numproc); for (i = 0; i < uwsgi.numproc; i++) { zero = PyDict_New(); Py_INCREF(zero); - PyTuple_SetItem(uwsgi.workers_tuple, i, zero); + PyTuple_SetItem(up.workers_tuple, i, zero); } @@ -395,103 +400,103 @@ void init_uwsgi_embedded_module() { exit(1); } - uwsgi.embedded_dict = PyModule_GetDict(new_uwsgi_module); - if (!uwsgi.embedded_dict) { + up.embedded_dict = PyModule_GetDict(new_uwsgi_module); + if (!up.embedded_dict) { uwsgi_log( "could not get uwsgi module __dict__\n"); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "version", PyString_FromString(UWSGI_VERSION))) { + if (PyDict_SetItemString(up.embedded_dict, "version", PyString_FromString(UWSGI_VERSION))) { PyErr_Print(); exit(1); } if (uwsgi.mode) { - if (PyDict_SetItemString(uwsgi.embedded_dict, "mode", PyString_FromString(uwsgi.mode))) { + if (PyDict_SetItemString(up.embedded_dict, "mode", PyString_FromString(uwsgi.mode))) { PyErr_Print(); exit(1); } } if (uwsgi.pidfile) { - if (PyDict_SetItemString(uwsgi.embedded_dict, "pidfile", PyString_FromString(uwsgi.pidfile))) { + if (PyDict_SetItemString(up.embedded_dict, "pidfile", PyString_FromString(uwsgi.pidfile))) { PyErr_Print(); exit(1); } } - if (PyDict_SetItemString(uwsgi.embedded_dict, "SPOOL_RETRY", PyInt_FromLong(17))) { + if (PyDict_SetItemString(up.embedded_dict, "SPOOL_RETRY", PyInt_FromLong(17))) { PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "numproc", PyInt_FromLong(uwsgi.numproc))) { + if (PyDict_SetItemString(up.embedded_dict, "numproc", PyInt_FromLong(uwsgi.numproc))) { PyErr_Print(); exit(1); } #ifdef UNBIT - if (PyDict_SetItemString(uwsgi.embedded_dict, "unbit", Py_True)) { + if (PyDict_SetItemString(up.embedded_dict, "unbit", Py_True)) { #else - if (PyDict_SetItemString(uwsgi.embedded_dict, "unbit", Py_None)) { + if (PyDict_SetItemString(up.embedded_dict, "unbit", Py_None)) { #endif PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "buffer_size", PyInt_FromLong(uwsgi.buffer_size))) { + if (PyDict_SetItemString(up.embedded_dict, "buffer_size", PyInt_FromLong(uwsgi.buffer_size))) { PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "started_on", PyInt_FromLong(uwsgi.start_tv.tv_sec))) { + if (PyDict_SetItemString(up.embedded_dict, "started_on", PyInt_FromLong(uwsgi.start_tv.tv_sec))) { PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "start_response", up.wsgi_spitout)) { + if (PyDict_SetItemString(up.embedded_dict, "start_response", up.wsgi_spitout)) { PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "fastfuncs", PyList_New(256))) { + if (PyDict_SetItemString(up.embedded_dict, "fastfuncs", PyList_New(256))) { PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "applications", Py_None)) { + if (PyDict_SetItemString(up.embedded_dict, "applications", Py_None)) { PyErr_Print(); exit(1); } if (uwsgi.is_a_reload) { - if (PyDict_SetItemString(uwsgi.embedded_dict, "is_a_reload", Py_True)) { + if (PyDict_SetItemString(up.embedded_dict, "is_a_reload", Py_True)) { PyErr_Print(); exit(1); } } else { - if (PyDict_SetItemString(uwsgi.embedded_dict, "is_a_reload", Py_False)) { + if (PyDict_SetItemString(up.embedded_dict, "is_a_reload", Py_False)) { PyErr_Print(); exit(1); } } - uwsgi.embedded_args = PyTuple_New(2); - if (!uwsgi.embedded_args) { + up.embedded_args = PyTuple_New(2); + if (!up.embedded_args) { PyErr_Print(); exit(1); } - if (PyDict_SetItemString(uwsgi.embedded_dict, "message_manager_marshal", Py_None)) { + if (PyDict_SetItemString(up.embedded_dict, "message_manager_marshal", Py_None)) { PyErr_Print(); exit(1); } - uwsgi.fastfuncslist = PyDict_GetItemString(uwsgi.embedded_dict, "fastfuncs"); - if (!uwsgi.fastfuncslist) { + up.fastfuncslist = PyDict_GetItemString(up.embedded_dict, "fastfuncs"); + if (!up.fastfuncslist) { PyErr_Print(); exit(1); } @@ -641,6 +646,7 @@ struct uwsgi_plugin python_plugin = { .enable_threads = uwsgi_python_enable_threads, .init_thread = uwsgi_python_init_thread, .manage_xml = uwsgi_python_xml, + //.spooler = uwsgi_python_spooler, /* .magic = uwsgi_python_magic, .help = uwsgi_python_help, diff --git a/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c similarity index 99% rename from uwsgi_pymodule.c rename to plugins/python/uwsgi_pymodule.c index f3327c62..e1253ae6 100644 --- a/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1,10 +1,11 @@ #ifdef UWSGI_EMBEDDED -#include "uwsgi.h" +#include "uwsgi_python.h" char *spool_buffer = NULL; extern struct uwsgi_server uwsgi; +extern struct uwsgi_python up; #ifdef __APPLE__ #define UWSGI_LOCK OSSpinLockLock((OSSpinLock *) uwsgi.sharedareamutex); @@ -753,10 +754,12 @@ PyObject *py_uwsgi_has_hook(PyObject * self, PyObject * args) { return NULL; } + /* if (uwsgi.shared->hooks[modifier1] != unconfigured_hook) { Py_INCREF(Py_True); return Py_True; } + */ Py_INCREF(Py_None); return Py_None; @@ -772,13 +775,14 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) { int arg_modifier2 = 0; int arg_timeout = 0; - PyObject *marshalled; - PyObject *retobject; + //PyObject *marshalled; + //PyObject *retobject; if (!PyArg_ParseTuple(args, "siiiO|i:send_uwsgi_message", &arg_host, &arg_port, &arg_modifier1, &arg_modifier2, &arg_message, &arg_timeout)) { return NULL; } + /* switch (arg_modifier1) { case UWSGI_MODIFIER_MESSAGE_MARSHAL: marshalled = PyMarshal_WriteObjectToString(arg_message, 1); @@ -813,6 +817,7 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) { break; } + */ Py_INCREF(Py_None); return Py_None; @@ -839,7 +844,7 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) { int i; for (i = 0; i < uwsgi.numproc; i++) { - worker_dict = PyTuple_GetItem(uwsgi.workers_tuple, i); + worker_dict = PyTuple_GetItem(up.workers_tuple, i); if (!worker_dict) { goto clear; } @@ -906,8 +911,8 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) { } - Py_INCREF(uwsgi.workers_tuple); - return uwsgi.workers_tuple; + Py_INCREF(up.workers_tuple); + return up.workers_tuple; clear: PyErr_Print(); diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index 276d2fec..836c5bc7 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -87,6 +87,11 @@ struct uwsgi_python { void (*gil_get) (void); void (*gil_release) (void); #endif + + PyObject *workers_tuple; + PyObject *embedded_dict; + PyObject *embedded_args; + PyObject *fastfuncslist; }; @@ -167,3 +172,7 @@ void gil_real_get(void); void gil_real_release(void); void gil_fake_get(void); void gil_fake_release(void); + +void init_uwsgi_module_advanced(PyObject *); +void init_uwsgi_module_spooler(PyObject *); +void init_uwsgi_module_sharedarea(PyObject *); diff --git a/plugins/python/uwsgiplugin.py b/plugins/python/uwsgiplugin.py index 0061fb4b..4e2174e1 100644 --- a/plugins/python/uwsgiplugin.py +++ b/plugins/python/uwsgiplugin.py @@ -3,7 +3,7 @@ import os,sys from distutils import sysconfig NAME='python' -GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil'] +GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule'] CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ] LDFLAGS = [] diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index 03f489ec..53bebb5b 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -7,18 +7,25 @@ extern struct uwsgi_server uwsgi; #define LONG_ARGS_RAILS 18001 #define LONG_ARGS_RUBY_GC_FREQ 18002 +#define LONG_ARGS_RACK 18003 struct uwsgi_rack { char *rails; + char *rack; int gc_freq; uint64_t cycles; + VALUE dispatcher; + VALUE rb_uwsgi_io_class; + ID call; + } ur; struct option uwsgi_rack_options[] = { {"rails", required_argument, 0, LONG_ARGS_RAILS}, + {"rack", required_argument, 0, LONG_ARGS_RACK}, {"ruby-gc-freq", required_argument, 0, LONG_ARGS_RUBY_GC_FREQ}, {0, 0, 0, 0}, @@ -75,9 +82,6 @@ static struct http_status_codes hsc[] = { }; -VALUE dispatcher; -VALUE rb_uwsgi_io_class; -ID call; VALUE rb_uwsgi_io_new(VALUE class, VALUE wr) { @@ -248,10 +252,33 @@ int uwsgi_rack_init(){ } ruby_init(); - ruby_init_loadpath(); ruby_script("uwsgi"); + ruby_init_loadpath(); - if (ur.rails) { + if (ur.rack) { + rb_require("rubygems"); + rb_funcall( rb_cObject, rb_intern("require"), 1, rb_str_new2("rack") ); + + VALUE rack = rb_const_get(rb_cObject, rb_intern("Rack")) ; + VALUE rackup = rb_funcall( rb_const_get(rack, rb_intern("Builder")), rb_intern("parse_file"), 1, rb_str_new2(ur.rack)); + if (TYPE(rackup) != T_ARRAY) { + uwsgi_log("unable to parse %s file\n", ur.rack); + exit(1); + } + + if (RARRAY(rackup)->len < 1) { + uwsgi_log("invalid rack config file: %s\n", ur.rack); + exit(1); + } + + ur.dispatcher = RARRAY(rackup)->ptr[0] ; + + if (ur.dispatcher == Qnil) { + exit(1); + } + + } + else if (ur.rails) { if (chdir(ur.rails)) { uwsgi_error("chdir()"); exit(1); @@ -262,40 +289,40 @@ int uwsgi_rack_init(){ uwsgi_log("rails app %s ready\n", ur.rails); VALUE ac = rb_const_get(rb_cObject, rb_intern("ActionController")) ; - dispatcher = rb_funcall( rb_const_get(ac, rb_intern("Dispatcher")), rb_intern("new"), 0); + ur.dispatcher = rb_funcall( rb_const_get(ac, rb_intern("Dispatcher")), rb_intern("new"), 0); - if (dispatcher == Qnil) { + if (ur.dispatcher == Qnil) { uwsgi_log("unable to load rails dispatcher\n"); exit(1); } - - rb_gc_register_address(&dispatcher); - - call = rb_intern("call"); - rb_gc_register_address(&call); - - - rb_uwsgi_io_class = rb_define_class("Uwsgi_IO", rb_cObject); - - rb_gc_register_address(&rb_uwsgi_io_class); - - rb_define_singleton_method(rb_uwsgi_io_class, "new", rb_uwsgi_io_new, 1); - rb_define_method(rb_uwsgi_io_class, "initialize", rb_uwsgi_io_init, -1); - rb_define_method(rb_uwsgi_io_class, "gets", rb_uwsgi_io_gets, 0); - rb_define_method(rb_uwsgi_io_class, "each", rb_uwsgi_io_each, 0); - rb_define_method(rb_uwsgi_io_class, "read", rb_uwsgi_io_read, -2); - rb_define_method(rb_uwsgi_io_class, "rewind", rb_uwsgi_io_rewind, 0); - - //rb_gc_disable(); } + rb_gc_register_address(&ur.dispatcher); + + ur.call = rb_intern("call"); + rb_gc_register_address(&ur.call); + + + ur.rb_uwsgi_io_class = rb_define_class("Uwsgi_IO", rb_cObject); + + rb_gc_register_address(&ur.rb_uwsgi_io_class); + + rb_define_singleton_method(ur.rb_uwsgi_io_class, "new", rb_uwsgi_io_new, 1); + rb_define_method(ur.rb_uwsgi_io_class, "initialize", rb_uwsgi_io_init, -1); + rb_define_method(ur.rb_uwsgi_io_class, "gets", rb_uwsgi_io_gets, 0); + rb_define_method(ur.rb_uwsgi_io_class, "each", rb_uwsgi_io_each, 0); + rb_define_method(ur.rb_uwsgi_io_class, "read", rb_uwsgi_io_read, -2); + rb_define_method(ur.rb_uwsgi_io_class, "rewind", rb_uwsgi_io_rewind, 0); + + //rb_gc_disable(); + return 0; } VALUE call_dispatch(VALUE env) { - return rb_funcall(dispatcher, call, 1, env); + return rb_funcall(ur.dispatcher, ur.call, 1, env); } @@ -379,8 +406,18 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) { // fill ruby hash for(i=0;ivar_cnt;i++) { - rb_hash_aset(env, rb_str_new(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len), - rb_str_new(wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len)); + // put the var only if it is not 0 size or required (rack requirement... very inefficient) + if (wsgi_req->hvec[i+1].iov_len > 0 || + !uwsgi_strncmp("REQUEST_METHOD", 14, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len) || + !uwsgi_strncmp("SCRIPT_NAME", 11, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len) || + !uwsgi_strncmp("PATH_INFO", 10, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len) || + !uwsgi_strncmp("QUERY_STRING", 12, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len) || + !uwsgi_strncmp("SERVER_NAME", 11, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len) || + !uwsgi_strncmp("SERVER_PORT", 11, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len) + ) { + rb_hash_aset(env, rb_str_new(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len), + rb_str_new(wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len)); + } i++; } @@ -395,8 +432,10 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) { rb_hash_aset(env, rb_str_new2("rack.multiprocess"), Qtrue); rb_hash_aset(env, rb_str_new2("rack.run_once"), Qfalse); - VALUE dws_wr = Data_Wrap_Struct(rb_uwsgi_io_class, 0, 0, wsgi_req); - rb_hash_aset(env, rb_str_new2("rack.input"), rb_funcall(rb_uwsgi_io_class, rb_intern("new"), 1, dws_wr )); + VALUE dws_wr = Data_Wrap_Struct(ur.rb_uwsgi_io_class, 0, 0, wsgi_req); + rb_hash_aset(env, rb_str_new2("rack.input"), rb_funcall(ur.rb_uwsgi_io_class, rb_intern("new"), 1, dws_wr )); + + rb_hash_aset(env, rb_str_new2("rack.errors"), rb_funcall( rb_const_get(rb_cObject, rb_intern("IO")), rb_intern("new"), 2, INT2NUM(2), rb_str_new("w",1) )); VALUE ret = rb_protect( call_dispatch, env, &error); @@ -460,7 +499,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) { if (rb_respond_to( body, rb_intern("to_path") )) { VALUE sendfile_path = rb_funcall( body, rb_intern("to_path"), 0); - uwsgi_log("BODY respond_to 'to_path' %s !!!\n", RSTRING_PTR(sendfile_path)); wsgi_req->sendfile_fd = open(RSTRING_PTR(sendfile_path), O_RDONLY); wsgi_req->response_size = uwsgi_sendfile(wsgi_req); rb_gc_unregister_address(&sendfile_path); @@ -513,6 +551,9 @@ int uwsgi_rack_manage_options(int i, char *optarg) { case LONG_ARGS_RAILS: ur.rails = optarg; return 1; + case LONG_ARGS_RACK: + ur.rack = optarg; + return 1; case LONG_ARGS_RUBY_GC_FREQ: ur.gc_freq = atoi(optarg); return 1; diff --git a/spooler.c b/spooler.c index 75547fc2..44f79a98 100644 --- a/spooler.c +++ b/spooler.c @@ -16,7 +16,7 @@ pid_t spooler_start() { for(i=0;i 0) { uwsgi_log( "spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid); @@ -96,7 +96,9 @@ int spool_request(char *filename, int rn, char *buffer, int size) { void spooler() { DIR *sdir; struct dirent *dp; - PyObject *spooler_callable, *spool_result, *spool_tuple, *spool_env; + + //PyObject *spooler_callable, *spool_result, *spool_tuple, *spool_env; + int spool_fd; uint16_t uwstrlen; int rlen = 0; @@ -110,6 +112,7 @@ void spooler() { char *key; char *val; + /* spool_tuple = PyTuple_New(1); if (!spool_tuple) { @@ -128,6 +131,7 @@ void spooler() { PyErr_Print(); exit(1); } + */ if (chdir(uwsgi.spool_dir)) { uwsgi_error("chdir()"); @@ -173,11 +177,13 @@ void spooler() { if (!access(dp->d_name, R_OK | W_OK)) { uwsgi_log( "managing spool request %s ...\n", dp->d_name); + /* spooler_callable = PyDict_GetItemString(uwsgi.embedded_dict, "spooler"); if (!spooler_callable) { uwsgi_log( "you have to define uwsgi.spooler to use the spooler !!!\n"); continue; } + */ spool_fd = open(dp->d_name, O_RDONLY); if (spool_fd < 0) { @@ -260,12 +266,14 @@ void spooler() { /* ready to add item to the dict */ } + /* if (PyDict_SetItemString(spool_env, key, PyString_FromStringAndSize(val, uwstrlen))) { PyErr_Print(); free(key); free(val); goto retry_later; } + */ free(key); free(val); @@ -276,6 +284,7 @@ void spooler() { } + /* spool_result = python_call(spooler_callable, spool_tuple, 0); if (!spool_result) { PyErr_Print(); @@ -291,6 +300,7 @@ void spooler() { } Py_DECREF(spool_result); + */ uwsgi_log( "done with task/spool %s\n", dp->d_name); next_spool: @@ -301,7 +311,7 @@ void spooler() { exit(1); } retry_later: - PyDict_Clear(spool_env); + //PyDict_Clear(spool_env); close(spool_fd); } } diff --git a/uwsgi.h b/uwsgi.h index ecdf3cab..efa7747c 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -79,6 +79,9 @@ #ifdef __linux #include + #include +#else + #include #endif #ifdef UWSGI_SCTP diff --git a/uwsgiconfig.py b/uwsgiconfig.py index a26f15d4..ea166f1a 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -191,7 +191,6 @@ class uConf(): if self.get('embedded'): self.cflags.append('-DUWSGI_EMBEDDED') - self.gcc_list.append('uwsgi_pymodule') if self.get('udp'): self.cflags.append("-DUWSGI_UDP")