Hello community,

here is the log from the commit of package uwsgi for openSUSE:Factory checked 
in at 2015-11-12 19:40:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/uwsgi (Old)
 and      /work/SRC/openSUSE:Factory/.uwsgi.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "uwsgi"

Changes:
--------
--- /work/SRC/openSUSE:Factory/uwsgi/uwsgi.changes      2015-08-19 
09:29:26.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.uwsgi.new/uwsgi.changes 2015-11-12 
19:41:00.000000000 +0100
@@ -1,0 +2,46 @@
+Sat Sep 26 17:39:41 UTC 2015 - [email protected]
+
+- Remove uwsgi-2.0.10-gcc5.patch as it was integrated upstream
+- Update to 2.0.11.1:
+  * Bugfixes
+    * fixed HTTPS router resource deallocation and fiel descriptors leak
+    * do not spit out ssl errors when errno is 0
+  * New Features
+    * The unix_signal hook - You can now remap UNIX signals to specific
+      functions symbols
+- Changes from 2.0.11:
+  * Bugfixes
+    * [pypy] fixed misuse of ffi.string
+    * fixed detection for gcc 5 (jimfunk)
+    * fixed shared sockets for gateways
+    * [psgi] Changed abs to labs because offset is declared as a long (Peter H.
+      Ezetta)
+    * add null terminator to uwsgi_get_dot_h() and uwsgi_config_py() (Jay
+      Oster)
+    * fixed thread waiting during stop/restart (Kaiwen Xu)
+    * fixed chain reloading verbosity
+    * [python] fixed spooler job reference counting (Curtis Maloney)
+    * various static analysis improvements (Riccardo Magliocchetti)
+    * fixed sharedarea support for very big ranges
+    * fixed gzip transformation for zero-sized responses (Curtis Maloney)
+    * fixed management of https client certificate authentication (Vladimir
+      Didenko)
+    * fixed OpenBSD build
+    * fixed TMPFILE permissions
+  * New Features
+    * The mem_collector thread - Evil memory monitors (like 
--evil-reload-on-rss)
+      are now asynchronously managed by a dedicated thread. This solves the 
issue
+      of runaway processes not catched by the master.
+    * fixpathinfo routing action - This is another step in removing the need of
+      the infamous uwsgi_modifier1 30 relic.
+    * uwsgi[sor] and time[micros] routing vars - This two new vars exposes the
+      start of the current request (in micros) and the current time (again in
+      micros)
+    * wait-for-socket - This works like wait-for-fs/iface/file/dir. The spawn
+      of the instance is suspended until the specified tcp/unix socket is
+      ready. You can use it to synchronize vassals spawn (like stopping a
+      vassal until a postgresql server has been spawned)
+    * wait_for hooks - All of the wait-for-* functions can now be used as a
+      hook
+
+-------------------------------------------------------------------

Old:
----
  debian.tar.gz
  uwsgi-2.0.10-gcc5.patch
  uwsgi-2.0.10.tar.gz
  uwsgi.dsc

New:
----
  uwsgi-2.0.11.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ uwsgi.spec ++++++
--- /var/tmp/diff_new_pack.S5YSRl/_old  2015-11-12 19:41:02.000000000 +0100
+++ /var/tmp/diff_new_pack.S5YSRl/_new  2015-11-12 19:41:02.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           uwsgi
-Version:        2.0.10
+Version:        2.0.11.1
 Release:        0
 Summary:        Application Container Server for Networked/Clustered Web 
Applications
 License:        GPL-2.0-with-GCC-exception
@@ -42,8 +42,6 @@
 Patch3:         uwsgi-1.9.11-systemd_logger-old_systemd.patch
 # PATCH-FIX-OPENSUSE uwsgi-1.9.13-emperor_pg-Wformat.patch - gcc complains 
about lack of -Wformat with -Wformat-security from pg_config
 Patch4:         uwsgi-1.9.13-emperor_pg-Wformat.patch
-# PATCH-FIX-UPSTREAM uwsgi-2.0.10-gcc5.patch - Fix version detection for GCC 5
-Patch5:         uwsgi-2.0.10-gcc5.patch
 %define apache_branch     %(rpm -q --qf %%{version} apache2 | grep -E -o 
"2\\.[0-9]+")
 %if "%{apache_branch}" == "2.4"
   %define apxs %{_bindir}/apxs2
@@ -450,7 +448,6 @@
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
-%patch5 -p1
 # Generate a config that builds all plugins except for examples and stuff we
 # can't satisfy the requirements for or are just broken
 excluded_plugins=""

++++++ uwsgi-2.0.10.tar.gz -> uwsgi-2.0.11.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/CONTRIBUTORS 
new/uwsgi-2.0.11.1/CONTRIBUTORS
--- old/uwsgi-2.0.10/CONTRIBUTORS       2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/CONTRIBUTORS     2015-07-19 08:17:07.000000000 +0200
@@ -30,3 +30,5 @@
 Yu Zhao (getcwd)
 Mathieu Dupuy
 Adriano Di Luzio ([email protected])
+Curtis Maloney
+Vladimir Didenko
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/emperor.c 
new/uwsgi-2.0.11.1/core/emperor.c
--- old/uwsgi-2.0.10/core/emperor.c     2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/emperor.c   2015-07-19 08:17:07.000000000 +0200
@@ -2295,6 +2295,9 @@
                                        }
                                        free(env_emperor_fd_config);
                                }
+                               if (fds)
+                                       free(fds);
+                               close(proxy_fd);
                                break;
                        }
 next:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/gateway.c 
new/uwsgi-2.0.11.1/core/gateway.c
--- old/uwsgi-2.0.10/core/gateway.c     2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/gateway.c   2015-07-19 08:17:07.000000000 +0200
@@ -72,7 +72,7 @@
 
        if (gw_pid == 0) {
                uwsgi_fixup_fds(0, 0, ug);
-               uwsgi_close_all_sockets();
+               uwsgi_close_all_unshared_sockets();
                if (uwsgi.master_as_root)
                        uwsgi_as_root();
 #ifdef __linux__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/hooks.c 
new/uwsgi-2.0.11.1/core/hooks.c
--- old/uwsgi-2.0.10/core/hooks.c       2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/hooks.c     2015-07-19 08:17:07.000000000 +0200
@@ -407,6 +407,24 @@
 #endif
 }
 
+static int uwsgi_hook_unix_signal(char *arg) {
+       char *space = strchr(arg, ' ');
+       if (!space) {
+               uwsgi_log("invalid unix_signal syntax, must be <signum> 
<func>\n");
+               return -1;
+       }
+       *space = 0;
+       int signum = atoi(arg);
+       *space = ' ';
+       void (*func)(int) = dlsym(RTLD_DEFAULT, space+1);
+       if (!func) {
+               uwsgi_log("unable to find function \"%s\"\n", space+1);
+               return -1;
+       }
+       uwsgi_unix_signal(signum, func);
+       return 0;
+}
+
 
 static int uwsgi_hook_callint(char *arg) {
         char *space = strchr(arg, ' ');
@@ -557,6 +575,22 @@
        return 0;
 }
 
+static int uwsgi_hook_wait_for_fs(char *arg) {
+       return uwsgi_wait_for_fs(arg, 0);
+}
+
+static int uwsgi_hook_wait_for_file(char *arg) {
+       return uwsgi_wait_for_fs(arg, 1);
+}
+
+static int uwsgi_hook_wait_for_dir(char *arg) {
+       return uwsgi_wait_for_fs(arg, 2);
+}
+
+static int uwsgi_hook_wait_for_socket(char *arg) {
+       return uwsgi_wait_for_socket(arg);
+}
+
 void uwsgi_register_base_hooks() {
        uwsgi_register_hook("cd", uwsgi_hook_chdir);
        uwsgi_register_hook("chdir", uwsgi_hook_chdir);
@@ -598,6 +632,14 @@
        uwsgi_register_hook("rpc", uwsgi_hook_rpc);
        uwsgi_register_hook("retryrpc", uwsgi_hook_retryrpc);
 
+       uwsgi_register_hook("wait_for_fs", uwsgi_hook_wait_for_fs);
+       uwsgi_register_hook("wait_for_file", uwsgi_hook_wait_for_file);
+       uwsgi_register_hook("wait_for_dir", uwsgi_hook_wait_for_dir);
+
+       uwsgi_register_hook("wait_for_socket", uwsgi_hook_wait_for_socket);
+
+       uwsgi_register_hook("unix_signal", uwsgi_hook_unix_signal);
+
        // for testing
        uwsgi_register_hook("exit", uwsgi_hook_exit);
        uwsgi_register_hook("print", uwsgi_hook_print);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/init.c 
new/uwsgi-2.0.11.1/core/init.c
--- old/uwsgi-2.0.10/core/init.c        2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/init.c      2015-07-19 08:17:07.000000000 +0200
@@ -471,6 +471,10 @@
                exit(1);
        }
 
+       if (uwsgi.evil_reload_on_rss || uwsgi.evil_reload_on_as) {
+               if (!uwsgi.mem_collector_freq) uwsgi.mem_collector_freq = 3;
+       }
+
        /* here we try to choose if thunder lock is a good thing */
 #ifdef UNBIT
        if (uwsgi.numproc > 1 && !uwsgi.map_socket) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/legion.c 
new/uwsgi-2.0.11.1/core/legion.c
--- old/uwsgi-2.0.10/core/legion.c      2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/legion.c    2015-07-19 08:17:07.000000000 +0200
@@ -277,14 +277,12 @@
                        memcpy(best_uuid, node->uuid, 36);
                }
                // go on if i am not an arbiter
-               else if (ul->valor > 0) {
-                       // no potential Lord is available, i will propose myself
-                       // but only if i am not suspended...
-                       if (uwsgi_now() > ul->suspended_til) {
-                               best_valor = ul->valor;
-                               memcpy(best_uuid, ul->uuid, 36);
-                               i_am_the_best = 1;
-                       }
+               // no potential Lord is available, i will propose myself
+               // but only if i am not suspended...
+               else if (ul->valor > 0 && uwsgi_now() > ul->suspended_til) {
+                       best_valor = ul->valor;
+                       memcpy(best_uuid, ul->uuid, 36);
+                       i_am_the_best = 1;
                }
                else {
                        // empty lord
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/logging.c 
new/uwsgi-2.0.11.1/core/logging.c
--- old/uwsgi-2.0.10/core/logging.c     2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/logging.c   2015-07-19 08:17:07.000000000 +0200
@@ -3,6 +3,7 @@
 #endif
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || 
defined(__OpenBSD__)
 #include <sys/user.h>
+#include <sys/sysctl.h>
 #include <kvm.h>
 #elif defined(__sun__)
 /* Terrible Hack !!! */
@@ -13,10 +14,6 @@
 #define _FILE_OFFSET_BITS 64
 #endif
 
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-#include <sys/sysctl.h>
-#endif
-
 #ifdef __DragonFly__
 #include <uwsgi.h>
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/master_checks.c 
new/uwsgi-2.0.11.1/core/master_checks.c
--- old/uwsgi-2.0.10/core/master_checks.c       2015-03-17 08:34:34.000000000 
+0100
+++ new/uwsgi-2.0.11.1/core/master_checks.c     2015-07-19 08:17:07.000000000 
+0200
@@ -39,6 +39,8 @@
 
 // check for chain reload
 void uwsgi_master_check_chain() {
+       static time_t last_check = 0;
+
        if (!uwsgi.status.chain_reloading) return;
 
        // we need to ensure the previous worker (if alive) is accepting new 
requests
@@ -49,7 +51,11 @@
                if (previous_worker->pid > 0 && !previous_worker->cheaped) {
                        // the worker has been respawned but it is still not 
ready
                        if (previous_worker->accepting == 0) {
-                               uwsgi_log_verbose("chain is still waiting for 
worker %d...\n", uwsgi.status.chain_reloading-1);
+                               time_t now = uwsgi_now();
+                               if (now != last_check) {
+                                       uwsgi_log_verbose("chain is still 
waiting for worker %d...\n", uwsgi.status.chain_reloading-1);
+                                       last_check = now;
+                               }
                                return;
                        }
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/routing.c 
new/uwsgi-2.0.11.1/core/routing.c
--- old/uwsgi-2.0.10/core/routing.c     2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/routing.c   2015-07-19 08:17:07.000000000 +0200
@@ -1215,6 +1215,27 @@
         return 0;
 }
 
+// fixpathinfo route
+static int uwsgi_router_fixpathinfo_func(struct wsgi_request *wsgi_req, struct 
uwsgi_route *ur) {
+       if (wsgi_req->script_name_len == 0)
+               return UWSGI_ROUTE_NEXT;
+
+        char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, 
wsgi_req->path_info+wsgi_req->script_name_len, wsgi_req->path_info_len - 
wsgi_req->script_name_len);
+        if (!ptr) {
+                return UWSGI_ROUTE_BREAK;
+        }
+        wsgi_req->path_info = wsgi_req->path_info+wsgi_req->script_name_len;
+        wsgi_req->path_info_len = wsgi_req->path_info_len - 
wsgi_req->script_name_len;
+        return UWSGI_ROUTE_NEXT;
+}
+static int uwsgi_router_fixpathinfo(struct uwsgi_route *ur, char *arg) {
+        ur->func = uwsgi_router_fixpathinfo_func;
+        ur->data = arg;
+        ur->data_len = strlen(arg);
+        return 0;
+}
+
+
 // setscheme route
 static int uwsgi_router_setscheme_func(struct wsgi_request *wsgi_req, struct 
uwsgi_route *ur) {
         char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
@@ -1778,6 +1799,10 @@
                 ret = uwsgi_64bit2str(wsgi_req->response_size);
                 *vallen = strlen(ret);
         }
+       else if (!uwsgi_strncmp(key, keylen, "sor", 3)) {
+                ret = uwsgi_64bit2str(wsgi_req->start_of_request);
+                *vallen = strlen(ret);
+        }
 
        return ret;
 }
@@ -1814,6 +1839,10 @@
                 ret = uwsgi_num2str(uwsgi_now());
                 *vallen = strlen(ret);
         }
+       else if (!uwsgi_strncmp(key, keylen, "micros", 6)) {
+               ret = uwsgi_64bit2str(uwsgi_micros());
+                *vallen = strlen(ret);
+       }
         return ret;
 }
 
@@ -1871,6 +1900,7 @@
         uwsgi_register_router("seturi", uwsgi_router_seturi);
         uwsgi_register_router("setremoteaddr", uwsgi_router_setremoteaddr);
         uwsgi_register_router("setpathinfo", uwsgi_router_setpathinfo);
+        uwsgi_register_router("fixpathinfo", uwsgi_router_fixpathinfo);
         uwsgi_register_router("setdocroot", uwsgi_router_setdocroot);
         uwsgi_register_router("setscheme", uwsgi_router_setscheme);
         uwsgi_register_router("setprocname", uwsgi_router_setprocname);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/sharedarea.c 
new/uwsgi-2.0.11.1/core/sharedarea.c
--- old/uwsgi-2.0.10/core/sharedarea.c  2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/sharedarea.c        2015-07-19 08:17:07.000000000 
+0200
@@ -280,8 +280,8 @@
        }
         uwsgi.sharedareas[id]->id = id;
         uwsgi.sharedareas[id]->fd = fd;
-        uwsgi.sharedareas[id]->pages = len / uwsgi.page_size;
-        if (len % uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
+        uwsgi.sharedareas[id]->pages = len / (size_t) uwsgi.page_size;
+        if (len % (size_t) uwsgi.page_size != 0) 
uwsgi.sharedareas[id]->pages++;
         uwsgi.sharedareas[id]->max_pos = len-1;
         char *id_str = uwsgi_num2str(id);
         uwsgi.sharedareas[id]->lock = 
uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
@@ -292,12 +292,12 @@
 
 struct uwsgi_sharedarea *uwsgi_sharedarea_init(int pages) {
        int id = uwsgi_sharedarea_new_id();
-       uwsgi.sharedareas[id] = uwsgi_calloc_shared(uwsgi.page_size * (pages + 
1));
-       uwsgi.sharedareas[id]->area = ((char *) uwsgi.sharedareas[id]) + 
uwsgi.page_size;
+       uwsgi.sharedareas[id] = uwsgi_calloc_shared((size_t)uwsgi.page_size * 
(size_t)(pages + 1));
+       uwsgi.sharedareas[id]->area = ((char *) uwsgi.sharedareas[id]) + 
(size_t) uwsgi.page_size;
        uwsgi.sharedareas[id]->id = id;
        uwsgi.sharedareas[id]->fd = -1;
        uwsgi.sharedareas[id]->pages = pages;
-       uwsgi.sharedareas[id]->max_pos = (uwsgi.page_size * pages) -1;
+       uwsgi.sharedareas[id]->max_pos = ((size_t)uwsgi.page_size * 
(size_t)pages) -1;
        char *id_str = uwsgi_num2str(id);
        uwsgi.sharedareas[id]->lock = 
uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
        free(id_str);
@@ -310,8 +310,8 @@
         uwsgi.sharedareas[id]->area = area;
         uwsgi.sharedareas[id]->id = id;
         uwsgi.sharedareas[id]->fd = -1;
-        uwsgi.sharedareas[id]->pages = len / uwsgi.page_size;
-       if (len % uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
+        uwsgi.sharedareas[id]->pages = len / (size_t) uwsgi.page_size;
+       if (len % (size_t) uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
         uwsgi.sharedareas[id]->max_pos = len-1;
         char *id_str = uwsgi_num2str(id);
         uwsgi.sharedareas[id]->lock = 
uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
@@ -348,8 +348,8 @@
                else {
                        len = uwsgi_n64(s_size);
                }
-               pages = len / uwsgi.page_size;
-               if (len % uwsgi.page_size != 0) pages++;
+               pages = len / (size_t) uwsgi.page_size;
+               if (len % (size_t) uwsgi.page_size != 0) pages++;
        }
 
        if (s_offset) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/socket.c 
new/uwsgi-2.0.11.1/core/socket.c
--- old/uwsgi-2.0.10/core/socket.c      2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/socket.c    2015-07-19 08:17:07.000000000 +0200
@@ -1249,10 +1249,20 @@
 }
 
 void uwsgi_close_all_sockets() {
+        struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
+
+        while (uwsgi_sock) {
+                if (uwsgi_sock->bound)
+                        close(uwsgi_sock->fd);
+                uwsgi_sock = uwsgi_sock->next;
+        }
+}
+
+void uwsgi_close_all_unshared_sockets() {
        struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
 
        while (uwsgi_sock) {
-               if (uwsgi_sock->bound)
+               if (uwsgi_sock->bound && !uwsgi_sock->shared)
                        close(uwsgi_sock->fd);
                uwsgi_sock = uwsgi_sock->next;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/ssl.c new/uwsgi-2.0.11.1/core/ssl.c
--- old/uwsgi-2.0.10/core/ssl.c 2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/ssl.c       2015-07-19 08:17:07.000000000 +0200
@@ -30,7 +30,18 @@
 }
 
 int uwsgi_ssl_verify_callback(int ok, X509_STORE_CTX * x509_store) {
-        return 1;
+        if (!ok && uwsgi.ssl_verbose) {
+                char buf[256];
+                X509 *err_cert;
+                int depth;
+                int err;
+                depth = X509_STORE_CTX_get_error_depth(x509_store);
+                err_cert = X509_STORE_CTX_get_current_cert(x509_store);
+                X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
+                err = X509_STORE_CTX_get_error(x509_store);
+                uwsgi_log("[uwsgi-ssl] client certificate verify error: 
num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf);
+        }
+        return ok;
 }
 
 int uwsgi_ssl_session_new_cb(SSL *ssl, SSL_SESSION *sess) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/utils.c 
new/uwsgi-2.0.11.1/core/utils.c
--- old/uwsgi-2.0.10/core/utils.c       2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/utils.c     2015-07-19 08:17:07.000000000 +0200
@@ -3514,7 +3514,7 @@
                tmpdir = "/tmp";
        }
 #ifdef O_TMPFILE
-       fd = open(tmpdir, O_TMPFILE | O_RDWR);
+       fd = open(tmpdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
        if (fd >= 0) {
                return fd;
        }
@@ -4446,6 +4446,7 @@
                                }
                        }
                        free(fds);
+                       close(ns_fd);
                        break;
                }
                if (fds)
@@ -4510,6 +4511,7 @@
                 sleep(1);
                 counter++;
         }
+       return -1;
 }
 
 // type -> 1 file, 2 dir, 0 both
@@ -4534,4 +4536,29 @@
                 sleep(1);
                 counter++;
         }
+       return -1;
+}
+
+int uwsgi_wait_for_socket(char *socket_name) {
+        if (!uwsgi.wait_for_socket_timeout) {
+                uwsgi.wait_for_socket_timeout = 60;
+        }
+        uwsgi_log("waiting for %s (max %d seconds) ...\n", socket_name, 
uwsgi.wait_for_socket_timeout);
+        int counter = 0;
+        for (;;) {
+                if (counter > uwsgi.wait_for_socket_timeout) {
+                        uwsgi_log("%s unavailable after %d seconds\n", 
socket_name, counter);
+                        return -1;
+                }
+               // wait for 1 second to respect uwsgi.wait_for_fs_timeout
+               int fd = uwsgi_connect(socket_name, 1, 0);
+               if (fd < 0) goto retry;
+               close(fd);
+                uwsgi_log_verbose("%s ready\n", socket_name);
+                return 0;
+retry:
+                sleep(1);
+                counter++;
+        }
+       return -1;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/core/uwsgi.c 
new/uwsgi-2.0.11.1/core/uwsgi.c
--- old/uwsgi-2.0.10/core/uwsgi.c       2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/core/uwsgi.c     2015-07-19 08:17:07.000000000 +0200
@@ -469,6 +469,9 @@
        {"wait-for-mountpoint", required_argument, 0, "wait for the specified 
mountpoint to appear before running root hooks", uwsgi_opt_add_string_list, 
&uwsgi.wait_for_mountpoint, 0},
        {"wait-for-fs-timeout", required_argument, 0, "set the timeout for 
wait-for-fs/file/dir", uwsgi_opt_set_int, &uwsgi.wait_for_fs_timeout, 0},
 
+       {"wait-for-socket", required_argument, 0, "wait for the specified 
socket to be ready before loading apps", uwsgi_opt_add_string_list, 
&uwsgi.wait_for_socket, 0},
+       {"wait-for-socket-timeout", required_argument, 0, "set the timeout for 
wait-for-socket", uwsgi_opt_set_int, &uwsgi.wait_for_socket_timeout, 0},
+
        {"call-asap", required_argument, 0, "call the specified function as 
soon as possible", uwsgi_opt_add_string_list, &uwsgi.call_asap, 0},
        {"call-pre-jail", required_argument, 0, "call the specified function 
before jailing", uwsgi_opt_add_string_list, &uwsgi.call_pre_jail, 0},
        {"call-post-jail", required_argument, 0, "call the specified function 
after jailing", uwsgi_opt_add_string_list, &uwsgi.call_post_jail, 0},
@@ -518,6 +521,7 @@
        {"reload-on-rss", required_argument, 0, "reload if rss memory is higher 
than specified megabytes", uwsgi_opt_set_megabytes, &uwsgi.reload_on_rss, 
UWSGI_OPT_MEMORY},
        {"evil-reload-on-as", required_argument, 0, "force the master to reload 
a worker if its address space is higher than specified megabytes", 
uwsgi_opt_set_megabytes, &uwsgi.evil_reload_on_as, UWSGI_OPT_MASTER | 
UWSGI_OPT_MEMORY},
        {"evil-reload-on-rss", required_argument, 0, "force the master to 
reload a worker if its rss memory is higher than specified megabytes", 
uwsgi_opt_set_megabytes, &uwsgi.evil_reload_on_rss, UWSGI_OPT_MASTER | 
UWSGI_OPT_MEMORY},
+       {"mem-collector-freq", required_argument, 0, "set the memory collector 
frequency when evil reloads are in place", uwsgi_opt_set_int, 
&uwsgi.mem_collector_freq, 0},
 
        {"reload-on-fd", required_argument, 0, "reload if the specified file 
descriptor is ready", uwsgi_opt_add_string_list, &uwsgi.reload_on_fd, 
UWSGI_OPT_MASTER},
        {"brutal-reload-on-fd", required_argument, 0, "brutal reload if the 
specified file descriptor is ready", uwsgi_opt_add_string_list, 
&uwsgi.brutal_reload_on_fd, UWSGI_OPT_MASTER},
@@ -1176,7 +1180,7 @@
        int sudden_death = 0;
 
        pthread_mutex_lock(&uwsgi.six_feet_under_lock);
-       for (i = 0; i < uwsgi.threads; i++) {
+       for (i = 1; i < uwsgi.threads; i++) {
                if 
(!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, pthread_self())) 
{
                        if 
(pthread_cancel(uwsgi.workers[uwsgi.mywid].cores[i].thread_id)) {
                                uwsgi_error("pthread_cancel()\n");
@@ -1189,7 +1193,7 @@
                goto end;
 
        // wait for thread termination
-       for (i = 0; i < uwsgi.threads; i++) {
+       for (i = 1; i < uwsgi.threads; i++) {
                if 
(!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, pthread_self())) 
{
                        ret = 
pthread_join(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, NULL);
                        if (ret) {
@@ -1198,6 +1202,22 @@
                }
        }
 
+       // cancel inital thread last since after pthread_cancel() and
+       // pthread_join() is called on it, the whole process will appear to be
+       // a zombie. although it won't eliminate process zombie time, but it
+       // should minimize it.
+       if (!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[0].thread_id, 
pthread_self())) {
+               if 
(pthread_cancel(uwsgi.workers[uwsgi.mywid].cores[0].thread_id)) {
+                       uwsgi_error("pthread_cancel() on initial thread\n");
+                       goto end;
+               }
+
+               ret = 
pthread_join(uwsgi.workers[uwsgi.mywid].cores[0].thread_id, NULL);
+               if (ret) {
+                       uwsgi_log("pthread_join() = %d on initial thread\n", 
ret);
+               }
+       }
+
 end:
 
        pthread_mutex_unlock(&uwsgi.six_feet_under_lock);
@@ -2544,6 +2564,11 @@
                uwsgi_as_root();
        }
 
+       // wait for socket
+       uwsgi_foreach(usl, uwsgi.wait_for_socket) {
+               if (uwsgi_wait_for_socket(usl->value)) exit(1);
+       }
+
        if (uwsgi.logto2) {
                if (!uwsgi.is_a_reload || uwsgi.log_reopen) {
                        logto(uwsgi.logto2);
@@ -3212,6 +3237,24 @@
 
 }
 
+// this lives in a worker thread and periodically scans for memory usage
+// when evil reloaders are in place
+void *mem_collector(void *foobar) {
+       // block all signals
+        sigset_t smask;
+        sigfillset(&smask);
+        pthread_sigmask(SIG_BLOCK, &smask, NULL);
+       uwsgi_log_verbose("mem-collector thread started for worker %d\n", 
uwsgi.mywid);
+       for(;;) {
+               sleep(uwsgi.mem_collector_freq);
+               uint64_t rss, vsz;
+               get_memusage(&rss, &vsz);
+               uwsgi.workers[uwsgi.mywid].rss_size = rss;
+               uwsgi.workers[uwsgi.mywid].vsz_size = vsz;
+       }
+       return NULL;
+}
+
 int uwsgi_run() {
 
        // !!! from now on, we could be in the master or in a worker !!!
@@ -3238,6 +3281,11 @@
        }
 #endif
 
+       if (uwsgi.evil_reload_on_rss || uwsgi.evil_reload_on_as) {
+               pthread_t t;
+               pthread_create(&t, NULL, mem_collector, NULL);
+       }
+
 
        // eventually maps (or disable) sockets for the  worker
        uwsgi_map_sockets();
@@ -4415,6 +4463,7 @@
 
        if (zerg == NULL) {
                uwsgi_log("--- invalid data received from zerg-server ---\n");
+               close(zerg_fd);
                return -1;
        }
 
@@ -4710,7 +4759,7 @@
 char *uwsgi_get_dot_h() {
        char *src = uwsgi_dot_h;
        size_t len = strlen(src);
-        char *ptr = uwsgi_malloc(len / 2);
+        char *ptr = uwsgi_malloc((len / 2) + 1);
         char *base = ptr;
         size_t i;
         unsigned int u;
@@ -4731,6 +4780,9 @@
        base = ub->buf;
        ub->buf = NULL;
        uwsgi_buffer_destroy(ub);
+#else
+        // add final null byte
+        *ptr = '\0';
 #endif
        return base;
 }
@@ -4743,7 +4795,7 @@
 char *uwsgi_get_config_py() {
         char *src = uwsgi_config_py;
         size_t len = strlen(src);
-        char *ptr = uwsgi_malloc(len / 2);
+        char *ptr = uwsgi_malloc((len / 2) + 1);
         char *base = ptr;
         size_t i;
         unsigned int u;
@@ -4764,6 +4816,9 @@
         base = ub->buf;
         ub->buf = NULL;
         uwsgi_buffer_destroy(ub);
+#else
+        // add final null byte
+        *ptr = '\0';
 #endif
         return base;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/cgi/cgi_plugin.c 
new/uwsgi-2.0.11.1/plugins/cgi/cgi_plugin.c
--- old/uwsgi-2.0.10/plugins/cgi/cgi_plugin.c   2015-03-17 08:34:34.000000000 
+0100
+++ new/uwsgi-2.0.11.1/plugins/cgi/cgi_plugin.c 2015-07-19 08:17:07.000000000 
+0200
@@ -533,9 +533,9 @@
                memcpy(full_path, tmp_path, full_path_len+1);
 
                if (uwsgi_starts_with(full_path, full_path_len, docroot, 
docroot_len)) {
+                       uwsgi_log("CGI security error: %s is not under %s\n", 
full_path, docroot);
                        if (need_free)
                                free(docroot);
-                       uwsgi_log("CGI security error: %s is not under %s\n", 
full_path, docroot);
                        return -1;
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/corerouter/corerouter.c 
new/uwsgi-2.0.11.1/plugins/corerouter/corerouter.c
--- old/uwsgi-2.0.10/plugins/corerouter/corerouter.c    2015-03-17 
08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/plugins/corerouter/corerouter.c  2015-07-19 
08:17:07.000000000 +0200
@@ -95,7 +95,7 @@
        if (peer->flush && !peer->is_flushing) {
                peer->is_flushing = 1;
                // on success, suspend the execution
-               if (peer->flush(peer) >= 0) return -1;
+               if (peer->flush(peer) > 0) return -1;
        }
        struct corerouter_peer *prev = peer->prev;
        struct corerouter_peer *next = peer->next;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/http/https.c 
new/uwsgi-2.0.11.1/plugins/http/https.c
--- old/uwsgi-2.0.10/plugins/http/https.c       2015-03-17 08:34:34.000000000 
+0100
+++ new/uwsgi-2.0.11.1/plugins/http/https.c     2015-07-19 08:17:07.000000000 
+0200
@@ -320,7 +320,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_cr_error(main_peer, "hr_ssl_write()");
+               if (errno != 0)
+                       uwsgi_cr_error(main_peer, "hr_ssl_write()");
         }
 
         else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
@@ -380,7 +381,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_cr_error(main_peer, "hr_ssl_read()");
+               if (errno != 0)
+                       uwsgi_cr_error(main_peer, "hr_ssl_read()");
         }
 
         else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
@@ -420,7 +422,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_cr_error(peer, "hr_ssl_shutdown()");
+               if (errno != 0)
+                       uwsgi_cr_error(peer, "hr_ssl_shutdown()");
         }
 
         else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/psgi/psgi_loader.c 
new/uwsgi-2.0.11.1/plugins/psgi/psgi_loader.c
--- old/uwsgi-2.0.10/plugins/psgi/psgi_loader.c 2015-03-17 08:34:34.000000000 
+0100
+++ new/uwsgi-2.0.11.1/plugins/psgi/psgi_loader.c       2015-07-19 
08:17:07.000000000 +0200
@@ -144,7 +144,7 @@
                        else {
                                long orig_offset = 0;
                                 // first of all get the new orig_len;   
-                                offset = abs(offset);
+                                offset = labs(offset);
                                 if (offset > (long) orig_len) {
                                         new_size = offset;
                                        orig_offset = offset - orig_len;
@@ -285,7 +285,7 @@
                                uwsgi_log("[perl] WARNING !!! unable to build 
uwsgi::opt hash !!!\n");
                                goto end;
                        }
-                       if (SvTYPE(SvRV(*value)) == SVt_PVAV) {
+                       if (SvROK(*value) && SvTYPE(SvRV(*value)) == SVt_PVAV) {
                                if (uwsgi.exported_opts[i]->value == NULL) {
                                         av_push((AV *)SvRV(*value), 
newSViv(1));
                                 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/pypy/pypy_setup.py 
new/uwsgi-2.0.11.1/plugins/pypy/pypy_setup.py
--- old/uwsgi-2.0.10/plugins/pypy/pypy_setup.py 2015-03-17 08:34:34.000000000 
+0100
+++ new/uwsgi-2.0.11.1/plugins/pypy/pypy_setup.py       2015-07-19 
08:17:07.000000000 +0200
@@ -393,7 +393,7 @@
         rlen = ffi.new('ssize_t*')
         chunk = lib.uwsgi_request_body_read(self.wsgi_req, size, rlen)
         if chunk != ffi.NULL:
-            return ffi.string(chunk, rlen[0])
+            return ffi.buffer(chunk, rlen[0])[:]
         if rlen[0] < 0:
             raise IOError("error reading wsgi.input")
         raise IOError("error waiting for wsgi.input")
@@ -402,7 +402,7 @@
         rlen = ffi.new('ssize_t*')
         chunk = lib.uwsgi_request_body_readline(self.wsgi_req, hint, rlen)
         if chunk != ffi.NULL:
-            return ffi.string(chunk, rlen[0])
+            return ffi.buffer(chunk, rlen[0])[:]
         if rlen[0] < 0:
             raise IOError("error reading line from wsgi.input")
         raise IOError("error waiting for line on wsgi.input")
@@ -521,7 +521,7 @@
     def __call__(self, argc, argv, argvs, buf):
         pargs = []
         for i in range(0, argc):
-            pargs.append(ffi.string(argv[i], argvs[i]))
+            pargs.append(ffi.buffer(argv[i], argvs[i])[:])
         response = self.func(*pargs)
         if len(response) > 0:
             buf[0] = lib.uwsgi_malloc(len(response))
@@ -560,7 +560,7 @@
 
     response = lib.uwsgi_do_rpc(c_node, ffi.new("char[]",func), argc, argv, 
argvs, rsize)
     if response:
-        ret = ffi.string(response, rsize[0])
+        ret = ffi.buffer(response, rsize[0])[:]
         lib.free(response)
         return ret
     return None
@@ -587,7 +587,7 @@
     value = lib.uwsgi_cache_magic_get(key, len(key), vallen, ffi.NULL, cache)
     if value == ffi.NULL:
         return None
-    ret = ffi.string(value, vallen[0])
+    ret = ffi.buffer(value, vallen[0])[:]
     libc.free(value)
     return ret
 uwsgi.cache_get = uwsgi_pypy_uwsgi_cache_get
@@ -617,8 +617,9 @@
     uci = ffi.new('struct uwsgi_cache_item **')
     while True:
         uci[0] = lib.uwsgi_cache_keys(uc, pos, uci)
-        if uci[0] == ffi.NULL: break
-        l.append(ffi.string(lib.uwsgi_cache_item_key(uci[0]), uci[0].keysize))
+        if uci[0] == ffi.NULL:
+            break
+        l.append(ffi.buffer(lib.uwsgi_cache_item_key(uci[0]), 
uci[0].keysize)[:])
     lib.uwsgi_cache_rwunlock(uc)
     return l
 uwsgi.cache_keys = uwsgi_pypy_uwsgi_cache_keys
@@ -849,7 +850,7 @@
     ub = lib.uwsgi_websocket_recv(wsgi_req);
     if ub == ffi.NULL:
         raise IOError("unable to receive websocket message")
-    ret = ffi.string(ub.buf, ub.pos)
+    ret = ffi.buffer(ub.buf, ub.pos)[:]
     lib.uwsgi_buffer_destroy(ub)
     return ret
 uwsgi.websocket_recv = uwsgi_pypy_websocket_recv
@@ -862,7 +863,7 @@
     ub = lib.uwsgi_websocket_recv_nb(wsgi_req);
     if ub == ffi.NULL:
         raise IOError("unable to receive websocket message")
-    ret = ffi.string(ub.buf, ub.pos)
+    ret = ffi.buffer(ub.buf, ub.pos)[:]
     lib.uwsgi_buffer_destroy(ub)
     return ret
 uwsgi.websocket_recv_nb = uwsgi_pypy_websocket_recv_nb
@@ -897,7 +898,7 @@
     chunk = lib.uwsgi_chunked_read(wsgi_req, rlen, timeout, 0)
     if chunk == ffi.NULL:
         raise IOError("unable to receive chunked part")
-    return ffi.string(chunk, rlen[0])
+    return ffi.buffer(chunk, rlen[0])[:]
 uwsgi.chunked_read = uwsgi_pypy_chunked_read
 
 """
@@ -911,8 +912,7 @@
         if lib.uwsgi_is_again() > 0:
             return None
         raise IOError("unable to receive chunked part")
-    
-    return ffi.string(chunk, rlen[0])
+    return ffi.buffer(chunk, rlen[0])[:]
 uwsgi.chunked_read_nb = uwsgi_pypy_chunked_read_nb
 
 """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/python/python_plugin.c 
new/uwsgi-2.0.11.1/plugins/python/python_plugin.c
--- old/uwsgi-2.0.10/plugins/python/python_plugin.c     2015-03-17 
08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/plugins/python/python_plugin.c   2015-07-19 
08:17:07.000000000 +0200
@@ -88,7 +88,7 @@
        {"module", required_argument,'w', "load a WSGI module", 
uwsgi_opt_set_str, &up.wsgi_config, 0},
        {"wsgi", required_argument, 'w', "load a WSGI module", 
uwsgi_opt_set_str, &up.wsgi_config, 0},
        {"callable", required_argument, 0, "set default WSGI callable name", 
uwsgi_opt_set_str, &up.callable, 0},
-       {"test", required_argument, 'J', "test a mdule import", 
uwsgi_opt_set_str, &up.test_module, 0},
+       {"test", required_argument, 'J', "test a module import", 
uwsgi_opt_set_str, &up.test_module, 0},
        {"home", required_argument, 'H', "set PYTHONHOME/virtualenv", 
uwsgi_opt_set_str, &up.home, 0},
        {"virtualenv", required_argument, 'H', "set PYTHONHOME/virtualenv", 
uwsgi_opt_set_str, &up.home, 0},
        {"venv", required_argument, 'H', "set PYTHONHOME/virtualenv", 
uwsgi_opt_set_str, &up.home, 0},
@@ -1670,6 +1670,8 @@
                PyDict_SetItemString(spool_dict, "body", value);
                Py_DECREF(value);
        }
+       // PyTuple_SetItem steals a reference !!!
+       Py_INCREF(spool_dict);
        PyTuple_SetItem(pyargs, 0, spool_dict);
 
        ret = python_call(spool_func, pyargs, 0, NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/python/uwsgi_pymodule.c 
new/uwsgi-2.0.11.1/plugins/python/uwsgi_pymodule.c
--- old/uwsgi-2.0.10/plugins/python/uwsgi_pymodule.c    2015-03-17 
08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/plugins/python/uwsgi_pymodule.c  2015-07-19 
08:17:07.000000000 +0200
@@ -1448,6 +1448,72 @@
 
 }
 
+PyObject *py_uwsgi_sharedarea_inc32(PyObject * self, PyObject * args) {
+        int id;
+        uint64_t pos = 0;
+        int32_t value = 1;
+
+        if (!PyArg_ParseTuple(args, "iL|i:sharedarea_inc32", &id, &pos, 
&value)) {
+                return NULL;
+        }
+
+        UWSGI_RELEASE_GIL
+        int ret = uwsgi_sharedarea_inc32(id, pos, value);
+        UWSGI_GET_GIL
+
+        if (ret) {
+                return PyErr_Format(PyExc_ValueError, "error calling 
uwsgi_sharedarea_inc32()");
+        }
+
+        Py_INCREF(Py_None);
+        return Py_None;
+
+}
+
+PyObject *py_uwsgi_sharedarea_dec64(PyObject * self, PyObject * args) {
+        int id;
+        uint64_t pos = 0;
+        int64_t value = 1;
+
+        if (!PyArg_ParseTuple(args, "iL|l:sharedarea_dec64", &id, &pos, 
&value)) {
+                return NULL;
+        }
+
+        UWSGI_RELEASE_GIL
+        int ret = uwsgi_sharedarea_dec64(id, pos, value);
+        UWSGI_GET_GIL
+
+        if (ret) {
+                return PyErr_Format(PyExc_ValueError, "error calling 
uwsgi_sharedarea_dec64()");
+        }
+
+        Py_INCREF(Py_None);
+        return Py_None;
+
+}
+
+PyObject *py_uwsgi_sharedarea_dec32(PyObject * self, PyObject * args) {
+        int id;
+        uint64_t pos = 0;
+        int32_t value = 1;
+
+        if (!PyArg_ParseTuple(args, "iL|i:sharedarea_dec32", &id, &pos, 
&value)) {
+                return NULL;
+        }
+
+        UWSGI_RELEASE_GIL
+        int ret = uwsgi_sharedarea_dec32(id, pos, value);
+        UWSGI_GET_GIL
+
+        if (ret) {
+                return PyErr_Format(PyExc_ValueError, "error calling 
uwsgi_sharedarea_dec32()");
+        }
+
+        Py_INCREF(Py_None);
+        return Py_None;
+
+}
+
 PyObject *py_uwsgi_sharedarea_write32(PyObject * self, PyObject * args) {
         int id;
         uint64_t pos = 0;
@@ -2569,6 +2635,9 @@
        {"sharedarea_write16", py_uwsgi_sharedarea_write16, METH_VARARGS, ""},
        {"sharedarea_inclong", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""},
        {"sharedarea_inc64", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""},
+       {"sharedarea_inc32", py_uwsgi_sharedarea_inc32, METH_VARARGS, ""},
+       {"sharedarea_dec64", py_uwsgi_sharedarea_dec64, METH_VARARGS, ""},
+       {"sharedarea_dec32", py_uwsgi_sharedarea_dec32, METH_VARARGS, ""},
        {"sharedarea_rlock", py_uwsgi_sharedarea_rlock, METH_VARARGS, ""},
        {"sharedarea_wlock", py_uwsgi_sharedarea_wlock, METH_VARARGS, ""},
        {"sharedarea_unlock", py_uwsgi_sharedarea_unlock, METH_VARARGS, ""},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/sslrouter/sslrouter.c 
new/uwsgi-2.0.11.1/plugins/sslrouter/sslrouter.c
--- old/uwsgi-2.0.10/plugins/sslrouter/sslrouter.c      2015-03-17 
08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/plugins/sslrouter/sslrouter.c    2015-07-19 
08:17:07.000000000 +0200
@@ -250,7 +250,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_cr_error(main_peer, "sr_write()");
+               if (errno != 0)
+                       uwsgi_cr_error(main_peer, "sr_write()");
         }
 
         else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
@@ -332,7 +333,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_cr_error(main_peer, "sr_ssl_read()");
+               if (errno != 0)
+                       uwsgi_cr_error(main_peer, "sr_ssl_read()");
         }
 
         else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/plugins/transformation_gzip/gzip.c 
new/uwsgi-2.0.11.1/plugins/transformation_gzip/gzip.c
--- old/uwsgi-2.0.10/plugins/transformation_gzip/gzip.c 2015-03-17 
08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/plugins/transformation_gzip/gzip.c       2015-07-19 
08:17:07.000000000 +0200
@@ -24,7 +24,7 @@
        struct uwsgi_buffer *ub = ut->chunk;
 
        if (ut->is_final) {
-               if (uwsgi_gzip_fix(&utgz->z, utgz->crc32, ub, utgz->len)) {
+               if (utgz->len > 0 && uwsgi_gzip_fix(&utgz->z, utgz->crc32, ub, 
utgz->len)) {
                        free(utgz);
                        return -1;
                }
@@ -32,6 +32,11 @@
                return 0;
        }
 
+       if (ub->pos == 0) {
+               // Don't try to compress empty responses.
+               return 0;
+       }
+
        size_t dlen = 0;
        char *gzipped = uwsgi_gzip_chunk(&utgz->z, &utgz->crc32, ub->buf, 
ub->pos, &dlen);
        if (!gzipped) return -1;
@@ -39,7 +44,7 @@
        uwsgi_buffer_map(ub, gzipped, dlen);
        if (!utgz->header) {
                // do not check for errors !!!
-               uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, 
"gzip", 4);
+               uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, 
"gzip", 4);
                utgz->header = 1;
                if (uwsgi_buffer_insert(ub, 0, gzheader, 10)) {
                        return -1;
@@ -59,7 +64,7 @@
        ut->can_stream = 1;
        // this is the trasformation clearing the memory
        ut = uwsgi_add_transformation(wsgi_req, transform_gzip, utgz);
-        ut->is_final = 1;
+       ut->is_final = 1;
        return UWSGI_ROUTE_NEXT;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/proto/base.c 
new/uwsgi-2.0.11.1/proto/base.c
--- old/uwsgi-2.0.10/proto/base.c       2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/proto/base.c     2015-07-19 08:17:07.000000000 +0200
@@ -287,7 +287,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_error("uwsgi_proto_ssl_write()/SSL_write()");
+               if (errno != 0)
+                       uwsgi_error("uwsgi_proto_ssl_write()/SSL_write()");
         }
 
         return -1;
@@ -383,7 +384,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_error("uwsgi_proto_ssl_read_body()/SSL_read()");
+               if (errno != 0)
+                       uwsgi_error("uwsgi_proto_ssl_read_body()/SSL_read()");
         }
 
        return -1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/proto/http.c 
new/uwsgi-2.0.11.1/proto/http.c
--- old/uwsgi-2.0.10/proto/http.c       2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/proto/http.c     2015-07-19 08:17:07.000000000 +0200
@@ -760,7 +760,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_error("uwsgi_proto_https_parser()/SSL_read()");
+               if (errno != 0)
+                       uwsgi_error("uwsgi_proto_https_parser()/SSL_read()");
         }
        return -1;
 empty:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/proto/uwsgi.c 
new/uwsgi-2.0.11.1/proto/uwsgi.c
--- old/uwsgi-2.0.10/proto/uwsgi.c      2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/proto/uwsgi.c    2015-07-19 08:17:07.000000000 +0200
@@ -83,7 +83,8 @@
         }
 
         else if (err == SSL_ERROR_SYSCALL) {
-                uwsgi_error("uwsgi_proto_suwsgi_parser()/SSL_read()");
+               if (errno != 0)
+                       uwsgi_error("uwsgi_proto_suwsgi_parser()/SSL_read()");
         }
 
         return -1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/t/sharedarea/bigranges.ini 
new/uwsgi-2.0.11.1/t/sharedarea/bigranges.ini
--- old/uwsgi-2.0.10/t/sharedarea/bigranges.ini 1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.11.1/t/sharedarea/bigranges.ini       2015-07-19 
08:17:07.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+socket = /tmp/foo
+
+sharedarea = size=4300000000
+
+pyrun = t/sharedarea/%n.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/t/sharedarea/bigranges.py 
new/uwsgi-2.0.11.1/t/sharedarea/bigranges.py
--- old/uwsgi-2.0.10/t/sharedarea/bigranges.py  1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.11.1/t/sharedarea/bigranges.py        2015-07-19 
08:17:07.000000000 +0200
@@ -0,0 +1,16 @@
+import uwsgi
+import unittest
+
+class SharedareaTest(unittest.TestCase):
+
+    def test_32(self):
+        pos = 2L * (1024L ** 3)
+        uwsgi.sharedarea_write32(0, pos, 17)
+        self.assertEqual(uwsgi.sharedarea_read32(0, pos), 17)
+
+    def test_64(self):
+        pos = 2L * (1024L ** 3)
+        uwsgi.sharedarea_write64(0, pos, 30)
+        self.assertEqual(uwsgi.sharedarea_read64(0, pos), 30)
+
+unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/t/sharedarea/sharedarea_incdec.ini 
new/uwsgi-2.0.11.1/t/sharedarea/sharedarea_incdec.ini
--- old/uwsgi-2.0.10/t/sharedarea/sharedarea_incdec.ini 1970-01-01 
01:00:00.000000000 +0100
+++ new/uwsgi-2.0.11.1/t/sharedarea/sharedarea_incdec.ini       2015-07-19 
08:17:07.000000000 +0200
@@ -0,0 +1,6 @@
+[uwsgi]
+socket = /tmp/foo
+
+sharedarea = size=64
+
+pyrun = t/sharedarea/%n.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/t/sharedarea/sharedarea_incdec.py 
new/uwsgi-2.0.11.1/t/sharedarea/sharedarea_incdec.py
--- old/uwsgi-2.0.10/t/sharedarea/sharedarea_incdec.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/uwsgi-2.0.11.1/t/sharedarea/sharedarea_incdec.py        2015-07-19 
08:17:07.000000000 +0200
@@ -0,0 +1,34 @@
+import uwsgi
+import unittest
+
+class SharedareaTest(unittest.TestCase):
+
+    def setUp(self):
+        uwsgi.sharedarea_write(0, 0, '\0' * 64)
+
+    def test_32(self):
+        uwsgi.sharedarea_write32(0, 0, 17)
+        self.assertEqual(uwsgi.sharedarea_read32(0, 0), 17)
+
+    def test_inc32(self):
+        uwsgi.sharedarea_write32(0, 4, 30)
+        uwsgi.sharedarea_inc32(0, 4, 3)
+        self.assertEqual(uwsgi.sharedarea_read32(0, 4), 33)
+
+    def test_dec32(self):
+        uwsgi.sharedarea_write32(0, 5, 30)
+        uwsgi.sharedarea_dec32(0, 5, 4)
+        self.assertEqual(uwsgi.sharedarea_read32(0, 5), 26)
+
+    def test_inc64(self):
+        uwsgi.sharedarea_write64(0, 8, 17 * (1024 ** 5))
+        uwsgi.sharedarea_inc64(0, 8, 1)
+        self.assertEqual(uwsgi.sharedarea_read64(0, 8), 17 * (1024 ** 5) + 1)
+
+    def test_dec64(self):
+        uwsgi.sharedarea_write64(0, 8, 30 * (1024 ** 5))
+        uwsgi.sharedarea_dec64(0, 8, 30 * (1024 ** 5) - 1)
+        self.assertEqual(uwsgi.sharedarea_read64(0, 8), 1)
+    
+
+unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/uwsgi.gemspec 
new/uwsgi-2.0.11.1/uwsgi.gemspec
--- old/uwsgi-2.0.10/uwsgi.gemspec      2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/uwsgi.gemspec    2015-07-19 08:17:07.000000000 +0200
@@ -2,7 +2,7 @@
   s.name        = 'uwsgi'
   s.license     = 'GPL-2'
   s.version     = `python -c "import uwsgiconfig as uc; print 
uc.uwsgi_version"`.sub(/-dev-.*/,'')
-  s.date        = '2015-03-17'
+  s.date        = '2015-07-19'
   s.summary     = "uWSGI"
   s.description = "The uWSGI server for Ruby/Rack"
   s.authors     = ["Unbit"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/uwsgi.h new/uwsgi-2.0.11.1/uwsgi.h
--- old/uwsgi-2.0.10/uwsgi.h    2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/uwsgi.h  2015-07-19 08:17:07.000000000 +0200
@@ -2760,6 +2760,11 @@
        // uWSGI 2.0.10
        struct uwsgi_string_list *emperor_wrapper_override;
        struct uwsgi_string_list *emperor_wrapper_fallback;
+
+       // uWSGI 2.0.11
+       struct uwsgi_string_list *wait_for_socket;
+       int wait_for_socket_timeout;
+       int mem_collector_freq;
 };
 
 struct uwsgi_rpc {
@@ -3469,6 +3474,7 @@
 struct uwsgi_socket *uwsgi_del_socket(struct uwsgi_socket *);
 
 void uwsgi_close_all_sockets(void);
+void uwsgi_close_all_unshared_sockets(void);
 
 struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **, 
char *);
 #ifdef UWSGI_PCRE
@@ -4852,6 +4858,7 @@
 
 int uwsgi_wait_for_fs(char *, int);
 int uwsgi_wait_for_mountpoint(char *);
+int uwsgi_wait_for_socket(char *);
 
 #ifdef __cplusplus
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.10/uwsgiconfig.py 
new/uwsgi-2.0.11.1/uwsgiconfig.py
--- old/uwsgi-2.0.10/uwsgiconfig.py     2015-03-17 08:34:34.000000000 +0100
+++ new/uwsgi-2.0.11.1/uwsgiconfig.py   2015-07-19 08:17:07.000000000 +0200
@@ -1,6 +1,6 @@
 # uWSGI build system
 
-uwsgi_version = '2.0.10'
+uwsgi_version = '2.0.11.1'
 
 import os
 import re
@@ -689,8 +689,13 @@
             print("detected include path: %s" % self.include_path)
 
         try:
-            gcc_major = int(gcc_version.split('.')[0])
-            gcc_minor = int(gcc_version.split('.')[1])
+            gcc_version_components = gcc_version.split('.')
+            gcc_major = int(gcc_version_components[0])
+            if len(gcc_version_components) > 1:
+                gcc_minor = int(gcc_version_components[1])
+            else:
+                # gcc 5.0 is represented as simply "5"
+                gcc_minor = 0
         except:
             raise Exception("you need a C compiler to build uWSGI")
         if (sys.version_info[0] == 2) or (gcc_major < 4) or (gcc_major == 4 
and gcc_minor < 3):
@@ -768,7 +773,7 @@
 
         if 'UWSGI_PROFILE_OVERRIDE' in os.environ:
             for item in os.environ['UWSGI_PROFILE_OVERRIDE'].split(';'):
-                k,v = item.split('=', 2)
+                k,v = item.split('=', 1)
                 self.set(k, v)
 
         if 'UWSGI_AS_LIB' in os.environ:


Reply via email to