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 = '
| id | mountpoint | requests |
'
+ for app in w['apps']:
+ apps += '| %d | %s | %d |
' % (app['id'], app['mountpoint'], app['requests'])
+ apps += '
'
+ 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
+
+
+ """ % (uwsgi.version, workers)