From a23ba653da080f4809cfa5f39d781b0b21a3dacd Mon Sep 17 00:00:00 2001 From: "roberto@debian32" Date: Fri, 16 Sep 2011 07:46:45 +0200 Subject: [PATCH] better shared sockets support --- plugins/python/uwsgi_pymodule.c | 6 ++++++ plugins/rack/rack_plugin.c | 6 ++++++ plugins/rack/uwsgi_rack.h | 3 +++ socket.c | 37 +++++++++++++++++++++++++++++++++ utils.c | 10 ++++++++- uwsgi.c | 18 ++++++++++++++++ uwsgi.h | 5 +++++ welcome.py | 23 +++++++++++++++++++- 8 files changed, 106 insertions(+), 2 deletions(-) diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 1223fb86..d9c940da 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -2242,6 +2242,12 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) { } Py_DECREF(zero); + zero = PyLong_FromLong(uwsgi.workers[i + 1].tx); + if (PyDict_SetItemString(worker_dict, "tx", zero)) { + goto clear; + } + Py_DECREF(zero); + /* return a tuple of current status ! (in_request, blocking, locking, ) zero = PyLong_FromLong(uwsgi.workers[i+1].in_request); diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index 19c97f11..0830d482 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -9,6 +9,7 @@ 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}, + {"rbshell", optional_argument, 0, LONG_ARGS_RUBY_SHELL}, {0, 0, 0, 0}, @@ -920,6 +921,9 @@ int uwsgi_rack_mount_app(char *mountpoint, char *app) { } */ +void uwsgi_rack_hijack(void) { +} + struct uwsgi_plugin rack_plugin = { .name = "rack", @@ -932,6 +936,8 @@ struct uwsgi_plugin rack_plugin = { .signal_handler = uwsgi_rack_signal_handler, + .hijack = uwsgi_rack_hijack, + .init_apps = uwsgi_rack_init_apps, //.mount_app = uwsgi_rack_mount_app, .manage_xml = uwsgi_rack_xml, diff --git a/plugins/rack/uwsgi_rack.h b/plugins/rack/uwsgi_rack.h index b62c31b6..10964eb5 100644 --- a/plugins/rack/uwsgi_rack.h +++ b/plugins/rack/uwsgi_rack.h @@ -6,6 +6,7 @@ #define LONG_ARGS_RAILS LONG_ARGS_RACK_BASE + 1 #define LONG_ARGS_RUBY_GC_FREQ LONG_ARGS_RACK_BASE + 2 #define LONG_ARGS_RACK LONG_ARGS_RACK_BASE + 3 +#define LONG_ARGS_RUBY_SHELL LONG_ARGS_RACK_BASE + 4 #ifndef RUBY19 #define rb_errinfo() ruby_errinfo @@ -59,6 +60,8 @@ struct uwsgi_rack { pthread_mutex_t gvl; + int rb_shell; + }; void uwsgi_ruby_exception(void); diff --git a/socket.c b/socket.c index de88899e..9f9c75c1 100644 --- a/socket.c +++ b/socket.c @@ -755,6 +755,20 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) { if (!name) return uwsgi_sock; + if (name[0] == '=') { + int shared_socket = atoi(uwsgi_sock->name+1); + if (shared_socket >= 0) { + struct uwsgi_socket *uss = uwsgi_get_shared_socket_by_num(shared_socket); + if (!uss) { + uwsgi_log("unable to use shared socket %d\n", shared_socket); + exit(1); + } + uwsgi_sock->bound = 1; + uwsgi_sock->shared = 1; + uwsgi_sock->from_shared = shared_socket; + return uwsgi_sock; + } + } char *tcp_port = strchr(name, ':'); if (tcp_port) { // INET socket, check for 0 port @@ -957,6 +971,29 @@ int uwsgi_get_shared_socket_fd_by_num(int num) { return -1; } +struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int num) { + + int counter = 0; + + struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.shared_sockets; + + while(uwsgi_sock) { + if (counter == num) { + found_sock = uwsgi_sock; + break; + } + counter++; + uwsgi_sock = uwsgi_sock->next; + } + + if (found_sock) { + return found_sock; + } + + return NULL; +} + + void uwsgi_add_sockets_to_queue(int queue) { struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; diff --git a/utils.c b/utils.c index 5b8af798..1fa1d033 100644 --- a/utils.c +++ b/utils.c @@ -620,7 +620,7 @@ void uwsgi_as_root() { } if (!getuid()) { - uwsgi_log(" *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n"); + uwsgi_log("*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n"); } } else { @@ -694,6 +694,14 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { set_harakiri(0); } + // this is racy in multithread mode + if (wsgi_req->response_size > 0) { + uwsgi.workers[uwsgi.mywid].tx += wsgi_req->response_size; + } + if (wsgi_req->headers_size > 0) { + uwsgi.workers[uwsgi.mywid].tx += wsgi_req->headers_size; + } + // defunct process reaper if (uwsgi.shared->options[UWSGI_OPTION_REAPER] == 1 || uwsgi.grunt) { while (waitpid(WAIT_ANY, &waitpid_status, WNOHANG) > 0); diff --git a/uwsgi.c b/uwsgi.c index 2c8e1f74..3f0809c4 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -1396,6 +1396,24 @@ int main(int argc, char *argv[], char *envp[]) { shared_sock = shared_sock->next; } + struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; + while(uwsgi_sock) { + + if (uwsgi_sock->shared) { + shared_sock = uwsgi_get_shared_socket_by_num(uwsgi_sock->from_shared); + if (!shared_sock) { + uwsgi_log("unable to find shared socket %d\n", uwsgi_sock->from_shared); + exit(1); + } + uwsgi_sock->fd = shared_sock->fd; + uwsgi_sock->family = shared_sock->family; + uwsgi_sock->name = shared_sock->name; + uwsgi_log("uwsgi socket %d mapped to shared socket %d (%s)\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_get_shared_socket_num(shared_sock), shared_sock->name); + } + + uwsgi_sock = uwsgi_sock->next; + } + // start the Emperor if needed if (uwsgi.early_emperor && uwsgi.emperor_dir) { diff --git a/uwsgi.h b/uwsgi.h index fcf7f2f6..cb4e876a 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -604,6 +604,8 @@ struct uwsgi_socket { int disabled; struct uwsgi_socket *next; + int shared; + int from_shared; }; struct uwsgi_server; @@ -1575,6 +1577,8 @@ struct uwsgi_worker { int apps_cnt; struct uwsgi_app apps[MAX_APPS]; + uint64_t tx; + }; @@ -2153,6 +2157,7 @@ socklen_t socket_to_in_addr(char *, char *, struct sockaddr_in *); socklen_t socket_to_un_addr(char *, struct sockaddr_un *); int uwsgi_get_shared_socket_fd_by_num(int); +struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int); int uwsgi_get_shared_socket_num(struct uwsgi_socket *); diff --git a/welcome.py b/welcome.py index 75a48004..a16d83af 100644 --- a/welcome.py +++ b/welcome.py @@ -45,6 +45,18 @@ def application(env, start_response): print len(gc.get_objects()) + workers = '' + for w in uwsgi.workers(): + apps = '' + for app in w['apps']: + apps += '' % (app['id'], app['mountpoint'], app['requests']) + apps += '
idmountpointrequests
%d%s%d
' + workers += """ + +%d%d%d%s + + """ % (w['id'], w['pid'], w['tx'], apps) + return """ version %s

@@ -57,7 +69,16 @@ Configuration
Dynamic options

- """ % (uwsgi.version) +
+Workers and applications
+ + + + +%s +
widpidtxapps
+ + """ % (uwsgi.version, workers)