Compare commits

...
102 Commits
Author SHA1 Message Date
roberto@precise64 4e57a6e145 uWSGI 1.2-rc1 2012-04-14 12:54:48 +02:00
roberto@openindiana64 784434ef3e opeinindiana fixes 2012-04-14 12:24:04 +02:00
roberto@precise64 91273b2301 py-auto-reload-ignore 2012-04-14 11:48:27 +02:00
roberto@precise64 2bcc85a99f added support for REMOTE_ADDR in mongrel2/zeromq 2012-04-14 10:08:34 +02:00
roberto@precise64 b7e6da3392 added --write-errors-tolerance and --write-errors-exception-only 2012-04-14 09:11:52 +02:00
roberto@precise64 d934270a27 merge 2012-04-14 08:22:54 +02:00
roberto@fiorenzo ed5a268e1f fix reloading of gateways 2012-04-13 19:01:05 +02:00
roberto@fiorenzo 95beaa0a86 merge 2012-04-13 17:09:22 +02:00
roberto@fiorenzo 0d3bf93c76 fixed fd leak in daemonize 2012-04-13 17:08:52 +02:00
roberto@sirius 50fb43066a ported fastcgi and zeromq to the new api 2012-04-13 16:23:55 +02:00
roberto@centos4 c33ec8ff56 ported locking to obsolete kernels 2012-04-13 14:09:03 +02:00
roberto@mrspurr e6afeec8af fixed return value in cache sweeper thread 2012-04-13 15:57:07 +02:00
roberto@sirius 57b9bdb958 better write()/writev() management 2012-04-13 11:36:43 +02:00
roberto@precise64 315bcb72c9 applied nagios patch from github 2012-04-11 07:23:00 +02:00
roberto@precise64 6b2460c02f improved syslog 2012-04-11 07:20:58 +02:00
roberto@precise64 35bc999a59 correctly set bin_name in setup.py 2012-04-09 08:41:27 +02:00
roberto@precise64 f00ad75e45 added --emperor-magic-exec 2012-04-08 09:13:07 +02:00
roberto@openbsd51 6bfe8e5b41 openBSD fixes 2012-04-08 08:24:51 +02:00
roberto@precise64 d7e8fd7d06 a couple of typo 2012-04-07 21:17:09 +02:00
roberto@precise64 949a0c35d5 improve cache reliability and performance of the sweeper 2012-04-07 21:08:42 +02:00
roberto@precise64 d193d5572f add --cache-expire-freq 2012-04-06 16:09:58 +02:00
roberto@precise64 f79f7e44a7 fixed cache and queue locking 2012-04-06 15:54:29 +02:00
roberto@mrspurr 26db55aafd fixed --pyargv 2012-04-06 11:39:48 +02:00
roberto@mrspurr 9d405c6cb2 fixed locking in uwsgi.cache_exists 2012-04-06 10:28:02 +02:00
roberto@mrspurr cceee511f2 added support for reload-on-exception on PyPy and interval-based cron syntax 2012-04-06 07:40:21 +02:00
roberto@freebsd9 e2024ed2fd merge 2012-04-05 12:28:30 +02:00
roberto@freebsd9 add7e2ee0e added execinfo support for FreeBSD 2012-04-05 12:28:10 +02:00
roberto@precise64 0458aa8eb4 use ctime_r instead of ctime 2012-04-05 12:15:04 +02:00
roberto@freebsd9 9ff6be783a use posix semaphores on freebsd9 2012-04-05 06:22:02 +02:00
roberto@mrspurr 14c558559b pypy now has PyFile_FromFile 2012-04-05 05:52:58 +02:00
roberto@centos64 92c5dcb6f2 allows robust mutexes on older linux systems 2012-04-04 22:54:56 +02:00
roberto@precise64 ae31f349f7 added robust mutexes 2012-04-04 22:53:07 +02:00
roberto@centos64 ce2846d04f first pthread robust implementation 2012-04-04 21:48:34 +02:00
roberto@mrspurr 7a6c9a5fe4 merge 2012-04-04 17:29:39 +02:00
roberto@mrspurr 43c258ad48 support for virtualenv in pypy 2012-04-04 17:29:00 +02:00
roberto@precise64 8ba032adb2 added --spooler-max-tasks 2012-04-03 17:59:37 +02:00
roberto@precise64 1a61dfd4e0 ported mod_Ruwsgi to apache 2.4 2012-04-03 09:02:00 +02:00
roberto@precise64 8e150e77a8 ported mod_uwsgi to apache 2.4 2012-04-03 08:47:09 +02:00
roberto@goyle 729fa753fa remove unneded pypy ifdef 2012-04-02 19:33:33 +02:00
roberto@longshot bf6c552189 fixed python 2.4 2012-04-02 07:55:22 +02:00
roberto@precise64 e9dc987a95 revert wsgi.url_scheme 2012-04-02 07:48:20 +02:00
roberto@precise64 35d9a39100 fixed autoload 2012-04-01 06:14:09 +02:00
roberto@mrspurr a864c8d6ed fix pypy when no app is loaded 2012-03-31 18:06:03 +02:00
roberto@precise64 c2df8a099e added --python-auto-reload 2012-03-31 17:55:09 +02:00
roberto@precise64 878e9cb9ba reports microseconds in python profilers 2012-03-31 15:48:22 +02:00
roberto@precise64 3612ea2186 fixed a deadlock in get_mime_type 2012-03-30 21:15:14 +02:00
roberto@precise64 81f0f93d96 improved module aliasing 2012-03-30 10:17:30 +02:00
roberto@precise64 c2d7b65145 better error management in pymodule-alias 2012-03-29 12:59:50 +02:00
roberto@precise64 6274e82cea fix fastrouter subscription refcnt 2012-03-29 11:26:35 +02:00
roberto@precise64 66655c9429 php append options 2012-03-28 18:28:24 +02:00
roberto@precise64 f47c8553d5 added uwsgi_expand_path() 2012-03-28 16:48:17 +02:00
roberto@precise64 f2802d3332 gevent current_req fix 2012-03-28 16:22:18 +02:00
roberto@precise64 1a173c849f minor fixes for test suite 2012-03-28 12:40:20 +02:00
roberto@precise64 57d4cd9fc9 gevent fixes 2012-03-28 11:08:04 +02:00
roberto@precise64 f6b9345716 fixed a garbage in python_call 2012-03-28 10:21:20 +02:00
roberto@freebsd64 792cd01320 fixed daemonize 2012-03-28 09:34:37 +02:00
roberto@mrspurr 03bc7d0399 close bug 85 2012-03-28 09:00:53 +02:00
roberto@mrspurr ed8f0812d7 PyPy SUPPORT 2012-03-27 13:58:27 +02:00
roberto@precise64 196dc45d0b fixed zero socket (2) 2012-03-26 14:28:18 +02:00
roberto@precise64 f8ff906d1b fixed zero socket 2012-03-26 14:20:08 +02:00
roberto@precise64 bbf1b0eda5 merged pypy 2012-03-26 13:41:50 +02:00
roberto@precise64 6f811a4899 better realpath for static docroot 2012-03-26 13:41:18 +02:00
roberto@mrspurr c66957d685 first round of pypy patches 2012-03-26 10:46:12 +02:00
roberto@goyle 282b2d5ace lua fixes 2012-03-23 21:22:17 +01:00
roberto@precise64 6a73e3ae05 fixed rack.input read 2012-03-22 16:25:27 +01:00
roberto@precise64 5856d410fd second part of zerg fixes 2012-03-22 11:14:41 +01:00
roberto@precise64 08d9de54f0 uniq zerg sockets 2012-03-22 10:05:00 +01:00
roberto@precise64 af1f98131a --perl-no-die-catch 2012-03-22 08:32:11 +01:00
roberto@precise64 9cef49ec57 fixed perl caching, added uwsgi::signal 2012-03-22 08:26:33 +01:00
roberto@precise64 d60c6d50ec fixed plugin loading by symlink 2012-03-22 07:35:27 +01:00
roberto@precise64 f3fdec2739 completed --reload-on-exception* options 2012-03-21 20:37:03 +01:00
roberto@precise64 1a20f57b73 fixed --spooler-quiet 2012-03-21 20:28:08 +01:00
roberto@precise64 0fc74dac4d better GIL usage 2012-03-21 20:21:51 +01:00
roberto@precise64 4117dd91fc ported psycopg2 example to the new api 2012-03-21 19:53:40 +01:00
roberto@precise64 508ca0df39 add realpath() for php DOCUMENT_ROOT 2012-03-21 19:28:24 +01:00
roberto@precise64 a50e356beb more verbose php debug 2012-03-21 07:50:27 +01:00
roberto@precise64 a0b7237083 added --spooler-quiet 2012-03-20 15:42:10 +01:00
roberto@precise64 08afa73e69 spooler multiprocess fixes 2012-03-20 10:58:48 +01:00
roberto@precise64 b386317921 fixed python3 reload-on-exception 2012-03-19 13:39:07 +01:00
roberto@precise64 2043127f22 fixed snmp support 2012-03-19 07:29:39 +01:00
roberto@precise64 c297a9415b started 1.2 development cycle 2012-03-18 09:03:14 +01:00
roberto@precise64 f9f9f25a01 added exception detection 2012-03-18 08:21:45 +01:00
roberto@precise64 9001af1beb better uuid detection 2012-03-17 11:01:01 +01:00
roberto@debian32 4b03f17186 python 3.x fix 2012-03-17 10:36:06 +01:00
roberto@precise64 3dbab36b91 uWSGI 1.1 2012-03-17 07:56:09 +01:00
roberto@precise64 056c890845 Added tag 1.1 for changeset e1568fd16b7b 2012-03-17 07:39:33 +01:00
roberto@precise64 4f43cd74ad env must not be immediate 2012-03-16 20:53:03 +01:00
roberto@precise64 6585b7b13d fixed pifile 2012-03-16 13:38:26 +01:00
roberto@precise64 e55048b574 fixed logdate 2012-03-16 13:07:06 +01:00
roberto@mercury 570dcde654 report listen_queue_errors 2012-03-16 06:52:48 +01:00
roberto@precise64 3cb16ee29b ready for 1.1 release 2012-03-15 20:42:41 +01:00
roberto@mailcop3 bb453da5b5 added support for SIOBKLGQ 2012-03-15 20:40:26 +01:00
roberto@precise64 1a93b68664 fixed expire_timeouts in fastrouter 2012-03-15 17:44:56 +01:00
roberto@precise64 2ce2494a50 bumped to -rc4 2012-03-15 17:36:59 +01:00
roberto@precise64 0a1e451289 Added tag 1.1-rc4 for changeset ef99144291f0 2012-03-15 17:31:05 +01:00
roberto@precise64 8ef7819080 re-included WSGI iterator close() 2012-03-15 17:29:55 +01:00
roberto@precise64 319ad13af2 allows plugin 255 to be used 2012-03-15 08:58:41 +01:00
roberto@precise4 fe28e90ae3 fixed a bug in spooler and signal plugin 2012-03-15 08:48:26 +01:00
roberto f604a0a533 bumped to 1.1-rc3 2012-03-14 18:30:19 +01:00
roberto@precise64 4ab78d42a3 Added tag 1.1-rc3 for changeset ede5c664978b 2012-03-14 18:30:02 +01:00
roberto@precise64 c631e7dae6 fixed multiple touch-reload 2012-03-14 18:29:04 +01:00
roberto@precise da8e88d638 Added tag 1.1-rc2 for changeset 901f0cb5de36 2012-03-14 12:08:58 +01:00
64 changed files with 1811 additions and 575 deletions
+4
View File
@@ -45,3 +45,7 @@ af490b8c30f83bc5fb6f3837a760981474647755 1.0-rc10
3c70927335856883283fe4db448e092cecc0ccdb 1.0
8fe7bb792399cb6e6a24e20551f4149409660363 1.0.1
1d1702789710ec1c20613d2490b14f70756e67ec 1.1-rc1
901f0cb5de36ea907b26d64ac9ce54605ec531d2 1.1-rc2
ede5c664978bb40e476e8d4a5789562928f28507 1.1-rc3
ef99144291f06822d026e981d5d856cbec14d867 1.1-rc4
e1568fd16b7b586cc72deb4dfccbbe64ae0b84df 1.1
+27
View File
@@ -1,3 +1,30 @@
*** march 2012 ***
* 1.1 [20120317]
- new options parser subsystem
- improved php support
- multiple spooler with multiprocessing
- segmentation fault and floating point exceptions manager
- never-swap option
- zergpool plugin
- perl/psgi multiple interpreters support
- deadlock detector
- pluggable cheaper algos
- new internal routing susbsystem
- preliminary support for config logic
- log rotation infrastructure
- support for paste loggers
- threading improvements
- plugins can now mapped to specific modifiers
- <app> tag is deprecated (use mount option)
- report startup time for apps
- reintroduced expat support
- reintroduced remote spooler plugin
- various fastrouter optimizations
- added ruby rvm support
*** december 2011 ***
* 1.0 [20111230]
+29 -2
View File
@@ -160,20 +160,35 @@ static int uwsgi_map_location(request_rec *r)
return DECLINED;
}
static void log_err(const char *file, int line, request_rec *r,
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
static void log_err(const char *file, int line, int ami, request_rec *r,
apr_status_t status, const char *msg)
{
ap_log_rerror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, status, r, "uwsgi: %s", msg);
#else
static void log_err(const char *file, int line, request_rec *r,
apr_status_t status, const char *msg)
{
ap_log_rerror(file, line, APLOG_ERR, status, r, "uwsgi: %s", msg);
#endif
}
static void log_debug(const char *file, int line, request_rec *r, const
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
static void log_debug(const char *file, int line, int ami, request_rec *r, const
char *msg)
{
/*
ap_log_rerror(file, line, APLOG_DEBUG, APR_SUCCESS, r, msg);
ap_log_rerror(file, line, APLOG_WARNING, APR_SUCCESS, r, "uwsgi: %s", msg);
*/
ap_log_rerror(file, line, APLOG_MODULE_INDEX, APLOG_DEBUG, APR_SUCCESS, r, "uwsgi: %s", msg);
#else
static void log_debug(const char *file, int line, request_rec *r, const
char *msg)
ap_log_rerror(file, line, APLOG_DEBUG, APR_SUCCESS, r, "uwsgi: %s", msg);
#endif
}
/* buffered socket implementation (buckets are overkill) */
@@ -412,7 +427,11 @@ send_headers(request_rec *r, struct sockbuff *s)
apr_table_t *t;
apr_status_t rv = 0;
apr_port_t port = 0;
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
GET_PORT(port, r->useragent_addr);
#else
GET_PORT(port, r->connection->remote_addr);
#endif
uwsgi_cfg *cfg = our_dconfig(r);
log_debug(APLOG_MARK,r, "sending headers");
@@ -430,7 +449,11 @@ send_headers(request_rec *r, struct sockbuff *s)
add_header(t, "REQUEST_METHOD", (char *) r->method);
add_header(t, "QUERY_STRING", r->args ? r->args : "");
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
add_header(t, "SERVER_SOFTWARE", ap_get_server_description());
#else
add_header(t, "SERVER_SOFTWARE", ap_get_server_version());
#endif
add_header(t, "SERVER_ADMIN", r->server->server_admin);
add_header(t, "SERVER_NAME", (char *) ap_get_server_name(r));
add_header(t, "SERVER_PORT", apr_psprintf(r->pool, "%u",ap_get_server_port(r)));
@@ -438,7 +461,11 @@ send_headers(request_rec *r, struct sockbuff *s)
add_header(t, "SERVER_PROTOCOL", r->protocol);
add_header(t, "REQUEST_URI", original_uri(r));
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
add_header(t, "REMOTE_ADDR", r->useragent_ip);
#else
add_header(t, "REMOTE_ADDR", r->connection->remote_ip);
#endif
add_header(t, "REMOTE_PORT", apr_psprintf(r->pool, "%d", port));
add_header(t, "REMOTE_USER", r->user);
add_header(t, "DOCUMENT_ROOT", (char *) ap_document_root(r));
+12 -1
View File
@@ -2,7 +2,7 @@
*** uWSGI/mod_uwsgi ***
Copyright 2009-2011 Unbit S.a.s. <info@unbit.it>
Copyright 2009-2012 Unbit S.a.s. <info@unbit.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -37,11 +37,18 @@ LoadModule uwsgi_module <path_of_apache_modules>/mod_uwsgi.so
*/
#include <unistd.h>
#include <ctype.h>
#include "apr_strings.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "httpd.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_config.h"
#include "http_log.h"
#include "util_script.h"
#include <sys/socket.h>
#include <sys/un.h>
@@ -346,7 +353,11 @@ static int uwsgi_handler(request_rec *r) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SERVER_PORT", apr_psprintf(r->pool, "%u",ap_get_server_port(r)), &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SERVER_PROTOCOL", r->protocol, &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REQUEST_URI", r->unparsed_uri, &pkt_size) ;
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_ADDR", r->useragent_ip, &pkt_size) ;
#else
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_ADDR", r->connection->remote_ip, &pkt_size) ;
#endif
//
if (r->user) {
+4 -4
View File
@@ -2,7 +2,7 @@
xml = true
ini = true
yaml = true
json = true
json = false
sqlite3 = false
zeromq = false
snmp = false
@@ -15,12 +15,12 @@ threading = true
sendfile = true
minterpreters = true
async = true
evdis = false
ldap = true
pcre = false
pcre = true
routing = true
debug = false
unbit = true
xml_implementation = libxml2
xml_implementation = expat
yaml_implementation = auto
malloc_implementation = libc
plugins =
+30 -5
View File
@@ -111,13 +111,14 @@ inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
uint64_t slot = uwsgi.cache_hashtable[hash_key];
struct uwsgi_cache_item *uci;
uint64_t rounds = 0;
//uwsgi_log("found slot %d for key %d\n", slot, hash_key);
uci = &uwsgi.cache_items[slot];
// first round
if (uci->djbhash != hash) goto cycle;
if (uci->djbhash != hash) return 0;
if (uci->keysize != keylen) goto cycle;
if (memcmp(uci->key, key, keylen)) goto cycle;
@@ -127,7 +128,20 @@ cycle:
while(uci->next) {
slot = uci->next;
uci = &uwsgi.cache_items[slot];
if (uci->djbhash != hash) continue;
rounds++;
if (rounds > uwsgi.cache_max_items) {
uwsgi_log("ALARM !!! cache-loop (and potential deadlock) detected slot = %llu prev = %llu next = %llu\n", uci->next, slot, uci->prev, uci->next);
// terrible case: the whole uWSGI stack can deadlock, leaving only the master alive
// if the master is avalable, trigger a brutal reload
if (uwsgi.master_process) {
kill(uwsgi.workers[0].pid, SIGTERM);
}
// otherwise kill the current worker (could be pretty useless...)
else {
exit(1);
}
}
if (uci->djbhash != hash) return 0;
if (uci->keysize != keylen) continue;
if (!memcmp(uci->key, key, keylen)) return slot;
}
@@ -154,13 +168,14 @@ char *uwsgi_cache_get(char *key, uint16_t keylen, uint64_t *valsize) {
return NULL;
}
int uwsgi_cache_del(char *key, uint16_t keylen) {
int uwsgi_cache_del(char *key, uint16_t keylen, uint64_t index) {
uint64_t index = 0;
struct uwsgi_cache_item *uci;
int ret = -1;
index = uwsgi_cache_get_index(key, keylen);
if (!index)
index = uwsgi_cache_get_index(key, keylen);
if (index) {
uci = &uwsgi.cache_items[index] ;
uci->keysize = 0;
@@ -177,9 +192,15 @@ int uwsgi_cache_del(char *key, uint16_t keylen) {
if (uci->prev) {
uwsgi.cache_items[uci->prev].next = uci->next;
}
else {
// set next as the new entry point (could be 0)
uwsgi.cache_hashtable[uci->djbhash % 0xffff] = uci->next;
}
if (uci->next) {
uwsgi.cache_items[uci->next].prev = uci->prev;
}
if (!uci->prev && !uci->next) {
// reset hashtable entry
//uwsgi_log("!!! resetted hashtable entry !!!\n");
@@ -188,6 +209,7 @@ int uwsgi_cache_del(char *key, uint16_t keylen) {
uci->djbhash = 0;
uci->prev = 0;
uci->next = 0;
uci->expires = 0;
}
return ret;
@@ -262,6 +284,9 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
ret = 0;
// now put the value in the 16bit hashtable
slot = uci->djbhash % 0xffff;
// reset values
uci->prev = 0;
uci->next = 0;
if (uwsgi.cache_hashtable[slot] == 0) {
uwsgi.cache_hashtable[slot] = index;
+12
View File
@@ -352,6 +352,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
colon[0] = 0;
}
}
// initialize to a default value
vassal_argv[1] = "--inherit";
if (!strcmp(name + (strlen(name) - 4), ".xml"))
vassal_argv[1] = "--xml";
if (!strcmp(name + (strlen(name) - 4), ".ini"))
@@ -368,7 +371,16 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
if (colon) {
colon[0] = ':';
}
vassal_argv[2] = name;
if (uwsgi.emperor_magic_exec) {
if (!access(name, R_OK|X_OK)) {
vassal_argv[2] = uwsgi_concat2("exec://", name);
}
}
counter = 3;
uct = uwsgi.vassals_templates;
while(uct) {
+18 -2
View File
@@ -1,7 +1,23 @@
import uwsgi
#uwsgi.cache_set('/', "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\nHello World from cache")
if uwsgi.loop == 'gevent':
import gevent
print uwsgi.version
print uwsgi.workers()
try:
uwsgi.cache_set('foo', "Hello World from cache")
except:
pass
def application(env, start_response):
if uwsgi.loop == 'gevent':
gevent.sleep()
start_response('200 OK', [('Content-Type', 'text/html')])
yield "foobar"
yield "foobar<br/>"
if uwsgi.loop == 'gevent':
gevent.sleep(10)
yield str(env['wsgi.input'].fileno())
yield "<h1>Hello World</h1>"
try:
yield uwsgi.cache_get('foo')
except:
pass
+78 -16
View File
@@ -45,7 +45,11 @@ static struct uwsgi_lock_item *uwsgi_register_lock(char *id, int rw) {
#ifdef UWSGI_LOCK_USE_MUTEX
#ifdef EOWNERDEAD
#define UWSGI_LOCK_ENGINE_NAME "pthread robust mutexes"
#else
#define UWSGI_LOCK_ENGINE_NAME "pthread mutexes"
#endif
#define UWSGI_LOCK_SIZE sizeof(pthread_mutex_t)
@@ -71,6 +75,13 @@ struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
exit(1);
}
#ifdef EOWNERDEAD
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP)) {
uwsgi_log("unable to make the mutex 'robust'\n");
exit(1);
}
#endif
if (pthread_mutex_init((pthread_mutex_t *) uli->lock_ptr, &attr)) {
uwsgi_log("unable to initialize mutex\n");
exit(1);
@@ -78,7 +89,9 @@ struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
pthread_mutexattr_destroy(&attr);
#ifndef EOWNERDEAD
uli->can_deadlock = 1;
#endif
return uli;
}
@@ -105,6 +118,27 @@ pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) {
#endif
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
#ifdef EOWNERDEAD
if (pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr) == EOWNERDEAD) {
uwsgi_log("[deadlock-detector] a process holding a robust mutex died. recovering...\n");
pthread_mutex_consistent_np((pthread_mutex_t *) uli->lock_ptr);
}
#else
pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr);
#endif
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
pthread_mutex_unlock((pthread_mutex_t *) uli->lock_ptr);
uli->pid = 0;
}
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
#ifdef OBSOLETE_LINUX_KERNEL
uwsgi_lock_fast(uli);
@@ -132,23 +166,10 @@ void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
#endif
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr);
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
pthread_mutex_unlock((pthread_mutex_t *) uli->lock_ptr);
uli->pid = 0;
}
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
#ifdef OBSOLETE_LINUX_KERNEL
return uwsgi_lock_fast_init(uli);
return uwsgi_lock_fast_init(id);
#else
pthread_rwlockattr_t attr;
@@ -225,6 +246,47 @@ pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); }
#elif defined(UWSGI_LOCK_USE_POSIX_SEM)
#define UWSGI_LOCK_SIZE sizeof(sem_t)
#define UWSGI_RWLOCK_SIZE sizeof(sem_t)
#define UWSGI_LOCK_ENGINE_NAME "POSIX semaphores"
#include <semaphore.h>
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
sem_init((sem_t*) uli->lock_ptr, 1, 1);
uli->can_deadlock = 1;
return uli;
}
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) { return uwsgi_lock_fast_init(id) ;}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
sem_wait((sem_t *) uli->lock_ptr);
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
sem_post((sem_t*) uli->lock_ptr);
uli->pid = 0;
}
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
if (sem_trywait((sem_t *) uli->lock_ptr) == 0) {
sem_post((sem_t*) uli->lock_ptr);
return 0;
}
return uli->pid;
}
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); }
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) { uwsgi_unlock_fast(uli); }
#elif defined(UWSGI_LOCK_USE_OSX_SPINLOCK)
#define UWSGI_LOCK_ENGINE_NAME "OSX spinlocks"
@@ -457,7 +519,7 @@ void uwsgi_setup_locking() {
int uwsgi_fcntl_lock(int fd) {
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_CUR;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = 0;
@@ -473,7 +535,7 @@ int uwsgi_fcntl_is_locked(int fd) {
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_CUR;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = 0;
+13 -2
View File
@@ -113,7 +113,7 @@ void uwsgi_check_logrotate(void) {
void log_request(struct wsgi_request *wsgi_req) {
// optimize this (please)
char *time_request;
char time_request[26];
time_t microseconds, microseconds2;
int rlen;
int app_req = -1;
@@ -160,7 +160,11 @@ void log_request(struct wsgi_request *wsgi_req) {
via = msg3;
}
time_request = ctime((const time_t *) &wsgi_req->start_of_request.tv_sec);
#ifdef __sun__
ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, time_request, 26);
#else
ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, time_request);
#endif
microseconds = wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec;
microseconds2 = wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec;
@@ -263,6 +267,13 @@ void get_memusage(uint64_t * rss, uint64_t * vsz) {
*vsz = kproc->ki_size;
*rss = kproc->ki_rssize * uwsgi.page_size;
}
#elif defined(UWSGI_NEW_OPENBSD)
struct kinfo_proc *kproc;
kproc = kvm_getprocs(kv, KERN_PROC_PID, uwsgi.mypid, sizeof(struct kinfo_proc), &cnt);
if (kproc && cnt > 0) {
*vsz = (kproc->p_vm_dsize + kproc->p_vm_ssize + kproc->p_vm_tsize) * uwsgi.page_size;
*rss = kproc->p_vm_rssize * uwsgi.page_size;
}
#elif defined(__NetBSD__) || defined(__OpenBSD__)
struct kinfo_proc2 *kproc2;
+2 -2
View File
@@ -59,7 +59,7 @@ void *simple_loop(void *arg1) {
sigdelset(&smask, SIGSEGV);
#endif
pthread_sigmask(SIG_BLOCK, &smask, NULL);
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->init_thread) {
uwsgi.p[i]->init_thread(core_id);
}
@@ -135,7 +135,7 @@ void *zeromq_loop(void *arg1) {
sigdelset(&smask, SIGSEGV);
#endif
pthread_sigmask(SIG_BLOCK, &smask, NULL);
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->init_thread) {
uwsgi.p[i]->init_thread(core_id);
}
+77 -15
View File
@@ -110,6 +110,39 @@ void *logger_thread_loop(void *noarg) {
return NULL;
}
void *cache_sweeper_loop(void *noarg) {
int i;
// block all signals
sigset_t smask;
sigfillset(&smask);
pthread_sigmask(SIG_BLOCK, &smask, NULL);
if (!uwsgi.cache_expire_freq) uwsgi.cache_expire_freq = 3;
// remove expired cache items TODO use rb_tree timeouts
for(;;) {
sleep(uwsgi.cache_expire_freq);
uint64_t freed_items = 0;
// skip the first slot
for (i = 1; i < (int) uwsgi.cache_max_items; i++) {
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi.cache_items[i].expires) {
if (uwsgi.cache_items[i].expires < (uint64_t) uwsgi.current_time) {
uwsgi_cache_del(NULL, 0, i);
freed_items++;
}
}
uwsgi_rwunlock(uwsgi.cache_lock);
}
if (uwsgi.cache_report_freed_items && freed_items > 0) {
uwsgi_log("freed %llu cache items\n", (unsigned long long) freed_items);
}
};
return NULL;
}
void uwsgi_subscribe(char *subscription, uint8_t cmd) {
int subfile_size;
@@ -230,6 +263,29 @@ void get_linux_tcp_info(int fd) {
}
}
}
#include <linux/sockios.h>
#ifdef UNBIT
#define SIOBKLGQ 0x8908
#endif
#ifdef SIOBKLGQ
void get_linux_unbit_SIOBKLGQ(int fd) {
int queue = 0;
if (ioctl(fd, SIOBKLGQ, &queue) >= 0) {
uwsgi.shared->load = queue;
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS] = queue;
if (queue >= uwsgi.listen_queue) {
uwsgi_log_verbose("*** uWSGI listen queue of socket %d full !!! (%d/%d) ***\n", fd, queue, uwsgi.listen_queue);
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_ERRORS]++;
}
}
}
#endif
#endif
@@ -256,6 +312,7 @@ int master_loop(char **argv, char **environ) {
uint64_t last_request_count = 0;
pthread_t logger_thread;
pthread_t cache_sweeper;
#ifdef UWSGI_UDP
struct sockaddr_in udp_client;
@@ -351,6 +408,16 @@ int master_loop(char **argv, char **environ) {
}
}
if (uwsgi.cache_max_items > 0 && !uwsgi.cache_no_expire) {
if (pthread_create(&cache_sweeper, NULL, cache_sweeper_loop, NULL)) {
uwsgi_error("pthread_create()");
uwsgi_log("unable to run the cache sweeper !!!\n");
}
else {
uwsgi_log("cache sweeper thread enabled\n");
}
}
uwsgi.wsgi_req->buffer = uwsgi.async_buf[0];
@@ -579,7 +646,7 @@ int master_loop(char **argv, char **environ) {
uwsgi.gp[i]->master_cycle();
}
}
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->master_cycle) {
uwsgi.p[i]->master_cycle();
}
@@ -918,7 +985,7 @@ int master_loop(char **argv, char **environ) {
// loop the various udp manager until one returns true
udp_managed = 0;
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->manage_udp) {
if (uwsgi.p[i]->manage_udp(udp_client_addr, udp_client.sin_port, uwsgi.wsgi_req->buffer, rlen)) {
udp_managed = 1;
@@ -1166,19 +1233,6 @@ int master_loop(char **argv, char **environ) {
}
}
// remove expired cache items TODO use rb_tree timeouts
if (uwsgi.cache_max_items > 0) {
for (i = 0; i < (int) uwsgi.cache_max_items; i++) {
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi.cache_items[i].expires) {
if (uwsgi.cache_items[i].expires < (uint64_t) uwsgi.current_time) {
uwsgi_cache_del(uwsgi.cache_items[i].key, uwsgi.cache_items[i].keysize);
}
}
uwsgi_rwunlock(uwsgi.cache_lock);
}
}
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval)
check_interval = 1;
@@ -1191,6 +1245,11 @@ int master_loop(char **argv, char **environ) {
if (uwsgi_sock->family == AF_INET) {
get_linux_tcp_info(uwsgi_sock->fd);
}
#ifdef SIOBKLGQ
else if (uwsgi_sock->family == AF_UNIX) {
get_linux_unbit_SIOBKLGQ(uwsgi_sock->fd);
}
#endif
uwsgi_sock = uwsgi_sock->next;
}
#endif
@@ -1535,6 +1594,9 @@ nextlock:
else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_DE_HIJACKED_CODE) {
uwsgi_log("...restoring worker %d (pid: %d)...\n", uwsgi.mywid, (int) diedpid);
}
else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_EXCEPTION_CODE) {
uwsgi_log("... monitored exception detected, respawning worker %d (pid: %d)...\n", uwsgi.mywid, (int) diedpid);
}
else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_QUIET_CODE) {
// noop
}
+73 -26
View File
@@ -8,6 +8,18 @@ void worker_wakeup() {
int uwsgi_calc_cheaper(void) {
int i;
static time_t last_check = 0;
int check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!last_check) last_check = time(NULL);
time_t now = time(NULL);
if (!check_interval)
check_interval = 1;
if ( (now - last_check) < check_interval) return 1;
last_check = now;
int needed_workers = uwsgi.cheaper_algo();
@@ -178,7 +190,7 @@ int uwsgi_cheaper_algo_backlog(void) {
int i;
#ifdef __linux__
int backlog = uwsgi.shared->ti.tcpi_unacked;
int backlog = uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS];
#else
int backlog = 0;
#endif
@@ -478,7 +490,7 @@ int uwsgi_respawn_worker(int wid) {
if (uwsgi.master_process) {
if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(1);
}
@@ -533,20 +545,36 @@ void uwsgi_manage_signal_cron(time_t now) {
uc_month = ucron->month;
uc_week = ucron->week;
if (ucron->minute == -1)
uc_minute = uwsgi_cron_delta->tm_min;
if (ucron->hour == -1)
uc_hour = uwsgi_cron_delta->tm_hour;
if (ucron->month == -1)
uc_month = uwsgi_cron_delta->tm_mon;
if (ucron->day == -1)
uc_day = uwsgi_cron_delta->tm_mday;
if (ucron->week == -1)
uc_week = uwsgi_cron_delta->tm_wday;
// negative values as interval -1 = * , -5 = */5
if (ucron->minute < 0) {
if ((uwsgi_cron_delta->tm_min % abs(ucron->minute)) == 0) {
uc_minute = uwsgi_cron_delta->tm_min;
}
}
if (ucron->hour < 0) {
if ((uwsgi_cron_delta->tm_hour % abs(ucron->hour)) == 0) {
uc_hour = uwsgi_cron_delta->tm_hour;
}
}
if (ucron->month < 0) {
if ((uwsgi_cron_delta->tm_mon % abs(ucron->month)) == 0) {
uc_month = uwsgi_cron_delta->tm_mon;
}
}
if (ucron->day < 0) {
if ((uwsgi_cron_delta->tm_mday % abs(ucron->day)) == 0) {
uc_day = uwsgi_cron_delta->tm_mday;
}
}
if (ucron->week < 0) {
if ((uwsgi_cron_delta->tm_wday % abs(ucron->week)) == 0) {
uc_week = uwsgi_cron_delta->tm_wday;
}
}
int run_task = 0;
// mday and wday are ORed
if (ucron->day != -1 && ucron->week != -1) {
if (ucron->day >= 0 && ucron->week >= 0) {
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
run_task = 1;
}
@@ -590,8 +618,10 @@ void uwsgi_manage_command_cron(time_t now) {
return;
}
while (current_cron) {
// fix month
uwsgi_cron_delta->tm_mon++;
while (current_cron) {
uc_minute = current_cron->minute;
uc_hour = current_cron->hour;
@@ -599,20 +629,36 @@ void uwsgi_manage_command_cron(time_t now) {
uc_month = current_cron->month;
uc_week = current_cron->week;
if (current_cron->minute == -1)
uc_minute = uwsgi_cron_delta->tm_min;
if (current_cron->hour == -1)
uc_hour = uwsgi_cron_delta->tm_hour;
if (current_cron->month == -1)
uc_month = uwsgi_cron_delta->tm_mon;
if (current_cron->day == -1)
uc_day = uwsgi_cron_delta->tm_mday;
if (current_cron->week == -1)
uc_week = uwsgi_cron_delta->tm_wday;
// negative values as interval -1 = * , -5 = */5
if (current_cron->minute < 0) {
if ((uwsgi_cron_delta->tm_min % abs(current_cron->minute)) == 0) {
uc_minute = uwsgi_cron_delta->tm_min;
}
}
if (current_cron->hour < 0) {
if ((uwsgi_cron_delta->tm_hour % abs(current_cron->hour)) == 0) {
uc_hour = uwsgi_cron_delta->tm_hour;
}
}
if (current_cron->month < 0) {
if ((uwsgi_cron_delta->tm_hour % abs(current_cron->month)) == 0) {
uc_month = uwsgi_cron_delta->tm_mon;
}
}
if (current_cron->day < 0) {
if ((uwsgi_cron_delta->tm_mday % abs(current_cron->day)) == 0) {
uc_day = uwsgi_cron_delta->tm_mday;
}
}
if (current_cron->week < 0) {
if ((uwsgi_cron_delta->tm_wday % abs(current_cron->week)) == 0) {
uc_week = uwsgi_cron_delta->tm_wday;
}
}
int run_task = 0;
// mday and wday are ORed
if (current_cron->day != -1 && current_cron->week != -1) {
if (current_cron->day >= 0 && current_cron->week >= 0) {
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
run_task = 1;
}
@@ -671,7 +717,8 @@ void uwsgi_send_stats(int fd) {
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
#ifdef __linux__
stats_send_llu("\"listen_queue\": %llu,\n", uwsgi.shared->ti.tcpi_unacked);
stats_send_llu("\"listen_queue\": %llu,\n", (unsigned long long) uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS]);
stats_send_llu("\"listen_queue_errors\": %llu,\n", (unsigned long long) uwsgi.shared->options[UWSGI_OPTION_BACKLOG_ERRORS]);
#endif
stats_send_llu("\"load\": %llu,\n", uwsgi.shared->load);
+4 -4
View File
@@ -48,13 +48,13 @@ void uwsgi_mule(int id) {
uwsgi_close_all_sockets();
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(1);
}
}
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->post_fork) {
uwsgi.p[i]->post_fork();
}
@@ -62,7 +62,7 @@ void uwsgi_mule(int id) {
if (uwsgi.mules[id-1].patch) {
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->mule) {
if (uwsgi.p[i]->mule(uwsgi.mules[id-1].patch) == 1) {
// never here
@@ -184,7 +184,7 @@ void uwsgi_mule_handler() {
}
else {
int i,found = 0;
for(i=0;i<0xff;i++) {
for(i=0;i<256;i++) {
if (uwsgi.p[i]->mule_msg) {
if (uwsgi.p[i]->mule_msg(message, len)) {
found = 1;
+84 -11
View File
@@ -5,7 +5,7 @@ extern struct uwsgi_server uwsgi;
static int plugin_already_loaded(const char *plugin) {
int i;
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->name) {
if (!strcmp(plugin, uwsgi.p[i]->name)) {
#ifdef UWSGI_DEBUG
@@ -50,6 +50,8 @@ static int plugin_already_loaded(const char *plugin) {
void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
void *plugin_handle = NULL;
char *plugin_abs_path = NULL;
char *plugin_filename = NULL;
int need_free = 0;
char *plugin_name = plugin;
@@ -79,35 +81,43 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
if (strchr(plugin_name, '/')) {
plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
if (!plugin_handle) {
uwsgi_log( "%s\n", dlerror());
if (!has_option)
uwsgi_log( "%s\n", dlerror());
goto end;
}
plugin_symbol_name_start = uwsgi_get_last_char(plugin_name, '/');
plugin_symbol_name_start++;
plugin_abs_path = plugin_name;
goto success;
}
// step dir, check for user-supplied plugins directory
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
while(pdir) {
char *plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
if (plugin_handle) {
free(plugin_filename);
break;
plugin_abs_path = plugin_filename;
//free(plugin_filename);
goto success;
}
free(plugin_filename);
plugin_filename = NULL;
pdir = pdir->next;
}
// last step: search in compile-time plugin_dir
if (!plugin_handle) {
char *plugin_filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin_name);
plugin_filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin_name);
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
free(plugin_filename);
plugin_abs_path = plugin_filename;
//free(plugin_filename);
}
success:
if (!plugin_handle) {
uwsgi_log( "%s\n", dlerror());
if (!has_option)
uwsgi_log( "%s\n", dlerror());
}
else {
char *plugin_entry_symbol = uwsgi_concat2n(plugin_symbol_name_start, strlen(plugin_symbol_name_start)-3, "", 0);
@@ -116,7 +126,7 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
// is it a link ?
memset(linkpath_buf, 0, 1024);
memset(linkpath, 0, 1024);
if ((linkpath_size = readlink(plugin_name, linkpath_buf, 1023)) > 0) {
if ((linkpath_size = readlink(plugin_abs_path, linkpath_buf, 1023)) > 0) {
do {
linkpath_buf[linkpath_size] = '\0';
strncpy(linkpath, linkpath_buf, linkpath_size+1);
@@ -145,6 +155,8 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
return NULL;
}
@@ -154,11 +166,13 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
return NULL;
}
if (has_option) {
struct uwsgi_option *op = uwsgi.options;
struct uwsgi_option *op = up->options;
int found = 0;
while (op && op->name) {
if (!strcmp(has_option, op->name)) {
@@ -173,6 +187,8 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
return NULL;
}
@@ -186,18 +202,75 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
if (up->on_load)
up->on_load();
return plugin_handle;
}
uwsgi_log( "%s\n", dlerror());
if (!has_option)
uwsgi_log( "%s\n", dlerror());
}
end:
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
return NULL;
}
int uwsgi_try_autoload(char *option) {
DIR *d;
struct dirent *dp;
// step dir, check for user-supplied plugins directory
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
while(pdir) {
d = opendir(pdir->value);
if (d) {
while ((dp = readdir(d)) != NULL) {
if (uwsgi_endswith(dp->d_name, "_plugin.so")) {
char *filename = uwsgi_concat3(pdir->value, "/", dp->d_name);
if (uwsgi_load_plugin(-1, filename, option)) {
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
free(filename);
closedir(d);
// add new options
build_options();
return 1;
}
free(filename);
}
}
closedir(d);
}
pdir = pdir->next;
}
// last step: search in compile-time plugin_dir
d = opendir(UWSGI_PLUGIN_DIR);
if (!d) return 0;
while((dp = readdir(d)) != NULL) {
if (uwsgi_endswith(dp->d_name, "_plugin.so")) {
char *filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", dp->d_name);
if (uwsgi_load_plugin(-1, filename, option)) {
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
free(filename);
closedir(d);
// add new options
build_options();
return 1;
}
free(filename);
}
}
closedir(d);
return 0;
}
+1 -1
View File
@@ -63,7 +63,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
case 2:
// del
if (wsgi_req->uh.pktsize > 0) {
uwsgi_cache_del(wsgi_req->buffer, wsgi_req->uh.pktsize);
uwsgi_cache_del(wsgi_req->buffer, wsgi_req->uh.pktsize, 0);
}
break;
case 3:
+1 -1
View File
@@ -17,7 +17,7 @@ int cheaper_backlog2_algo(void) {
int i;
#ifdef __linux__
int backlog = uwsgi.shared->ti.tcpi_unacked;
int backlog = uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS];
#else
int backlog = 0;
#endif
+19 -14
View File
@@ -207,6 +207,18 @@ void close_session(struct fastrouter_session *fr_session) {
#endif
}
if (ufr.subscriptions && fr_session->un && fr_session->un->len > 0) {
// decrease reference count
#ifdef UWSGI_DEBUG
uwsgi_log("[1] node %.*s refcnt: %llu\n", fr_session->un->len, fr_session->un->name, fr_session->un->reference);
#endif
fr_session->un->reference--;
#ifdef UWSGI_DEBUG
uwsgi_log("[2] node %.*s refcnt: %llu\n", fr_session->un->len, fr_session->un->name, fr_session->un->reference);
#endif
}
if (fr_session->instance_failed) {
if (fr_session->soopt) {
@@ -227,14 +239,7 @@ void close_session(struct fastrouter_session *fr_session) {
// now check for dead nodes
if (ufr.subscriptions && fr_session->un && fr_session->un->len > 0) {
// decrease reference count
#ifdef UWSGI_DEBUG
uwsgi_log("[1] node %.*s refcnt: %llu\n", fr_session->un->len, fr_session->un->name, fr_session->un->reference);
#endif
fr_session->un->reference--;
#ifdef UWSGI_DEBUG
uwsgi_log("[2] node %.*s refcnt: %llu\n", fr_session->un->len, fr_session->un->name, fr_session->un->reference);
#endif
if (fr_session->un->death_mark == 0)
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len, fr_session->instance_address);
@@ -498,8 +503,8 @@ void fastrouter_loop(int id) {
ufr.mapper = uwsgi_fr_map_use_void;
if (ufr.use_cache) {
ufr.mapper = uwsgi_fr_map_use_cache;
if (ufr.use_cache) {
ufr.mapper = uwsgi_fr_map_use_cache;
}
else if (ufr.pattern) {
ufr.mapper = uwsgi_fr_map_use_pattern;
@@ -511,8 +516,8 @@ void fastrouter_loop(int id) {
ufr.mapper = uwsgi_fr_map_use_base;
}
else if (ufr.code_string_code && ufr.code_string_function) {
ufr.mapper = uwsgi_fr_map_use_cache;
}
ufr.mapper = uwsgi_fr_map_use_cs;
}
else if (ufr.to_socket) {
ufr.mapper = uwsgi_fr_map_use_to;
}
@@ -538,7 +543,7 @@ void fastrouter_loop(int id) {
else {
delta = min_timeout->key - time(NULL);
if (delta <= 0) {
expire_timeouts(ufr.timeouts, ufr.fr_table);
expire_timeouts();
delta = 0;
}
}
@@ -554,7 +559,7 @@ void fastrouter_loop(int id) {
}
if (nevents == 0) {
expire_timeouts(ufr.timeouts, ufr.fr_table);
expire_timeouts();
}
for (i = 0; i < nevents; i++) {
+12 -11
View File
@@ -5,7 +5,7 @@ extern struct uwsgi_python up;
#define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, ugevent.greenlet_switch_args, 0, NULL); Py_DECREF(gswitch)
#define GET_CURRENT_GREENLET python_call(ugevent.get_current, ugevent.get_current_args, 0, NULL)
#define free_req_queue uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req
#define free_req_queue uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req
#define stop_the_watchers ret = PyObject_CallMethod(timer, "stop", NULL);\
if (ret) { Py_DECREF(ret); }\
ret = PyObject_CallMethod(watcher, "stop", NULL);\
@@ -24,6 +24,14 @@ struct uwsgi_gevent {
} ugevent;
struct wsgi_request *uwsgi_gevent_current_wsgi_req(void) {
PyObject *current_greenlet = GET_CURRENT_GREENLET;
PyObject *py_wsgi_req = PyObject_GetAttrString(current_greenlet, "uwsgi_wsgi_req");
return (struct wsgi_request*) PyLong_AsLong(py_wsgi_req);
}
PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) {
uint8_t uwsgi_signal;
@@ -90,7 +98,6 @@ PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {
uwsgi_log("async queue is full !!!\n");
goto clear;
}
uwsgi.wsgi_req = wsgi_req;
// fill wsgi_request structure
wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets );
@@ -107,7 +114,6 @@ PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {
// accept the connection
if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) {
uwsgi_close_request(wsgi_req);
free_req_queue;
goto clear;
}
@@ -150,10 +156,10 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
int status ;
PyObject *current_greenlet = GET_CURRENT_GREENLET;
// another hack to retrieve the current wsgi_req;
PyObject_SetAttrString(current_greenlet, "uwsgi_wsgi_req", py_wsgi_req);
PyObject *greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch");
uwsgi.wsgi_req = wsgi_req;
// create a watcher for request socket
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1);
if (!watcher) goto clear1;
@@ -167,9 +173,6 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
PyObject *ret = uwsgi_gevent_wait(watcher, timer, greenlet_switch);
if (!ret) goto clear_and_stop;
// do not forget to overwrite this pointer each time !!!
uwsgi.wsgi_req = wsgi_req;
// we can safely decref here as watcher and timer has got a +1 for start() method
Py_DECREF(ret);
if (ret == timer) {
@@ -196,7 +199,6 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
}
for(;;) {
uwsgi.wsgi_req = wsgi_req;
wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req);
if (wsgi_req->async_status <= UWSGI_OK) {
goto clear;
@@ -220,8 +222,6 @@ clear1:
Py_DECREF(current_greenlet);
uwsgi_close_request(wsgi_req);
uwsgi.wsgi_req = wsgi_req;
free_req_queue;
Py_INCREF(Py_None);
@@ -246,6 +246,7 @@ void gevent_loop() {
exit(1);
}
uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req;
PyObject *gevent_dict = get_uwsgi_pydict("gevent");
if (!gevent_dict) uwsgi_pyexit;
-1
View File
@@ -630,7 +630,6 @@ char *uwsgi_lua_code_string(char *id, char *code, char *func, char *key, uint16_
#endif
if (lua_pcall(L, 1, 1, 0) != 0) {
uwsgi_log("CAZZO\n");
uwsgi_log("error running function `f': %s",
lua_tostring(L, -1));
return NULL;
+4 -1
View File
@@ -28,7 +28,10 @@ int nagios() {
int fd = uwsgi_connect(uwsgi.sockets->name, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
if (fd < 0) {
fprintf(stdout, "UWSGI CRITICAL: could not connect() to workers\n");
fprintf(stdout, "UWSGI CRITICAL: could not connect() to workers %s\n", strerror(errno));
if (errno == EPERM || errno == EACCES) {
exit(3);
}
exit(2);
}
+42 -8
View File
@@ -20,9 +20,11 @@ struct uwsgi_php {
struct uwsgi_string_list *allowed_ext;
struct uwsgi_string_list *index;
struct uwsgi_string_list *set;
struct uwsgi_string_list *append_config;
char *docroot;
char *app;
size_t ini_size;
int dump_config;
char *server_software;
size_t server_software_len;
} uphp;
@@ -32,11 +34,12 @@ void uwsgi_opt_php_ini(char *opt, char *value, void *foobar) {
uwsgi_sapi_module.php_ini_ignore = 1;
}
struct uwsgi_option uwsgi_php_options[] = {
{"php-ini", required_argument, 0, "set php.ini path", uwsgi_opt_php_ini, NULL, 0},
{"php-config", required_argument, 0, "set php.ini path", uwsgi_opt_php_ini, NULL, 0},
{"php-ini-append", required_argument, 0, "set php.ini path (append mode)", uwsgi_opt_add_string_list, &uphp.append_config, 0},
{"php-config-append", required_argument, 0, "set php.ini path (append mode)", uwsgi_opt_add_string_list, &uphp.append_config, 0},
{"php-set", required_argument, 0, "set a php config directive", uwsgi_opt_add_string_list, &uphp.set, 0},
{"php-index", required_argument, 0, "list the php index files", uwsgi_opt_add_string_list, &uphp.index, 0},
{"php-docroot", required_argument, 0, "force php DOCUMENT_ROOT", uwsgi_opt_set_str, &uphp.docroot, 0},
@@ -44,6 +47,7 @@ struct uwsgi_option uwsgi_php_options[] = {
{"php-allowed-ext", required_argument, 0, "list the allowed php file extensions", uwsgi_opt_add_string_list, &uphp.allowed_ext, 0},
{"php-server-software", required_argument, 0, "force php SERVER_SOFTWARE", uwsgi_opt_set_str, &uphp.server_software, 0},
{"php-app", required_argument, 0, "force the php file to run at each request", uwsgi_opt_set_str, &uphp.app, 0},
{"php-dump-config", no_argument, 0, "dump php config (if modified via --php-set or append options)", uwsgi_opt_true, &uphp.dump_config, 0},
{0, 0, 0, 0, 0, 0, 0},
};
@@ -90,12 +94,11 @@ static int sapi_uwsgi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
ssize_t len = wsgi_req->socket->proto_write(wsgi_req, (char *) str, str_length);
if (len != (ssize_t) str_length) {
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, (char *) str, str_length);
if (wsgi_req->write_errors > uwsgi.write_errors_tolerance) {
php_handle_aborted_connection();
return -1;
}
wsgi_req->response_size += len;
return str_length;
}
@@ -295,6 +298,14 @@ static sapi_module_struct uwsgi_sapi_module;
void uwsgi_php_append_config(char *filename) {
int file_size = 0;
char *file_content = uwsgi_open_and_read(filename, &file_size, 1, NULL);
uwsgi_sapi_module.ini_entries = realloc(uwsgi_sapi_module.ini_entries, uphp.ini_size + file_size);
memcpy(uwsgi_sapi_module.ini_entries + uphp.ini_size, file_content, file_size);
uphp.ini_size += file_size-1;
free(file_content);
}
void uwsgi_php_set(char *opt) {
@@ -339,7 +350,7 @@ PHP_FUNCTION(uwsgi_cache_del) {
}
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_del(key, keylen)) {
if (uwsgi_cache_del(key, keylen, 0)) {
uwsgi_rwunlock(uwsgi.cache_lock);
RETURN_TRUE;
}
@@ -611,15 +622,26 @@ int uwsgi_php_init(void) {
struct http_status_codes *http_sc;
struct uwsgi_string_list *pset = uphp.set;
struct uwsgi_string_list *append_config = uphp.append_config;
sapi_startup(&uwsgi_sapi_module);
// applying custom options
while(append_config) {
uwsgi_php_append_config(append_config->value);
append_config = append_config->next;
}
while(pset) {
uwsgi_php_set(pset->value);
pset = pset->next;
}
if (uphp.dump_config) {
uwsgi_log("--- PHP custom config ---\n\n");
uwsgi_log("%s\n", uwsgi_sapi_module.ini_entries);
uwsgi_log("--- end of PHP custom config ---\n");
}
uwsgi_sapi_module.startup(&uwsgi_sapi_module);
// filling http status codes
@@ -707,13 +729,24 @@ int uwsgi_php_request(struct wsgi_request *wsgi_req) {
if (uphp.docroot) {
wsgi_req->document_root = uphp.docroot;
wsgi_req->document_root_len = strlen(wsgi_req->document_root);
}
// fallback to cwd
else if (!wsgi_req->document_root_len) {
wsgi_req->document_root = uwsgi.cwd;
wsgi_req->document_root_len = strlen(uwsgi.cwd);
}
else {
// explode DOCUMENT_ROOT (both for security and sanity checks)
// this memory will be cleared on request end
char *sanitized_docroot = ecalloc(1, PATH_MAX+1);
if (!uwsgi_expand_path(wsgi_req->document_root, wsgi_req->document_root_len, sanitized_docroot)) {
efree(sanitized_docroot);
return -1;
}
wsgi_req->document_root = sanitized_docroot;
}
// fix document_root_len
wsgi_req->document_root_len = strlen(wsgi_req->document_root);
if (uphp.app) {
strcpy(real_filename, uphp.app);
@@ -837,7 +870,8 @@ secure2:
wsgi_req->script_name_len = strlen(wsgi_req->script_name);
#ifdef UWSGI_DEBUG
uwsgi_log("php filename = %s %.*s\n", real_filename, wsgi_req->script_name_len, wsgi_req->script_name);
uwsgi_log("php filename = %s script_name = %.*s (%d) document_root = %.*s (%d)\n", real_filename, wsgi_req->script_name_len, wsgi_req->script_name, wsgi_req->script_name_len,
wsgi_req->document_root_len, wsgi_req->document_root, wsgi_req->document_root_len);
#endif
+1
View File
@@ -20,6 +20,7 @@ struct uwsgi_perl {
char *embedding[3];
// check for Devel::StackTrace
int no_die_catch;
int stacktrace_available;
// this is a pointer to the main list of interpreters (required for signals, rpc....);
+6 -4
View File
@@ -384,10 +384,12 @@ int init_psgi_app(struct wsgi_request *wsgi_req, char *app, uint16_t app_len, Pe
perl_eval_pv("use IO::Handle;", 0);
perl_eval_pv("use IO::File;", 0);
perl_eval_pv("use Devel::StackTrace;", 0);
if (!SvTRUE(ERRSV)) {
uperl.stacktrace_available = 1;
perl_eval_pv("$SIG{__DIE__} = \\&uwsgi::stacktrace;", 0);
if (!uperl.no_die_catch) {
perl_eval_pv("use Devel::StackTrace;", 0);
if (!SvTRUE(ERRSV)) {
uperl.stacktrace_available = 1;
perl_eval_pv("$SIG{__DIE__} = \\&uwsgi::stacktrace;", 0);
}
}
SV *dollar_zero = get_sv("0", GV_ADD);
+2 -7
View File
@@ -12,6 +12,7 @@ struct uwsgi_perl uperl;
struct uwsgi_option uwsgi_perl_options[] = {
{"psgi", required_argument, 0, "load a psgi app", uwsgi_opt_set_str, &uperl.psgi, 0},
{"perl-no-die-catch", no_argument, 0, "do not catch $SIG{__DIE__}", uwsgi_opt_true, &uperl.no_die_catch, 0},
{"perl-local-lib", required_argument, 0, "set perl locallib path", uwsgi_opt_set_str, &uperl.locallib, 0},
{0, 0, 0, 0, 0, 0, 0},
@@ -471,19 +472,13 @@ int uwsgi_perl_magic(char *mountpoint, char *lazy) {
// taken from Torsten Foertsch AfterFork.xs
void uwsgi_perl_post_fork() {
/*
GV *tmpgv;
PL_ppid = (IV)getppid();
hv_clear(PL_pidstatus);
tmpgv = gv_fetchpv("$", TRUE, SVt_PV);
GV *tmpgv = gv_fetchpv("$", TRUE, SVt_PV);
if (tmpgv) {
SvREADONLY_off(GvSV(tmpgv));
sv_setiv(GvSV(tmpgv), (IV)getpid());
SvREADONLY_on(GvSV(tmpgv));
}
*/
}
int uwsgi_perl_mount_app(char *mountpoint, char *app, int regexp) {
+1 -3
View File
@@ -126,9 +126,7 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
vi = (i*2)+base;
wsgi_req->hvec[vi].iov_base = "\r\n"; wsgi_req->hvec[vi].iov_len = 2;
if ( !(wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, vi+1)) ) {
uwsgi_error("writev()");
}
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, vi+1);
hitem = av_fetch(response, 2, 0);
+16 -2
View File
@@ -76,13 +76,21 @@ XS(XS_wait_fd_write) {
#endif
XS(XS_signal) {
dXSARGS;
psgi_check_args(1);
uwsgi_signal_send(uwsgi.signal_socket, SvIV(ST(0)));
XSRETURN_UNDEF;
}
XS(XS_reload) {
dXSARGS;
psgi_check_args(0);
psgi_check_args(0);
uwsgi_log("SENDING HUP TO %d\n", (int) uwsgi.workers[0].pid);
if (kill(uwsgi.workers[0].pid, SIGHUP)) {
uwsgi_error("kill()");
XSRETURN_NO;
@@ -104,7 +112,9 @@ XS(XS_cache_set) {
key = SvPV(ST(0), keylen);
val = SvPV(ST(1), vallen);
uwsgi_wlock(uwsgi.cache_lock);
uwsgi_cache_set(key, (uint16_t) keylen, val, (uint64_t) vallen, 0, 0);
uwsgi_rwunlock(uwsgi.cache_lock);
clear:
XSRETURN_UNDEF;
@@ -123,13 +133,16 @@ XS(XS_cache_get) {
key = SvPV(ST(0), keylen);
uwsgi_rlock(uwsgi.cache_lock);
val = uwsgi_cache_get(key, (uint16_t) keylen, &vallen);
if (!val)
uwsgi_rwunlock(uwsgi.cache_lock);
clear:
XSRETURN_UNDEF;
ST(0) = newSVpv(val, vallen);
uwsgi_rwunlock(uwsgi.cache_lock);
sv_2mortal(ST(0));
XSRETURN(1);
@@ -215,5 +228,6 @@ void init_perl_embedded_module() {
psgi_xs(log);
psgi_xs(async_connect);
psgi_xs(suspend);
psgi_xs(signal);
}
+13
View File
@@ -0,0 +1,13 @@
import os,sys
from distutils import sysconfig
NAME='pypy'
GCC_LIST = ['../python/python_plugin', '../python/pyutils', '../python/pyloader', '../python/wsgi_handlers', '../python/wsgi_headers', '../python/wsgi_subhandler',
'../python/web3_subhandler', '../python/pump_subhandler','../python/gil', '../python/uwsgi_pymodule', '../python/profiler', '../python/symimporter']
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ]
CFLAGS.append('-DUWSGI_PYPY')
LIBS = ['-lpypy-c']
LDFLAGS = []
+2 -8
View File
@@ -3,14 +3,9 @@
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
#ifdef UWSGI_PYPY
void gil_real_get() {}
void gil_real_release() {}
#else
void gil_real_get() {
//uwsgi_log("LOCK %d\n", uwsgi.mywid);
#ifndef PYTHREE
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
PyEval_AcquireLock();
PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_gil_key));
#else
@@ -22,7 +17,7 @@ void gil_real_get() {
void gil_real_release() {
//uwsgi_log("UNLOCK %d\n", uwsgi.mywid);
#ifndef PYTHREE
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
pthread_setspecific(up.upt_gil_key, (void *) PyThreadState_Swap(NULL));
PyEval_ReleaseLock();
#else
@@ -31,7 +26,6 @@ void gil_real_release() {
#endif
}
#endif
void gil_fake_get() {}
void gil_fake_release() {}
+37 -2
View File
@@ -16,15 +16,27 @@ int PyFrame_GetLineNumber(PyFrameObject *frame) {
int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) {
#ifndef UWSGI_PYPY
static uint64_t last_ts = 0;
uint64_t now = uwsgi_micros();
uint64_t delta = 0;
switch(what) {
case PyTrace_CALL:
uwsgi_log("[uWSGI Python profiler] CALL: %s (line %d) -> %s %d args, stacksize %d\n",
if (last_ts == 0) delta = 0;
else delta = now - last_ts;
last_ts = now;
uwsgi_log("[uWSGI Python profiler %llu] CALL: %s (line %d) -> %s %d args, stacksize %d\n",
(unsigned long long) delta,
PyString_AsString(frame->f_code->co_filename),
PyFrame_GetLineNumber(frame),
PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount, frame->f_code->co_stacksize);
break;
case PyTrace_C_CALL:
uwsgi_log("[uWSGI Python profiler] C CALL: %s (line %d) -> %s %d args, stacksize %d\n",
if (last_ts == 0) delta = 0;
else delta = now - last_ts;
last_ts = now;
uwsgi_log("[uWSGI Python profiler %llu] C CALL: %s (line %d) -> %s %d args, stacksize %d\n",
(unsigned long long) delta,
PyString_AsString(frame->f_code->co_filename),
PyFrame_GetLineNumber(frame),
PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize);
@@ -34,3 +46,26 @@ int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, Py
return 0;
}
int uwsgi_python_tracer(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) {
#ifndef UWSGI_PYPY
static uint64_t last_ts = 0;
uint64_t now = uwsgi_micros();
uint64_t delta = 0;
if (what == PyTrace_LINE) {
if (last_ts == 0) {
delta = 0;
}
else {
delta = now - last_ts;
}
last_ts = now;
uwsgi_log("[uWSGI Python profiler %llu] file %s line %d: %s argc:%d\n", (unsigned long long)delta, PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount);
}
#endif
return 0;
}
-11
View File
@@ -185,8 +185,6 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {
struct http_status_codes *http_sc;
char sc[4];
UWSGI_GET_GIL
// ok its a yield
if (!wsgi_req->async_placeholder) {
if (PyDict_Check((PyObject *)wsgi_req->async_result)) {
@@ -339,7 +337,6 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {
}
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1) {
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
}
#endif
@@ -371,22 +368,14 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {
Py_DECREF(pychunk);
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
clear:
if (wsgi_req->async_input) {
Py_DECREF((PyObject *)wsgi_req->async_input);
}
if (wsgi_req->async_environ) {
PyDict_Clear(wsgi_req->async_environ);
}
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
Py_DECREF((PyObject *)wsgi_req->async_result);
PyErr_Clear();
UWSGI_RELEASE_GIL
return UWSGI_OK;
}
+6 -10
View File
@@ -425,7 +425,8 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
doh:
free(mountpoint);
PyErr_Print();
if (PyErr_Occurred())
PyErr_Print();
#ifdef UWSGI_MINTERPRETERS
if (interpreter == NULL && id) {
Py_EndInterpreter(wi->interpreter);
@@ -481,9 +482,7 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
PyObject *tmp_callable;
PyObject *applications;
#ifndef UWSGI_PYPY
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
#endif
char *module = (char *) arg1;
@@ -506,11 +505,8 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
return NULL;
}
#ifndef UWSGI_PYPY
applications = PyDict_GetItemString(uwsgi_dict, "applications");
if (applications && PyDict_Check(applications)) return applications;
#endif
applications = PyDict_GetItemString(wsgi_dict, "applications");
if (applications && PyDict_Check(applications)) return applications;
@@ -714,8 +710,10 @@ PyObject *uwsgi_paste_loader(void *arg1) {
PyObject *uwsgi_eval_loader(void *arg1) {
#ifndef UWSGI_PYPY
#ifdef UWSGI_PYPY
uwsgi_log("the eval loader is currently not supported under PyPy !!!\n");
return NULL;
#else
char *code = (char *) arg1;
PyObject *wsgi_eval_module, *wsgi_eval_callable = NULL;
@@ -771,8 +769,6 @@ PyObject *uwsgi_eval_loader(void *arg1) {
}
return wsgi_eval_callable;
#else
return NULL;
#endif
}
+205 -34
View File
@@ -108,8 +108,6 @@ struct uwsgi_option uwsgi_python_options[] = {
{"ini-paste", required_argument, 0, "load a paste.deploy config file containing uwsgi section", uwsgi_opt_ini_paste, NULL, UWSGI_OPT_IMMEDIATE},
{"ini-paste-logged", required_argument, 0, "load a paste.deploy config file containing uwsgi section (load loggers too)", uwsgi_opt_ini_paste, NULL, UWSGI_OPT_IMMEDIATE},
#endif
{"catch-exceptions", no_argument, 0, "report exception has http output (discouraged)", uwsgi_opt_true, &up.catch_exceptions, 0},
{"ignore-script-name", no_argument, 0, "ignore SCRIPT_NAME", uwsgi_opt_true, &up.ignore_script_name, 0},
{"reload-os-env", no_argument, 0, "force reload of os.environ at each request", uwsgi_opt_true, &up.reload_os_env, 0},
#ifndef UWSGI_PYPY
{"no-site", no_argument, 0, "do not import site module", uwsgi_opt_true, &Py_NoSiteFlag, 0},
@@ -121,6 +119,14 @@ struct uwsgi_option uwsgi_python_options[] = {
{"py", required_argument, 0, "run a python script in the uWSGI environment", uwsgi_opt_pyrun, NULL, 0},
{"pyrun", required_argument, 0, "run a python script in the uWSGI environment", uwsgi_opt_pyrun, NULL, 0},
#ifdef UWSGI_THREADING
{"py-auto-reload", required_argument, 0, "monitor python modules mtime to trigger reload (use only in development)", uwsgi_opt_set_int, &up.auto_reload, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER},
{"py-autoreload", required_argument, 0, "monitor python modules mtime to trigger reload (use only in development)", uwsgi_opt_set_int, &up.auto_reload, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER},
{"python-auto-reload", required_argument, 0, "monitor python modules mtime to trigger reload (use only in development)", uwsgi_opt_set_int, &up.auto_reload, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER},
{"python-autoreload", required_argument, 0, "monitor python modules mtime to trigger reload (use only in development)", uwsgi_opt_set_int, &up.auto_reload, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER},
{"py-auto-reload-ignore", required_argument, 0, "ignore the specified module during auto-reload scan (can be specified multiple times)", uwsgi_opt_add_string_list, &up.auto_reload_ignore, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER},
#endif
{0, 0, 0, 0, 0, 0, 0},
};
@@ -149,7 +155,6 @@ int uwsgi_python_init() {
uwsgi_log_initial("PyPy version: %s\n", PYPY_VERSION);
#endif
#ifndef UWSGI_PYPY
if (up.home != NULL) {
#ifdef PYTHREE
wchar_t *wpyhome;
@@ -168,23 +173,22 @@ int uwsgi_python_init() {
uwsgi_log("Set PythonHome to %s\n", up.home);
}
#ifdef PYTHREE
wchar_t pname[6];
mbstowcs(pname, "uWSGI", 6);
Py_SetProgramName(pname);
#else
Py_SetProgramName("uWSGI");
#endif
#ifndef UWSGI_PYPY
Py_OptimizeFlag = up.optimize;
#endif
Py_Initialize();
#endif
up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL);
up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL);
@@ -206,7 +210,6 @@ int uwsgi_python_init() {
void uwsgi_python_reset_random_seed() {
#ifndef UWSGI_PYPY
PyObject *random_module, *random_dict, *random_seed;
// reinitialize the random seed (thanks Jonas Borgström)
@@ -217,6 +220,9 @@ void uwsgi_python_reset_random_seed() {
random_seed = PyDict_GetItemString(random_dict, "seed");
if (random_seed) {
PyObject *random_args = PyTuple_New(1);
#ifdef UWSGI_PYPY
Py_INCREF(Py_None);
#endif
// pass no args
PyTuple_SetItem(random_args, 0, Py_None);
PyEval_CallObject(random_seed, random_args);
@@ -226,7 +232,6 @@ void uwsgi_python_reset_random_seed() {
}
}
}
#endif
}
@@ -288,7 +293,6 @@ void uwsgi_python_post_fork() {
uwsgi_python_reset_random_seed();
#ifndef UWSGI_PYPY
#ifdef UWSGI_EMBEDDED
// call the post_fork_hook
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
@@ -300,7 +304,16 @@ void uwsgi_python_post_fork() {
}
PyErr_Clear();
#endif
if (uwsgi.mywid > 0) {
#ifdef UWSGI_THREADING
if (up.auto_reload) {
// spawn the reloader thread
pthread_t par_tid;
pthread_create(&par_tid, NULL, uwsgi_python_autoreloader_thread, NULL);
}
#endif
}
UWSGI_RELEASE_GIL
@@ -308,7 +321,10 @@ UWSGI_RELEASE_GIL
PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
#ifndef UWSGI_PYPY
#ifdef UWSGI_PYPY
uwsgi_log("import by filename is currently not supported on PyPy !!!\n");
return NULL;
#else
FILE *pyfile;
struct _node *py_file_node = NULL;
PyObject *py_compiled_node, *py_file_module;
@@ -376,6 +392,14 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
return NULL;
}
if (is_a_package) {
py_file_module = PyImport_AddModule(name);
if (py_file_module) {
PyModule_AddObject(py_file_module, "__path__", Py_BuildValue("[O]", PyString_FromString(filename)));
}
free(real_filename);
}
py_file_module = PyImport_ExecCodeModule(name, py_compiled_node);
if (!py_file_module) {
PyErr_Print();
@@ -384,17 +408,7 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
Py_DECREF(py_compiled_node);
if (is_a_package) {
PyObject *py_file_module_dict = PyModule_GetDict(py_file_module);
if (py_file_module_dict) {
PyDict_SetItemString(py_file_module_dict, "__path__", Py_BuildValue("[O]", PyString_FromString(filename)));
}
free(real_filename);
}
return py_file_module;
#else
return NULL;
#endif
}
@@ -450,7 +464,7 @@ void init_uwsgi_vars() {
char *value = strchr(uppma->value, '=');
if (!value) {
uwsgi_log("invalid pymodule-alias syntax\n");
continue;
goto next;
}
value[0] = 0;
if (!strchr(value + 1, '/')) {
@@ -475,6 +489,7 @@ void init_uwsgi_vars() {
// reset original value
value[0] = '=';
next:
uppma = uppma->next;
}
@@ -538,6 +553,7 @@ void init_uwsgi_embedded_module() {
// just for safety
Py_INCREF(up.embedded_dict);
if (PyDict_SetItemString(up.embedded_dict, "version", PyString_FromString(UWSGI_VERSION))) {
PyErr_Print();
exit(1);
@@ -639,6 +655,9 @@ void init_uwsgi_embedded_module() {
exit(1);
}
}
else {
PyDict_SetItemString(up.embedded_dict, "loop", Py_None);
}
PyObject *py_opt_dict = PyDict_New();
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
@@ -912,18 +931,14 @@ void uwsgi_python_preinit_apps() {
init_pyargv();
#ifndef UWSGI_PYPY
#ifdef UWSGI_EMBEDDED
init_uwsgi_embedded_module();
#endif
#endif
#ifdef __linux__
#ifndef UWSGI_PYPY
#ifdef UWSGI_EMBEDDED
uwsgi_init_symbol_import();
#endif
#endif
#endif
if (up.test_module != NULL) {
@@ -955,13 +970,13 @@ void uwsgi_python_init_apps() {
struct http_status_codes *http_sc;
#ifndef UWSGI_PYPY
// prepare for stack suspend/resume
if (uwsgi.async > 1) {
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
#ifndef UWSGI_PYPY
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
#endif
}
#endif
// setup app loaders
#ifdef UWSGI_MINTERPRETERS
@@ -997,7 +1012,7 @@ void uwsgi_python_init_apps() {
char *value = strchr(uppa->value, '=');
if (!value) {
uwsgi_log("invalid pymodule-alias syntax\n");
continue;
goto next;
}
value[0] = 0;
if (!strchr(value + 1, '/')) {
@@ -1022,6 +1037,7 @@ void uwsgi_python_init_apps() {
// reset original value
value[0] = '=';
next:
uppa = uppa->next;
}
@@ -1053,13 +1069,16 @@ void uwsgi_python_init_apps() {
init_uwsgi_app(LOADER_UWSGI, up.wsgi_lite, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI_LITE);
}
if (uwsgi.profiler) {
#ifndef UWSGI_PYPY
if (uwsgi.profiler) {
if (!strcmp(uwsgi.profiler, "pycall")) {
PyEval_SetProfile(uwsgi_python_profiler_call, NULL);
}
#endif
else if (!strcmp(uwsgi.profiler, "pyline")) {
PyEval_SetTrace(uwsgi_python_tracer, NULL);
}
}
#endif
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
if (uwsgi_dict) {
@@ -1167,6 +1186,150 @@ void uwsgi_python_init_thread(int core_id) {
}
#ifdef UWSGI_THREADING
int uwsgi_check_python_mtime(PyObject *times_dict, uint64_t cycles, char *filename) {
struct stat st;
PyObject *py_mtime = PyDict_GetItemString(times_dict, filename);
if (!py_mtime) {
if (cycles == 0) {
if (stat(filename, &st)) {
return 0;
}
PyDict_SetItemString(times_dict, filename, PyLong_FromLong(st.st_mtime));
}
else {
uwsgi_log("[uwsgi-python-reloader] found new module/file: %s\n", filename);
kill(uwsgi.workers[0].pid, SIGHUP);
return 1;
}
}
// the record is already tracked;
else {
long mtime = PyLong_AsLong(py_mtime);
if (stat(filename, &st)) {
return 0;
}
if ((long) st.st_mtime != mtime) {
uwsgi_log("[uwsgi-python-reloader] module/file %s has been modified\n", filename);
kill(uwsgi.workers[0].pid, SIGHUP);
return 1;
}
}
return 0;
}
void *uwsgi_python_autoreloader_thread(void *foobar) {
PyObject *modules;
// block signals on this thread
sigset_t smask;
sigfillset(&smask);
#ifndef UWSGI_DEBUG
sigdelset(&smask, SIGSEGV);
#endif
pthread_sigmask(SIG_BLOCK, &smask, NULL);
PyThreadState *pts = PyThreadState_New(up.main_thread->interp);
pthread_setspecific(up.upt_save_key, (void *) pts);
pthread_setspecific(up.upt_gil_key, (void *) pts);
UWSGI_GET_GIL;
PyObject *threading_module = PyImport_ImportModule("threading");
if (threading_module) {
PyObject *threading_module_dict = PyModule_GetDict(threading_module);
if (threading_module_dict) {
#ifdef PYTHREE
PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "current_thread");
#else
PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "currentThread");
#endif
if (threading_current) {
PyObject *current_thread = PyEval_CallObject(threading_current, (PyObject *)NULL);
if (!current_thread) {
// ignore the error
PyErr_Clear();
}
else {
PyObject_SetAttrString(current_thread, "name", PyString_FromString("uWSGIAutoReloader"));
Py_INCREF(current_thread);
modules = PyImport_GetModuleDict();
goto cycle;
}
}
}
}
return NULL;
cycle:
if (uwsgi.mywid == 1) {
uwsgi_log("Python auto-reloader enabled\n");
}
PyObject *times_dict = PyDict_New();
char *filename;
uint64_t cycles = 0;
for(;;) {
UWSGI_RELEASE_GIL;
sleep(up.auto_reload);
UWSGI_GET_GIL;
// do not start monitoring til the first app is loaded (required for lazy mode)
if (uwsgi_apps_cnt == 0) continue;
#ifdef UWSGI_PYTHON_OLD
int pos = 0;
#else
Py_ssize_t pos = 0;
#endif
PyObject *mod_name, *mod;
while (PyDict_Next(modules, &pos, &mod_name, &mod)) {
int found = 0;
struct uwsgi_string_list *usl = up.auto_reload_ignore;
while(usl) {
if (!strcmp(usl->value, PyString_AsString(mod_name))) {
found = 1;
break;
}
usl = usl->next;
}
if (found) continue;
if (!PyObject_HasAttrString(mod, "__file__")) continue;
PyObject *mod_file = PyObject_GetAttrString(mod, "__file__");
if (!mod_file) continue;
#ifdef PYTHREE
PyObject *zero = PyUnicode_AsUTF8String(mod_file);
char *mod_filename = PyString_AsString(zero);
#else
char *mod_filename = PyString_AsString(mod_file);
#endif
if (!mod_filename) {
#ifdef PYTHREE
Py_DECREF(zero);
#endif
continue;
}
char *ext = strrchr(mod_filename, '.');
if (ext && (!strcmp(ext+1, "pyc") || !strcmp(ext+1, "pyd") || !strcmp(ext+1, "pyo"))) {
filename = uwsgi_concat2n(mod_filename, strlen(mod_filename)-1, "", 0);
}
else {
filename = uwsgi_concat2(mod_filename, "");
}
if (uwsgi_check_python_mtime(times_dict, cycles, filename)) {
UWSGI_RELEASE_GIL;
return NULL;
}
free(filename);
#ifdef PYTHREE
Py_DECREF(zero);
#endif
}
cycles++;
}
return NULL;
}
#endif
#ifndef UWSGI_PYPY
void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
@@ -1406,6 +1569,7 @@ void uwsgi_python_hijack(void) {
// the pyshell will be execute only in the first worker
#ifndef UWSGI_PYPY
FILE *pyfile;
if (up.pyrun) {
uwsgi.workers[uwsgi.mywid].hijacked = 1;
@@ -1419,8 +1583,8 @@ void uwsgi_python_hijack(void) {
// could be never executed
exit(0);
}
#endif
#ifndef UWSGI_PYPY
if (up.pyshell_oneshot && uwsgi.workers[uwsgi.mywid].hijacked_count > 0) {
uwsgi.workers[uwsgi.mywid].hijacked = 0;
return;
@@ -1439,6 +1603,8 @@ void uwsgi_python_hijack(void) {
}
UWSGI_GET_GIL;
PyImport_ImportModule("readline");
#ifndef UWSGI_PYPY
int ret = PyRun_InteractiveLoop(stdin, "uwsgi");
if (up.pyshell_oneshot) {
@@ -1448,9 +1614,9 @@ void uwsgi_python_hijack(void) {
if (ret == 0) {
exit(UWSGI_QUIET_CODE);
}
#endif
exit(0);
}
#endif
}
int uwsgi_python_mule(char *opt) {
@@ -1495,9 +1661,14 @@ int uwsgi_python_mule_msg(char *message, size_t len) {
return 1;
}
struct uwsgi_plugin python_plugin = {
#ifndef UWSGI_PYPY
struct uwsgi_plugin python_plugin = {
.name = "python",
#else
struct uwsgi_plugin pypy_plugin = {
.name = "pypy",
#endif
.alias = "python",
.modifier1 = 0,
.init = uwsgi_python_init,
+98 -7
View File
@@ -8,20 +8,106 @@ int manage_python_response(struct wsgi_request *wsgi_req) {
return uwsgi_response_subhandler_wsgi(wsgi_req);
}
PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi_request *wsgi_req) {
char *uwsgi_python_get_exception_type(PyObject *exc) {
char *class_name = NULL;
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
if (PyClass_Check(exc)) {
class_name = PyString_AsString( ((PyClassObject*)(exc))->cl_name );
}
else {
#endif
class_name = (char *) ((PyTypeObject*)exc)->tp_name;
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
}
#endif
PyObject *pyret;
if (class_name) {
char *dot = strrchr(class_name, '.');
if (dot) class_name = dot+1;
PyObject *module_name = PyObject_GetAttrString(exc, "__module__");
if (module_name) {
char *mod_name = PyString_AsString(module_name);
if (mod_name && strcmp(mod_name, "exceptions") ) {
char *ret = uwsgi_concat3(mod_name, ".", class_name);
Py_DECREF(module_name);
return ret;
}
Py_DECREF(module_name);
return uwsgi_str(class_name);
}
}
return NULL;
}
char *uwsgi_python_get_exception_value(PyObject *value) {
return PyString_AsString( PyObject_Str(value) );
}
char *uwsgi_python_get_exception_repr(PyObject *exc, PyObject *value) {
char *exc_type = uwsgi_python_get_exception_type(exc);
char *exc_value = uwsgi_python_get_exception_value(value);
if (exc_type && exc_value) {
return uwsgi_concat3(exc_type, ": ", exc_value);
}
return NULL;
}
int uwsgi_python_manage_exceptions(void) {
PyObject *type = NULL;
PyObject *value = NULL;
PyObject *traceback = NULL;
char *exc_type = NULL;
char *exc_value = NULL;
char *exc_repr = NULL;
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
if (uwsgi.reload_on_exception_type) {
exc_type = uwsgi_python_get_exception_type(type);
}
if (uwsgi.reload_on_exception_value) {
exc_value = uwsgi_python_get_exception_value(value);
}
if (uwsgi.reload_on_exception_repr) {
exc_repr = uwsgi_python_get_exception_repr(type, value);
}
int ret = uwsgi_manage_exception(exc_type, exc_value, exc_repr);
// free memory allocated for strcmp
if (exc_type) free(exc_type);
if (exc_repr) free(exc_repr);
PyErr_Restore(type, value, traceback);
return ret;
}
PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi_request *wsgi_req) {
//uwsgi_log("ready to call %p %p\n", callable, args);
pyret = PyEval_CallObject(callable, args);
PyObject *pyret = PyEval_CallObject(callable, args);
//uwsgi_log("called\n");
if (PyErr_Occurred()) {
int do_exit = uwsgi_python_manage_exceptions();
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
uwsgi_log("Memory Error detected !!!\n");
}
// this can be in a spooler or in the master
if (uwsgi.mywid > 0) {
uwsgi.workers[uwsgi.mywid].exceptions++;
@@ -32,6 +118,10 @@ PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi
if (!catch) {
PyErr_Print();
}
if (do_exit) {
exit(UWSGI_EXCEPTION_CODE);
}
}
#ifdef UWSGI_DEBUG
@@ -71,7 +161,7 @@ void init_pyargv() {
}
#ifdef PYTHREE
wchar_t *pname = uwsgi_calloc(strlen(argv0)+1);
wchar_t *pname = uwsgi_calloc(sizeof(wchar_t) * (strlen(argv0)+1));
mbstowcs(pname, argv0, strlen(argv0)+1);
#else
char *pname = argv0;
@@ -106,17 +196,18 @@ void init_pyargv() {
if (up.argv) {
char *py_argv_copy = uwsgi_str(up.argv);
up.argc = 1;
#ifdef PYTHREE
wchar_t *wcargv = uwsgi_calloc( sizeof( wchar_t ) * (strlen(up.argv)+1));
wchar_t *wcargv = uwsgi_calloc( sizeof( wchar_t ) * (strlen(py_argv_copy)+1));
#endif
#ifdef __sun__
// FIX THIS !!!
ap = strtok(up.argv, " ");
ap = strtok(py_argv_copy, " ");
while ((ap = strtok(NULL, " ")) != NULL) {
#else
while ((ap = strsep(&up.argv, " \t")) != NULL) {
while ((ap = strsep(&py_argv_copy, " \t")) != NULL) {
#endif
if (*ap != '\0') {
#ifdef PYTHREE
+107 -92
View File
@@ -171,7 +171,7 @@ char *uwsgi_encode_pydict(PyObject * pydict, uint16_t * size) {
PyObject *py_uwsgi_listen_queue(PyObject * self, PyObject * args) {
#ifdef __linux__
return PyInt_FromLong(uwsgi.shared->ti.tcpi_unacked);
return PyInt_FromLong(uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS]);
#else
return NULL;
#endif
@@ -1715,6 +1715,8 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
}
}
UWSGI_RELEASE_GIL
if (numprio) {
priority = uwsgi_num2str(numprio);
}
@@ -1725,6 +1727,8 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
free(spool_buffer);
UWSGI_GET_GIL
Py_DECREF(spool_vars);
if (i > 0) {
@@ -3134,7 +3138,7 @@ PyObject *py_uwsgi_cache_del(PyObject * self, PyObject * args) {
else if (uwsgi.cache_max_items) {
UWSGI_RELEASE_GIL
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_del(key, keylen)) {
if (uwsgi_cache_del(key, keylen, 0)) {
uwsgi_rwunlock(uwsgi.cache_lock);
UWSGI_GET_GIL
Py_INCREF(Py_None);
@@ -3249,15 +3253,25 @@ PyObject *py_uwsgi_cache_exists(PyObject * self, PyObject * args) {
if (remote && strlen(remote) > 0) {
// TODO FIX THIS !!!
UWSGI_RELEASE_GIL
uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
UWSGI_GET_GIL
if (valsize > 0) {
Py_INCREF(Py_True);
return Py_True;
}
}
else if (uwsgi_cache_exists(key, keylen)) {
Py_INCREF(Py_True);
return Py_True;
else if (uwsgi.cache_max_items) {
UWSGI_RELEASE_GIL
uwsgi_rlock(uwsgi.cache_lock);
if (uwsgi_cache_exists(key, keylen)) {
uwsgi_rwunlock(uwsgi.cache_lock);
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
uwsgi_rwunlock(uwsgi.cache_lock);
UWSGI_GET_GIL
}
Py_INCREF(Py_None);
@@ -3349,29 +3363,29 @@ PyObject *py_uwsgi_queue_pull(PyObject * self, PyObject * args) {
char *message;
uint64_t size;
PyObject *res;
char *storage;
if (uwsgi.queue_size) {
UWSGI_RELEASE_GIL
uwsgi_wlock(uwsgi.queue_lock);
message = uwsgi_queue_pull(&size);
UWSGI_GET_GIL
if (message && size > 0) {
res = PyString_FromStringAndSize(NULL, size);
#ifdef PYTHREE
char *storage = PyBytes_AsString(res);
#else
char *storage = PyString_AS_STRING(res);
#endif
UWSGI_RELEASE_GIL
memcpy(storage, message, size);
}
else {
if (!message || size == 0) {
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
Py_INCREF(Py_None);
res = Py_None;
UWSGI_RELEASE_GIL
return Py_None;
}
storage = uwsgi_malloc(size);
memcpy(storage, message, size);
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
res = PyString_FromStringAndSize(storage, size);
free(storage);
return res;
}
@@ -3385,29 +3399,29 @@ PyObject *py_uwsgi_queue_pop(PyObject * self, PyObject * args) {
char *message;
uint64_t size;
PyObject *res;
char *storage;
if (uwsgi.queue_size) {
UWSGI_RELEASE_GIL
uwsgi_wlock(uwsgi.queue_lock);
message = uwsgi_queue_pop(&size);
UWSGI_GET_GIL
if (message && size > 0) {
res = PyString_FromStringAndSize(NULL, size);
#ifdef PYTHREE
char *storage = PyBytes_AsString(res);
#else
char *storage = PyString_AS_STRING(res);
#endif
UWSGI_RELEASE_GIL
memcpy(storage, message, size);
}
else {
if (!message || size == 0) {
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
Py_INCREF(Py_None);
res = Py_None;
UWSGI_RELEASE_GIL
}
return Py_None;
}
storage = uwsgi_malloc(size);
memcpy(storage, message, size);
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
res = PyString_FromStringAndSize(storage, size);
free(storage);
return res;
}
@@ -3423,6 +3437,7 @@ PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
uint64_t size = 0;
char *message;
PyObject *res;
char *storage;
if (!PyArg_ParseTuple(args, "l:queue_get", &index)) {
return NULL;
@@ -3431,25 +3446,23 @@ PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
if (uwsgi.queue_size) {
UWSGI_RELEASE_GIL
uwsgi_rlock(uwsgi.queue_lock);
message = uwsgi_queue_get(index, &size);
UWSGI_GET_GIL
if (message && size > 0) {
res = PyString_FromStringAndSize(NULL, size);
#ifdef PYTHREE
char *storage = PyBytes_AsString(res);
#else
char *storage = PyString_AS_STRING(res);
#endif
UWSGI_RELEASE_GIL
memcpy(storage, message, size);
}
else {
if (!message || size == 0) {
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
Py_INCREF(Py_None);
res = Py_None;
UWSGI_RELEASE_GIL
}
return Py_None;
}
storage = uwsgi_malloc(size);
memcpy(storage, message, size);
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
res = PyString_FromStringAndSize(storage, size);
free(storage);
return res;
}
@@ -3459,11 +3472,12 @@ PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
long num = 0;
long i, num = 0;
uint64_t size = 0;
char *message;
PyObject *res = NULL;
uint64_t base;
char *storage;
if (!PyArg_ParseTuple(args, "|l:queue_last", &num)) {
return NULL;
@@ -3487,50 +3501,41 @@ PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
if (num == 0) {
message = uwsgi_queue_get(base, &size);
UWSGI_GET_GIL
if (message && size > 0) {
res = PyString_FromStringAndSize(NULL, size);
#ifdef PYTHREE
char *storage = PyBytes_AsString(res);
#else
char *storage = PyString_AS_STRING(res);
#endif
UWSGI_RELEASE_GIL
memcpy(storage, message, size);
}
else {
if (!message || size == 0) {
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
Py_INCREF(Py_None);
res = Py_None;
UWSGI_RELEASE_GIL
}
return Py_None;
}
storage = uwsgi_malloc(size);
memcpy(storage, message, size);
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
res = PyString_FromStringAndSize(storage, size);
free(storage);
return res;
}
if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
char **queue_items = uwsgi_malloc(sizeof(char *) * num);
uint64_t *queue_items_size = uwsgi_malloc(sizeof(uint64_t) * num);
long item_pos = 0;
while(num) {
message = uwsgi_queue_get(base, &size);
UWSGI_GET_GIL
if (message && size) {
PyObject *zero = PyString_FromStringAndSize(NULL, size);
PyList_Append(res, zero);
Py_DECREF(zero);
#ifdef PYTHREE
char *storage = PyBytes_AsString(res);
#else
char *storage = PyString_AS_STRING(res);
#endif
UWSGI_RELEASE_GIL
memcpy(storage, message, size);
}
else {
UWSGI_RELEASE_GIL
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
return res;
if (!message || size == 0) {
queue_items[item_pos] = NULL;
queue_items_size[item_pos] = 0;
}
else {
queue_items[item_pos] = uwsgi_malloc(size);
memcpy(queue_items[item_pos], message, size);
queue_items_size[item_pos] = size;
}
item_pos++;
if (base > 0) {
base--;
}
@@ -3539,9 +3544,24 @@ PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
}
num--;
}
UWSGI_RELEASE_GIL
uwsgi_rwunlock(uwsgi.queue_lock);
UWSGI_GET_GIL
for(i=0;i<item_pos;i++) {
if (queue_items[i]) {
PyObject *zero = PyString_FromStringAndSize(queue_items[i], queue_items_size[i]);
PyList_Append(res, zero);
Py_DECREF(zero);
free(queue_items[i]);
}
else {
Py_INCREF(Py_None);
PyList_Append(res, Py_None);
}
}
free(queue_items);
free(queue_items_size);
return res;
}
@@ -3591,14 +3611,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
ret = PyString_FromStringAndSize(NULL, valsize);
#ifdef PYTHREE
char *storage = PyBytes_AsString(ret);
#else
char *storage = PyString_AS_STRING(ret);
#endif
UWSGI_RELEASE_GIL
char *storage = uwsgi_malloc(valsize);
#ifdef UWSGI_DEBUG
gettimeofday(&tv2, NULL);
if ((tv2.tv_sec* (1000*1000) + tv2.tv_usec) - (tv.tv_sec* (1000*1000) + tv.tv_usec) > 30000) {
@@ -3608,6 +3621,8 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
memcpy(storage, value, valsize);
uwsgi_rwunlock(uwsgi.cache_lock);
UWSGI_GET_GIL
ret = PyString_FromStringAndSize(storage, valsize);
free(storage);
return ret;
}
+14 -3
View File
@@ -38,6 +38,14 @@
#define PyVarObject_HEAD_INIT(x, y) PyObject_HEAD_INIT(x) y,
#endif
#define uwsgi_py_write_set_exception(x) PyErr_SetString(PyExc_IOError, "write error");
#define uwsgi_py_write_exception(x) uwsgi_py_write_set_exception(x); PyErr_Print();
#define uwsgi_py_check_write_errors if (wsgi_req->write_errors > 0 && uwsgi.write_errors_exception_only) {\
uwsgi_py_write_set_exception(wsgi_req);\
}\
else if (wsgi_req->write_errors > uwsgi.write_errors_tolerance)\
PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int);
PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
@@ -136,9 +144,6 @@ struct uwsgi_python {
char *callable;
int ignore_script_name;
int catch_exceptions;
int *current_recursion_depth;
struct _frame **current_frame;
@@ -154,6 +159,8 @@ struct uwsgi_python {
pthread_mutex_t lock_pyloaders;
void (*gil_get) (void);
void (*gil_release) (void);
int auto_reload;
struct uwsgi_string_list *auto_reload_ignore;
#endif
PyObject *workers_tuple;
@@ -251,10 +258,14 @@ void simple_reset_ts(struct wsgi_request *, struct uwsgi_app *);
void simple_threaded_reset_ts(struct wsgi_request *, struct uwsgi_app *);
int uwsgi_python_profiler_call(PyObject *, PyFrameObject *, int, PyObject *);
int uwsgi_python_tracer(PyObject *, PyFrameObject *, int, PyObject *);
void uwsgi_python_reset_random_seed(void);
char *uwsgi_pythonize(char *);
void *uwsgi_python_autoreloader_thread(void *);
int uwsgi_python_manage_exceptions(void);
#ifdef UWSGI_PYPY
#undef UWSGI_MINTERPRETERS
+14 -19
View File
@@ -134,9 +134,6 @@ void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_
int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
PyObject *pychunk;
ssize_t wsize;
UWSGI_GET_GIL
// ok its a yield
if (!wsgi_req->async_placeholder) {
@@ -170,11 +167,14 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
Py_DECREF(spit_args);
if (PyString_Check((PyObject *)wsgi_req->async_placeholder)) {
if ((wsize = wsgi_req->socket->proto_write(wsgi_req, PyString_AsString(wsgi_req->async_placeholder), PyString_Size(wsgi_req->async_placeholder))) < 0) {
uwsgi_error("write()");
goto clear;
char *content = PyString_AsString(wsgi_req->async_placeholder);
size_t content_len = PyString_Size(wsgi_req->async_placeholder);
UWSGI_RELEASE_GIL
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, content, content_len);
UWSGI_GET_GIL
uwsgi_py_check_write_errors {
uwsgi_py_write_exception(wsgi_req);
}
wsgi_req->response_size += wsize;
goto clear;
}
@@ -189,7 +189,6 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
}
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1) {
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
}
#endif
@@ -211,32 +210,28 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
if (PyString_Check(pychunk)) {
if ((wsize = wsgi_req->socket->proto_write(wsgi_req, PyString_AsString(pychunk), PyString_Size(pychunk))) < 0) {
uwsgi_error("write()");
char *content = PyString_AsString(pychunk);
size_t content_len = PyString_Size(pychunk);
UWSGI_RELEASE_GIL
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, content, content_len);
UWSGI_GET_GIL
uwsgi_py_check_write_errors {
uwsgi_py_write_exception(wsgi_req);
Py_DECREF(pychunk);
goto clear;
}
wsgi_req->response_size += wsize;
}
Py_DECREF(pychunk);
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
clear:
if (wsgi_req->async_input) {
Py_DECREF((PyObject *)wsgi_req->async_input);
}
if (wsgi_req->async_environ) {
PyDict_Clear(wsgi_req->async_environ);
}
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
Py_DECREF((PyObject *)wsgi_req->async_result);
PyErr_Clear();
UWSGI_RELEASE_GIL
return UWSGI_OK;
}
+18 -4
View File
@@ -278,6 +278,12 @@ PyObject *py_uwsgi_write(PyObject * self, PyObject * args) {
UWSGI_RELEASE_GIL
wsgi_req->response_size = wsgi_req->socket->proto_write(wsgi_req, content, len);
UWSGI_GET_GIL
// this is a special case for the write callable
// no need to honout write-errors-exception-only
if (wsgi_req->write_errors > uwsgi.write_errors_tolerance) {
uwsgi_py_write_set_exception(wsgi_req);
return NULL;
}
}
Py_INCREF(Py_None);
@@ -363,7 +369,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
if (wsgi_req->appid_len == 0) {
if (!up.ignore_script_name) {
if (!uwsgi.ignore_script_name) {
wsgi_req->appid = wsgi_req->script_name;
wsgi_req->appid_len = wsgi_req->script_name_len;
}
@@ -445,8 +451,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
wsgi_req->async_result = wi->request_subhandler(wsgi_req, wi);
UWSGI_RELEASE_GIL
if (wsgi_req->async_result) {
@@ -466,7 +470,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
}
else if (up.catch_exceptions) {
else if (uwsgi.catch_exceptions) {
// LOCK THIS PART
@@ -501,6 +505,16 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
close(tmp_stderr);
}
// this object must be freed/cleared always
if (wsgi_req->async_input) {
Py_DECREF((PyObject *)wsgi_req->async_input);
}
if (wsgi_req->async_environ) {
PyDict_Clear(wsgi_req->async_environ);
}
UWSGI_RELEASE_GIL
clear:
up.reset_ts(wsgi_req, wi);
+5
View File
@@ -201,6 +201,11 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
UWSGI_GET_GIL
#endif
if (wsgi_req->write_errors > uwsgi.write_errors_tolerance) {
uwsgi_py_write_set_exception(wsgi_req);
return NULL;
}
//uwsgi_log("%d %p\n", wsgi_req->poll.fd, up.wsgi_writeout);
Py_INCREF(up.wsgi_writeout);
+36 -30
View File
@@ -28,7 +28,7 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
#endif
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
Py_DECREF(pydictkey);
Py_DECREF(pydictvalue);
Py_DECREF(pydictvalue);
}
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
@@ -48,7 +48,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
}
#ifndef UWSGI_PYPY
// if async_post is mapped as a file, directly use it as wsgi.input
if (wsgi_req->async_post) {
#ifdef PYTHREE
@@ -69,7 +68,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input);
#endif
#ifdef UWSGI_SENDFILE
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile);
@@ -85,11 +83,9 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version);
#ifndef UWSGI_PYPY
zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL);
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero);
Py_DECREF(zero);
#endif
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False);
@@ -108,6 +104,7 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_True);
}
if (wsgi_req->scheme_len > 0) {
zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len);
}
@@ -125,16 +122,12 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.url_scheme", zero);
Py_DECREF(zero);
wsgi_req->async_app = wi->callable;
// export .env only in non-threaded mode
#ifndef UWSGI_PYPY
if (uwsgi.threads < 2) {
PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
}
#endif
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);
@@ -159,26 +152,26 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
// call
PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ);
return python_call(wsgi_req->async_app, wsgi_req->async_args, up.catch_exceptions, wsgi_req);
return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req);
}
int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
PyObject *pychunk;
ssize_t wsize;
#ifdef UWSGI_SENDFILE
ssize_t sf_len = 0;
#endif
UWSGI_GET_GIL
// return or yield ?
if (PyString_Check((PyObject *)wsgi_req->async_result)) {
if ((wsize = wsgi_req->socket->proto_write(wsgi_req, PyString_AsString(wsgi_req->async_result), PyString_Size(wsgi_req->async_result))) < 0) {
uwsgi_error("write()");
goto clear;
char *content = PyString_AsString(wsgi_req->async_result);
size_t content_len = PyString_Size(wsgi_req->async_result);
UWSGI_RELEASE_GIL
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, content, content_len);
UWSGI_GET_GIL
uwsgi_py_check_write_errors {
uwsgi_py_write_exception(wsgi_req);
}
wsgi_req->response_size += wsize;
goto clear;
}
@@ -195,7 +188,6 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1) {
if (wsgi_req->response_size < wsgi_req->sendfile_fd_size) {
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
}
}
@@ -213,7 +205,6 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
}
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1) {
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
}
#endif
@@ -224,15 +215,34 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
pychunk = PyIter_Next(wsgi_req->async_placeholder);
if (!pychunk) {
if (PyErr_Occurred()) {
int do_exit = uwsgi_python_manage_exceptions();
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
uwsgi_log("Memory Error detected !!!\n");
}
uwsgi.workers[uwsgi.mywid].exceptions++;
uwsgi_apps[wsgi_req->app_id].exceptions++;
PyErr_Print();
if (do_exit) {
exit(UWSGI_EXCEPTION_CODE);
}
}
if (PyObject_HasAttrString((PyObject *)wsgi_req->async_result, "close")) {
PyObject *close_method = PyObject_GetAttrString((PyObject *)wsgi_req->async_result, "close");
PyObject *close_method_args = PyTuple_New(0);
#ifdef UWSGI_DEBUG
uwsgi_log("calling close() for %.*s %p %p\n", wsgi_req->uri_len, wsgi_req->uri, close_method, close_method_args);
#endif
PyObject *close_method_output = PyEval_CallObject(close_method, close_method_args);
if (PyErr_Occurred()) {
PyErr_Print();
}
Py_DECREF(close_method_args);
Py_XDECREF(close_method_output);
Py_DECREF(close_method);
}
goto clear;
}
@@ -240,12 +250,16 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
if (PyString_Check(pychunk)) {
if ((wsize = wsgi_req->socket->proto_write(wsgi_req, PyString_AsString(pychunk), PyString_Size(pychunk))) < 0) {
uwsgi_error("write()");
char *content = PyString_AsString(pychunk);
size_t content_len = PyString_Size(pychunk);
UWSGI_RELEASE_GIL
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, content, content_len);
UWSGI_GET_GIL
uwsgi_py_check_write_errors {
uwsgi_py_write_exception(wsgi_req);
Py_DECREF(pychunk);
goto clear;
}
wsgi_req->response_size += wsize;
}
#ifdef UWSGI_SENDFILE
@@ -258,7 +272,6 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
Py_DECREF(pychunk);
UWSGI_RELEASE_GIL
return UWSGI_AGAIN;
clear:
@@ -266,18 +279,11 @@ clear:
if (wsgi_req->sendfile_fd != -1) {
Py_DECREF((PyObject *)wsgi_req->async_sendfile);
}
if (wsgi_req->async_input) {
Py_DECREF((PyObject *)wsgi_req->async_input);
}
if (wsgi_req->async_environ) {
PyDict_Clear(wsgi_req->async_environ);
}
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
clear2:
Py_DECREF((PyObject *)wsgi_req->async_result);
PyErr_Clear();
UWSGI_RELEASE_GIL
return UWSGI_OK;
}
+1 -1
View File
@@ -347,7 +347,7 @@ VALUE rack_uwsgi_cache_del(VALUE *class, VALUE rbkey) {
size_t keylen = RSTRING_LEN(rbkey);
uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_del(key, keylen)) {
if (uwsgi_cache_del(key, keylen, 0)) {
uwsgi_rwunlock(uwsgi.cache_lock);
return Qfalse;
}
+15 -11
View File
@@ -110,7 +110,18 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) {
int chunk_size;
if (!wsgi_req->post_cl || wsgi_req->buf_pos >= wsgi_req->post_cl) {
return Qnil;
/*
When EOF is reached, this method returns nil if length is given and not nil, or "" if length is not given or is nil.
If buffer is given, then the read data will be placed into buffer instead of a newly created String object.
*/
if (RARRAY_LEN(args) > 0) {
if (RARRAY_PTR(args)[0] == Qnil) {
return rb_str_new("", 0);
}
return Qnil;
}
return rb_str_new("", 0);
}
if (RARRAY_LEN(args) == 0) {
@@ -509,18 +520,15 @@ VALUE call_dispatch(VALUE env) {
static VALUE send_body(VALUE obj) {
struct wsgi_request *wsgi_req = current_wsgi_req();
ssize_t len = 0;
//uwsgi_log("sending body\n");
if (TYPE(obj) == T_STRING) {
len = wsgi_req->socket->proto_write( wsgi_req, RSTRING_PTR(obj), RSTRING_LEN(obj));
wsgi_req->response_size += wsgi_req->socket->proto_write( wsgi_req, RSTRING_PTR(obj), RSTRING_LEN(obj));
}
else {
uwsgi_log("UNMANAGED BODY TYPE %d\n", TYPE(obj));
}
wsgi_req->response_size += len;
return Qnil;
}
@@ -754,9 +762,7 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
wsgi_req->hvec[5].iov_base = (char *) "\r\n";
wsgi_req->hvec[5].iov_len = 2 ;
if ( !(wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, 6)) ) {
uwsgi_error("writev()");
}
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, 6);
headers = RARRAY_PTR(ret)[1] ;
if (rb_respond_to( headers, rb_intern("each") )) {
@@ -767,9 +773,7 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
}
}
if (wsgi_req->socket->proto_write(wsgi_req, (char *)"\r\n", 2) != 2) {
uwsgi_error("write()");
}
wsgi_req->socket->proto_write(wsgi_req, (char *)"\r\n", 2);
body = RARRAY_PTR(ret)[2] ;
+7 -2
View File
@@ -7,6 +7,7 @@ extern struct uwsgi_server uwsgi;
ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) {
char buf[MAX_SYSLOG_PKT];
char ctime_storage[26];
time_t current_time;
int portn = 514;
int rlen;
@@ -55,8 +56,12 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len)
// drop newline
if (message[len-1] == '\n') len--;
rlen = snprintf(buf, MAX_SYSLOG_PKT, "<29>%.*s %s: %.*s", 15, ctime(&current_time)+4, (char *) ul->data, (int) len, message);
#ifdef __sun__
ctime_r(&current_time, ctime_storage, 26);
#else
ctime_r(&current_time, ctime_storage);
#endif
rlen = snprintf(buf, MAX_SYSLOG_PKT, "<29>%.*s %s: %.*s", 15, ctime_storage+4, (char *) ul->data, (int) len, message);
if (rlen > 0) {
return sendto(ul->fd, buf, rlen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len);
}
+5 -4
View File
@@ -7,14 +7,15 @@ int uwsgi_request_signal(struct wsgi_request *wsgi_req) {
ssize_t len;
uint8_t ret_status = 1;
struct uwsgi_header uh;
if (uwsgi_signal_send(uwsgi.signal_socket, wsgi_req->uh.modifier2) < 0) {
ret_status = 0;
}
wsgi_req->uh.modifier1 = 255;
wsgi_req->uh.pktsize = 0;
wsgi_req->uh.modifier2 = ret_status;
len = write(wsgi_req->poll.fd, wsgi_req, 4);
uh.modifier1 = 255;
uh.pktsize = 0;
uh.modifier2 = ret_status;
len = write(wsgi_req->poll.fd, &uh, 4);
if (len != 4) {
uwsgi_error("write()");
}
+7 -6
View File
@@ -12,6 +12,7 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
int i;
char spool_filename[1024];
struct uwsgi_header uh;
// get the spooler from the modifier2
@@ -24,11 +25,11 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
}
i = spool_request(uspool, spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize, NULL, 0, NULL, 0);
wsgi_req->uh.modifier1 = 255;
wsgi_req->uh.pktsize = 0;
uh.modifier1 = 255;
uh.pktsize = 0;
if (i > 0) {
wsgi_req->uh.modifier2 = 1;
if (write(wsgi_req->poll.fd, wsgi_req, 4) != 4) {
uh.modifier2 = 1;
if (write(wsgi_req->poll.fd, &uh, 4) != 4) {
uwsgi_log("disconnected client, remove spool file.\n");
/* client disconnect, remove spool file */
if (unlink(spool_filename)) {
@@ -41,8 +42,8 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
}
else {
/* announce a failed spool request */
wsgi_req->uh.modifier2 = 0;
i = write(wsgi_req->poll.fd, wsgi_req, 4);
uh.modifier2 = 0;
i = write(wsgi_req->poll.fd, &uh, 4);
if (i != 4) {
uwsgi_error("write()");
}
+71 -2
View File
@@ -4,9 +4,63 @@
extern struct uwsgi_server uwsgi;
struct uwsgi_syslog_facility {
const char *name;
int facility;
};
struct uwsgi_syslog_facility usf[] = {
{ "auth", LOG_AUTH, },
#ifdef LOG_AUTHPRIV
{ "authpriv", LOG_AUTHPRIV, },
#endif
{ "cron", LOG_CRON, },
{ "daemon", LOG_DAEMON, },
#ifdef LOG_FTP
{ "ftp", LOG_FTP, },
#endif
#ifdef LOG_INSTALL
{ "install", LOG_INSTALL },
#endif
{ "kern", LOG_KERN, },
{ "lpr", LOG_LPR, },
{ "mail", LOG_MAIL, },
#ifdef INTERNAL_MARK
{ "mark", INTERNAL_MARK, }, /* INTERNAL */
#endif
#ifdef LOG_NETINFO
{ "netinfo", LOG_NETINFO, },
#endif
#ifdef LOG_RAS
{ "ras", LOG_RAS },
#endif
#ifdef LOG_REMOTEAUTH
{ "remoteauth", LOG_REMOTEAUTH },
#endif
{ "news", LOG_NEWS, },
{ "security", LOG_AUTH }, /* DEPRECATED */
{ "syslog", LOG_SYSLOG, },
{ "user", LOG_USER, },
{ "uucp", LOG_UUCP, },
{ "local0", LOG_LOCAL0, },
{ "local1", LOG_LOCAL1, },
{ "local2", LOG_LOCAL2, },
{ "local3", LOG_LOCAL3, },
{ "local4", LOG_LOCAL4, },
{ "local5", LOG_LOCAL5, },
{ "local6", LOG_LOCAL6, },
{ "local7", LOG_LOCAL7, },
#ifdef LOG_LAUNCHD
{ "launchd", LOG_LAUNCHD },
#endif
{ NULL, -1, }
};
ssize_t uwsgi_syslog_logger(struct uwsgi_logger *ul, char *message, size_t len) {
char *syslog_opts;
int facility = LOG_DAEMON;
if (!ul->configured) {
@@ -16,10 +70,25 @@ ssize_t uwsgi_syslog_logger(struct uwsgi_logger *ul, char *message, size_t len)
syslog_opts = "uwsgi";
}
else {
syslog_opts = uwsgi.choosen_logger_arg;
char *colon = strchr(uwsgi.choosen_logger_arg, ',');
if (colon) {
struct uwsgi_syslog_facility *fn = usf;
while(fn->name) {
if (!strcmp(fn->name, colon+1)) {
facility = fn->facility;
break;
}
fn++;
}
syslog_opts = uwsgi_str(uwsgi.choosen_logger_arg);
syslog_opts[colon-uwsgi.choosen_logger_arg] = 0;
}
else {
syslog_opts = uwsgi.choosen_logger_arg;
}
}
openlog(syslog_opts, 0, LOG_DAEMON);
openlog(syslog_opts, 0, facility);
ul->configured = 1;
}
+29 -9
View File
@@ -193,22 +193,42 @@ ssize_t uwsgi_proto_fastcgi_write(struct wsgi_request * wsgi_req, char *buf, siz
if (len <= 65535) {
rlen = write(wsgi_req->poll.fd, &fr, 8);
if (rlen <= 0) {
return rlen;
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("write()");
}
wsgi_req->write_errors++;
return 0;
}
return write(wsgi_req->poll.fd, buf, len);
rlen = write(wsgi_req->poll.fd, buf, len);
if (rlen <= 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("write()");
}
wsgi_req->write_errors++;
return 0;
}
return rlen;
}
else {
while(len > 0) {
chunk_len = UMIN(65535, len);
fr.cl = htons(chunk_len);
rlen = write(wsgi_req->poll.fd, &fr, 8);
if (rlen <= 0) {
return rlen;
}
if (rlen != 8) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("write()");
}
wsgi_req->write_errors++;
return 0;
}
rlen = write(wsgi_req->poll.fd, ptr, chunk_len);
if (rlen <= 0) {
return rlen;
}
if (rlen != 8) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("write()");
}
wsgi_req->write_errors++;
return 0;
}
ptr += rlen;
len -= rlen;
}
@@ -224,7 +244,7 @@ ssize_t uwsgi_proto_fastcgi_write_header(struct wsgi_request * wsgi_req, char *b
void uwsgi_proto_fastcgi_close(struct wsgi_request *wsgi_req) {
if (write(wsgi_req->poll.fd, FCGI_END_REQUEST, 24) <= 0) {
uwsgi_error("write()");
uwsgi_req_error("write()");
}
uwsgi_proto_base_close(wsgi_req);
-16
View File
@@ -369,19 +369,3 @@ int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) {
return UWSGI_AGAIN;
}
ssize_t uwsgi_proto_http_writev_header(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
return writev(wsgi_req->poll.fd, iovec, iov_len);
}
ssize_t uwsgi_proto_http_writev(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
return writev(wsgi_req->poll.fd, iovec, iov_len);
}
ssize_t uwsgi_proto_http_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
return write(wsgi_req->poll.fd, buf, len);
}
ssize_t uwsgi_proto_http_write_header(struct wsgi_request * wsgi_req, char *buf, size_t len) {
return write(wsgi_req->poll.fd, buf, len);
}
+27 -21
View File
@@ -114,38 +114,44 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) {
return -1;
}
ssize_t uwsgi_proto_uwsgi_writev_header(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
ssize_t uwsgi_proto_uwsgi_writev_header(struct wsgi_request *wsgi_req, struct iovec * iovec, size_t iov_len) {
if (iov_len == 0) return 0;
ssize_t wlen = writev(wsgi_req->poll.fd, iovec, iov_len);
if (wlen < 0) {
uwsgi_req_error("writev()");
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("writev()");
}
wsgi_req->write_errors++;
return 0;
}
return wlen;
}
ssize_t uwsgi_proto_uwsgi_writev(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
ssize_t wlen = writev(wsgi_req->poll.fd, iovec, iov_len);
if (wlen < 0) {
uwsgi_req_error("writev()");
return 0;
}
return wlen;
ssize_t uwsgi_proto_uwsgi_writev(struct wsgi_request *wsgi_req, struct iovec * iovec, size_t iov_len) {
return uwsgi_proto_uwsgi_writev_header(wsgi_req, iovec, iov_len);
}
ssize_t uwsgi_proto_uwsgi_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
ssize_t wlen = write(wsgi_req->poll.fd, buf, len);
if (wlen < 0) {
uwsgi_req_error("write()");
return 0;
ssize_t wlen;
char *ptr = buf;
if (len == 0) return 0;
while(len > 0) {
wlen = write(wsgi_req->poll.fd, ptr, len);
if (wlen <= 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("write()");
}
wsgi_req->write_errors++;
return ptr-buf;
}
ptr+=wlen;
len -= wlen;
}
return wlen;
return ptr-buf;
}
ssize_t uwsgi_proto_uwsgi_write_header(struct wsgi_request * wsgi_req, char *buf, size_t len) {
ssize_t wlen = write(wsgi_req->poll.fd, buf, len);
if (wlen < 0) {
uwsgi_req_error("write()");
return 0;
}
return wlen;
ssize_t uwsgi_proto_uwsgi_write_header(struct wsgi_request *wsgi_req, char *buf, size_t len) {
return uwsgi_proto_uwsgi_write(wsgi_req, buf, len);
}
+27 -3
View File
@@ -96,6 +96,17 @@ static int uwsgi_mongrel2_json_parse(json_t * root, struct wsgi_request *wsgi_re
}
}
if ((json_val = uwsgi_mongrel2_json_get_string(root, "x-forwarded-for"))) {
char *colon = strchr(json_val, ',');
if (colon) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, colon + 1, (colon + 1) - json_val);
}
else {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, json_val, strlen(json_val));
}
}
if ((json_val = uwsgi_mongrel2_json_get_string(root, "content-length"))) {
wsgi_req->post_cl = atoi(json_val);
}
@@ -205,6 +216,15 @@ static int uwsgi_mongrel2_tnetstring_parse(struct wsgi_request *wsgi_req, char *
async_upload += 2;
free(post_filename);
}
else if (!uwsgi_strncmp("x-forwarded-for", 15, key, keylen)) {
char *colon = strchr(val, ',');
if (colon) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, colon + 1, (colon + 1) - val);
}
else {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, val, vallen);
}
}
else if (!uwsgi_strncmp("x-mongrel2-upload-start", 23, key, keylen)) {
async_upload += 1;
}
@@ -415,7 +435,8 @@ ssize_t uwsgi_proto_zeromq_writev_header(struct wsgi_request *wsgi_req, struct i
for (i = 0; i < (int) iov_len; i++) {
len = uwsgi_proto_zeromq_write(wsgi_req, iovec[i].iov_base, iovec[i].iov_len);
if (len <= 0) {
return len;
wsgi_req->write_errors++;
return 0;
}
ret += len;
}
@@ -441,10 +462,13 @@ ssize_t uwsgi_proto_zeromq_write(struct wsgi_request * wsgi_req, char *buf, size
zmq_msg_init_data(&reply, zmq_body, wsgi_req->proto_parser_pos + len, uwsgi_proto_zeromq_free, NULL);
if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.zmq_lock);
if (zmq_send(uwsgi.zmq_pub, &reply, 0)) {
uwsgi_error("zmq_send()");
if (!uwsgi.ignore_write_errors) {
uwsgi_error("zmq_send()");
}
wsgi_req->write_errors++;
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.zmq_lock);
zmq_msg_close(&reply);
return -1;
return 0;
}
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.zmq_lock);
zmq_msg_close(&reply);
+13 -1
View File
@@ -958,9 +958,15 @@ nextsm:
// finally check for docroot
if (uwsgi.check_static_docroot && wsgi_req->document_root_len > 0) {
if (!uwsgi_file_serve(wsgi_req, wsgi_req->document_root, wsgi_req->document_root_len, wsgi_req->path_info, wsgi_req->path_info_len)) {
char *real_docroot = uwsgi_expand_path(wsgi_req->document_root, wsgi_req->document_root_len, NULL);
if (!real_docroot) {
return -1;
}
if (!uwsgi_file_serve(wsgi_req, real_docroot, strlen(real_docroot), wsgi_req->path_info, wsgi_req->path_info_len)) {
free(real_docroot);
return -1;
}
free(real_docroot);
}
return 0;
@@ -1641,7 +1647,13 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
int mime_type_size = 0;
char http_last_modified[49];
#ifdef UWSGI_THREADING
if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static);
#endif
char *mime_type = uwsgi_get_mime_type(real_filename, real_filename_len, &mime_type_size);
#ifdef UWSGI_THREADING
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static);
#endif
if (wsgi_req->if_modified_since_len) {
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
if (st.st_mtime <= ims) {
+8 -8
View File
@@ -31,15 +31,15 @@ def patch_bin_path(cmd, conf):
bin_name = conf.get('bin_name')
try:
if not os.path.exists(cmd.install_scripts):
os.makedirs(cmd.install_scripts)
if not os.path.isabs(bin_name):
print('Patching "bin_name" to properly install_scripts dir')
if not os.path.isabs(bin_name):
print('Patching "bin_name" to properly install_scripts dir')
try:
if not os.path.exists(cmd.install_scripts):
os.makedirs(cmd.install_scripts)
conf.set('bin_name',
os.path.join(cmd.install_scripts, conf.get('bin_name')))
except:
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
os.path.join(cmd.install_scripts, conf.get('bin_name')))
except:
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
class uWSGIBuilder(build_ext):
+2 -2
View File
@@ -354,8 +354,8 @@ static int get_snmp_integer(uint8_t * ptr, uint64_t * val) {
void uwsgi_opt_snmp(char *opt, char *value, void *foobar) {
uwsgi.snmp = 1;
if (value) {
uwsgi.snmp_addr = optarg;
uwsgi.master_process = 1;
uwsgi.snmp_addr = value;
uwsgi.master_process = 1;
}
}
+45 -6
View File
@@ -915,6 +915,7 @@ struct uwsgi_socket *uwsgi_new_shared_socket(char *name) {
memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
uwsgi_sock->name = name;
uwsgi_sock->fd = -1;
return uwsgi_sock;
}
@@ -942,6 +943,7 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) {
memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
uwsgi_sock->name = name;
uwsgi_sock->fd = -1;
if (!name)
return uwsgi_sock;
@@ -1220,12 +1222,11 @@ void uwsgi_add_sockets_to_queue(int queue) {
uwsgi_sock->fd = connect_to_sctp(uwsgi_sock->name, queue);
uwsgi_sock->queue = queue;
}
else {
else
#endif
event_queue_add_fd_read(queue, uwsgi_sock->fd);
#ifdef UWSGI_SCTP
if (uwsgi_sock->fd > -1) {
event_queue_add_fd_read(queue, uwsgi_sock->fd);
}
#endif
uwsgi_sock = uwsgi_sock->next;
}
@@ -1235,7 +1236,9 @@ void uwsgi_del_sockets_from_queue(int queue) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->fd == -1) goto nextsock;
event_queue_del_fd(queue, uwsgi_sock->fd, event_queue_read());
nextsock:
uwsgi_sock = uwsgi_sock->next;
}
@@ -1254,6 +1257,34 @@ int uwsgi_is_bad_connection(int fd) {
return soopt;
}
int uwsgi_socket_is_already_bound(char *name) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
if (uwsgi_sock->name && !strcmp(uwsgi_sock->name, name) && uwsgi_sock->bound) {
return 1;
}
uwsgi_sock = uwsgi_sock->next;
}
return 0;
}
int uwsgi_socket_uniq(struct uwsgi_socket *list, struct uwsgi_socket *item) {
int found = 0;
if (list == item) return 0;
struct uwsgi_socket *uwsgi_sock = list;
while(uwsgi_sock && uwsgi_sock != item) {
if (uwsgi_sock->fd == -1) goto nextsock;
if (!strcmp(uwsgi_sock->name, item->name)) {
found = 1;
break;
}
nextsock:
uwsgi_sock = uwsgi_sock->next;
}
return found;
}
void uwsgi_manage_zerg(int fd, int num_sockets, int *sockets) {
struct sockaddr_un zsun;
socklen_t zsun_len = sizeof(struct sockaddr_un);
@@ -1297,11 +1328,19 @@ void uwsgi_manage_zerg(int fd, int num_sockets, int *sockets) {
if (!sockets) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
int uniq_count = 0;
while (uwsgi_sock) {
memcpy(zerg_fd_ptr, &uwsgi_sock->fd, sizeof(int));
zerg_fd_ptr += sizeof(int);
if (uwsgi_sock->fd == -1) goto nextsock;
if (!uwsgi_socket_uniq(uwsgi.sockets, uwsgi_sock)) {
memcpy(zerg_fd_ptr, &uwsgi_sock->fd, sizeof(int));
zerg_fd_ptr += sizeof(int);
uniq_count++;
}
nextsock:
uwsgi_sock = uwsgi_sock->next;
}
zerg_iov[1].iov_base = &uniq_count;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * uniq_count);
}
else {
memcpy(zerg_fd_ptr, sockets, sizeof(int) * num_sockets);
+42 -18
View File
@@ -101,7 +101,7 @@ pid_t spooler_start(struct uwsgi_spooler *uspool) {
uwsgi_fixup_fds(0, 0, NULL);
uwsgi_close_all_sockets();
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->post_fork) {
uwsgi.p[i]->post_fork();
}
@@ -109,7 +109,7 @@ pid_t spooler_start(struct uwsgi_spooler *uspool) {
uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1];
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->spooler_init) {
uwsgi.p[i]->spooler_init();
}
@@ -237,7 +237,8 @@ int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core
// here the file will be unlocked too
close(fd);
uwsgi_log("[spooler] written %d bytes to file %s\n", size + body_len + 4, filename);
if (!uwsgi.spooler_quiet)
uwsgi_log("[spooler] written %d bytes to file %s\n", size + body_len + 4, filename);
// and here waiting threads can continue
uwsgi_unlock(uspool->lock);
@@ -309,6 +310,9 @@ void spooler(struct uwsgi_spooler *uspool) {
event_queue_add_fd_read(spooler_event_queue, uwsgi.shared->spooler_signal_pipe[1]);
}
// reset the tasks counter
uspool->tasks = 0;
for (;;) {
@@ -360,6 +364,12 @@ void spooler(struct uwsgi_spooler *uspool) {
}
wakeup = tmp_wakeup;
// need to recycle ?
if (uwsgi.spooler_max_tasks > 0 && uspool->tasks >= (uint64_t)uwsgi.spooler_max_tasks) {
uwsgi_log("[spooler %s pid: %d] maximum number of tasks reached (%d) recycling ...\n", uspool->dir, (int) uwsgi.mypid, uwsgi.spooler_max_tasks);
end_me(0);
}
}
}
@@ -453,20 +463,30 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
spool_fd = open(task, O_RDWR);
if (spool_fd < 0) {
uwsgi_error_open(task);
if (errno != ENOENT)
uwsgi_error_open(task);
return;
}
// check if the file is locked by anther process
// check if the file is locked by another process
if (uwsgi_fcntl_is_locked(spool_fd)) {
close(spool_fd);
uwsgi_protected_close(spool_fd);
return;
}
if (read(spool_fd, &uh, 4) != 4) {
// unlink() can destroy the lock !!!
if (access(task, R_OK | W_OK)) {
uwsgi_protected_close(spool_fd);
return;
}
ssize_t rlen = uwsgi_protected_read(spool_fd, &uh, 4);
if (rlen != 4) {
// it could be here for broken file or just opened one
uwsgi_error("read()");
close(spool_fd);
if (rlen < 0)
uwsgi_error("read()");
uwsgi_protected_close(spool_fd);
return;
}
@@ -474,10 +494,10 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
uh.pktsize = uwsgi_swap16(uh.pktsize);
#endif
if (read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
if (uwsgi_protected_read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
uwsgi_error("read()");
destroy_spool(dir, task);
close(spool_fd);
uwsgi_protected_close(spool_fd);
return;
}
@@ -485,19 +505,20 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
if (sf_lstat.st_size > (uh.pktsize+4)) {
body_len = sf_lstat.st_size - (uh.pktsize+4);
body = uwsgi_malloc(body_len);
if ((size_t)read(spool_fd, body, body_len) != body_len) {
if ((size_t)uwsgi_protected_read(spool_fd, body, body_len) != body_len) {
uwsgi_error("read()");
destroy_spool(dir, task);
close(spool_fd);
uwsgi_protected_close(spool_fd);
free(body);
return;
}
}
// not the task is running and should not be waken
// now the task is running and should not be waken up
uspool->running = 1;
uwsgi_log("[spooler %s pid: %d] managing request %s ...\n", uspool->dir, (int) uwsgi.mypid, task);
if (!uwsgi.spooler_quiet)
uwsgi_log("[spooler %s pid: %d] managing request %s ...\n", uspool->dir, (int) uwsgi.mypid, task);
// chdir before running the task (if requested)
@@ -508,7 +529,7 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
}
int callable_found = 0;
for(i=0;i<0xff;i++) {
for(i=0;i<256;i++) {
if (uwsgi.p[i]->spooler) {
time_t now = time(NULL);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
@@ -520,8 +541,11 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
}
if (ret == 0) continue;
callable_found = 1;
// increase task counter
uspool->tasks++;
if (ret == -2) {
uwsgi_log("[spooler %s pid: %d] done with task %s after %d seconds\n", uspool->dir, (int) uwsgi.mypid, task, time(NULL)-now);
if (!uwsgi.spooler_quiet)
uwsgi_log("[spooler %s pid: %d] done with task %s after %d seconds\n", uspool->dir, (int) uwsgi.mypid, task, time(NULL)-now);
destroy_spool(dir, task);
}
// re-spool it
@@ -533,7 +557,7 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
free(body);
// here we free and unlock the task
close(spool_fd);
uwsgi_protected_close(spool_fd);
uspool->running = 0;
if (!callable_found) {
+8 -5
View File
@@ -8,12 +8,15 @@ if ($rpc_value) {
}
my $app = sub {
my $env = shift;
uwsgi::cache_set("key1", "val1");
print uwsgi::call('hello');
return [
my $env = shift;
uwsgi::cache_set("key1", "val1");
if ($rpc_value) {
print uwsgi::call('hello')."\n";
}
print 'pid '.$$."\n";
return [
'200',
[ 'Content-Type' => 'text/plain' ],
[ "Hello World\r\n", $env->{'REQUEST_URI'}, uwsgi::cache_get('key1'), uwsgi::call('hello') ],
];
];
};
+35
View File
@@ -0,0 +1,35 @@
import time
import sys
def application(e, sr):
time.sleep(3)
print("3 seconds elapsed")
sr('200 Ok', [('Content-Type', 'text/html')])
time.sleep(2)
print("2 seconds elapsed")
yield "part1"
try:
time.sleep(2)
except:
print("CLIENT DISCONNECTED !!!")
print("2 seconds elapsed")
yield "part2"
try:
time.sleep(2)
except:
print("CLIENT DISCONNECTED !!!")
print("2 seconds elapsed")
yield "part3"
time.sleep(2)
print("2 seconds elapsed")
yield "part4"
print("end of request")
+6 -3
View File
@@ -1,3 +1,4 @@
# uwsgi --async 1000 --ugreen
import uwsgi
import psycopg2
@@ -12,9 +13,11 @@ def async_wait(conn):
if state == psycopg2.extensions.POLL_OK:
break
elif state == psycopg2.extensions.POLL_READ:
uwsgi.green_wait_fdread(conn.fileno())
uwsgi.wait_fd_read(conn.fileno())
uwsgi.suspend()
elif state == psycopg2.extensions.POLL_WRITE:
uwsgi.green_wait_fdwrite(conn.fileno())
uwsgi.wait_fd_write(conn.fileno())
uwsgi.suspend()
else:
raise Exception("Unexpected result from poll: %r", state)
@@ -26,7 +29,7 @@ def application(env, start_response):
start_response('200 Ok', [('Content-type', 'text/html')])
conn = psycopg2.connect("dbname=prova user=postgres", async=True)
conn = psycopg2.connect("dbname=template1 user=postgres", async=True)
# suspend until connection
async_wait(conn)
+5
View File
@@ -5,6 +5,11 @@ import os
def application(env, start_response):
print(env.__class__)
print(env['PATH_INFO'])
print(env['REQUEST_METHOD'])
print(env['wsgi.input'])
if env['PATH_INFO'].startswith('/progress/'):
start_response('200 Ok', [('Content-type', 'application/json')])
filename = 'foobar/' + env['PATH_INFO'][10:]
+142 -10
View File
@@ -153,7 +153,7 @@ void daemonize(char *logfile) {
exit(1);
}
if (pid != 0) {
exit(0);
_exit(0);
}
if (setsid() < 0) {
@@ -168,7 +168,7 @@ void daemonize(char *logfile) {
exit(1);
}
if (pid != 0) {
exit(0);
_exit(0);
}
if (!uwsgi.do_not_change_umask) {
@@ -187,9 +187,12 @@ void daemonize(char *logfile) {
}
/* stdin */
if (dup2(fdin, 0) < 0) {
uwsgi_error("dup2()");
exit(1);
if (fdin != 0) {
if (dup2(fdin, 0) < 0) {
uwsgi_error("dup2()");
exit(1);
}
close(fdin);
}
@@ -619,7 +622,9 @@ void uwsgi_as_root() {
char *uidname = uwsgi.uidname;
if (!uidname) {
struct passwd *pw = getpwuid(uwsgi.uid);
uidname = pw->pw_name;
if (pw)
uidname = pw->pw_name;
}
if (!uidname) uidname = uwsgi_num2str(uwsgi.uid);
if (initgroups(uidname, uwsgi.gid)) {
@@ -1125,6 +1130,11 @@ void sanitize_args() {
uwsgi.vacuum = 1;
}
#endif
if (uwsgi.write_errors_exception_only) {
uwsgi.ignore_sigpipe = 1;
uwsgi.ignore_write_errors = 1;
}
}
void env_to_arg(char *src, char *dst) {
@@ -1189,6 +1199,7 @@ void uwsgi_log(const char *fmt, ...) {
struct timeval tv;
char sftime[64];
char ctime_storage[26];
time_t now;
if (uwsgi.logdate) {
@@ -1201,8 +1212,12 @@ void uwsgi_log(const char *fmt, ...) {
}
else {
gettimeofday(&tv, NULL);
memcpy(logpkt, ctime((const time_t *) &tv.tv_sec), 24);
#ifdef __sun__
ctime_r((const time_t *) &tv.tv_sec, ctime_storage, 26);
#else
ctime_r((const time_t *) &tv.tv_sec, ctime_storage);
#endif
memcpy(logpkt, ctime_storage, 24);
memcpy(logpkt + 24, " - ", 3);
rlen = 24 + 3;
@@ -1238,6 +1253,7 @@ void uwsgi_log_verbose(const char *fmt, ...) {
struct timeval tv;
char sftime[64];
time_t now;
char ctime_storage[26];
if (uwsgi.log_strftime) {
now = time(NULL);
@@ -1248,8 +1264,12 @@ void uwsgi_log_verbose(const char *fmt, ...) {
}
else {
gettimeofday(&tv, NULL);
memcpy(logpkt, ctime((const time_t *) &tv.tv_sec), 24);
#ifdef __sun__
ctime_r((const time_t *) &tv.tv_sec, ctime_storage, 26);
#else
ctime_r((const time_t *) &tv.tv_sec, ctime_storage);
#endif
memcpy(logpkt, ctime_storage, 24);
memcpy(logpkt + 24, " - ", 3);
rlen = 24 + 3;
@@ -2692,6 +2712,7 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
uwsgi_error("dup2()");
exit(1);
}
close(devnull);
}
if (setsid() < 0) {
@@ -4065,6 +4086,7 @@ char *uwsgi_check_touches(struct uwsgi_string_list *touch_list) {
touch->custom = 0;
}
else {
if (!touch->custom) touch->custom = (uint64_t) tr_st.st_mtime;
if ((uint64_t) tr_st.st_mtime > touch->custom) {
touch->custom = (uint64_t) tr_st.st_mtime;
return touch->value;
@@ -4147,3 +4169,113 @@ void uwsgi_emulate_cow_for_apps(int id) {
time_t uwsgi_now() {
return time(NULL);
}
uint64_t uwsgi_micros() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000000) + tv.tv_usec;
}
void uwsgi_write_pidfile(char *pidfile_name) {
uwsgi_log("writing pidfile to %s\n", pidfile_name);
FILE *pidfile = fopen(pidfile_name, "w");
if (!pidfile) {
uwsgi_error_open(pidfile_name);
exit(1);
}
if (fprintf(pidfile, "%d\n", (int) getpid()) < 0) {
uwsgi_log("could not write pidfile.\n");
}
fclose(pidfile);
}
int uwsgi_manage_exception(char *type, char *value, char *repr) {
struct uwsgi_string_list *list = NULL;
// first manage non fatal case (like signals and alarm)....
if (uwsgi.reload_on_exception) {
return -1;
}
if (type) {
list = uwsgi.reload_on_exception_type;
while(list) {
if (!strcmp(list->value, type)) {
return -1;
}
list = list->next;
}
}
if (value) {
list = uwsgi.reload_on_exception_value;
while(list) {
if (!strcmp(list->value, value)) {
return -1;
}
list = list->next;
}
}
if (repr) {
list = uwsgi.reload_on_exception_repr;
while(list) {
if (!strcmp(list->value, repr)) {
return -1;
}
list = list->next;
}
}
return 0;
}
void uwsgi_protected_close(int fd) {
sigset_t mask, oset;
sigfillset(&mask);
if (sigprocmask(SIG_BLOCK, &mask, &oset)) {
uwsgi_error("sigprocmask()");
exit(1);
}
close(fd);
if (sigprocmask(SIG_SETMASK, &oset, NULL)) {
uwsgi_error("sigprocmask()");
exit(1);
}
}
ssize_t uwsgi_protected_read(int fd, void *buf, size_t len) {
sigset_t mask, oset;
sigfillset(&mask);
if (sigprocmask(SIG_BLOCK, &mask, &oset)) {
uwsgi_error("sigprocmask()");
exit(1);
}
ssize_t ret = read(fd, buf, len);
if (sigprocmask(SIG_SETMASK, &oset, NULL)) {
uwsgi_error("sigprocmask()");
exit(1);
}
return ret;
}
char *uwsgi_expand_path(char *dir, int dir_len, char *ptr) {
char src[PATH_MAX+1];
memcpy(src, dir, dir_len);
src[dir_len] = 0;
char *dst = ptr;
if (!dst) dst = uwsgi_malloc(PATH_MAX+1);
if (!realpath(src, dst)) {
uwsgi_error_realpath(src);
if (!ptr)
free(dst);
return NULL;
}
return dst;
}
+122 -67
View File
@@ -83,6 +83,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"endif", optional_argument, 0, "(opt logic) end if", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
{"ignore-sigpipe", no_argument, 0, "do not report (annoying) SIGPIPE", uwsgi_opt_true, &uwsgi.ignore_sigpipe,0},
{"ignore-write-errors", no_argument, 0, "do not report (annoying) write()/writev() errors", uwsgi_opt_true, &uwsgi.ignore_write_errors,0},
{"write-errors-tolerance", required_argument, 0, "set the maximum number of allowed write errors (default: no tolerance)", uwsgi_opt_set_int, &uwsgi.write_errors_tolerance,0},
{"write-errors-exception-only", no_argument, 0, "only raise an exception on write errors giving control to the app itself", uwsgi_opt_true, &uwsgi.write_errors_exception_only,0},
{"inherit", required_argument, 0, "use the specified file as config template", uwsgi_opt_load, NULL,0},
{"daemonize", required_argument, 'd', "daemonize uWSGI", uwsgi_opt_set_str, &uwsgi.daemonize, 0},
@@ -131,6 +134,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"emperor-amqp-username", required_argument, 0, "set emperor amqp username", uwsgi_opt_set_str, &uwsgi.emperor_amqp_username, 0},
{"emperor-amqp-password", required_argument, 0, "set emperor amqp password", uwsgi_opt_set_str, &uwsgi.emperor_amqp_password, 0},
{"emperor-throttle", required_argument, 0, "throttle each vassal spawn (in seconds)", uwsgi_opt_set_int, &uwsgi.emperor_throttle, 0},
{"emperor-magic-exec", no_argument, 0, "prefix vassals config files with exec:// if they have the executable bit", uwsgi_opt_true, &uwsgi.emperor_magic_exec, 0},
{"vassals-inherit", required_argument, 0, "add config templates to vassals config", uwsgi_opt_add_string_list, &uwsgi.vassals_templates, 0},
{"vassals-start-hook", required_argument, 0, "run the specified command before each vassal starts", uwsgi_opt_set_str, &uwsgi.vassals_start_hook, 0},
{"vassals-stop-hook", required_argument, 0, "run the specified command after vassal's death", uwsgi_opt_set_str, &uwsgi.vassals_stop_hook,0},
@@ -158,6 +162,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"cache-store-sync", required_argument, 0, "set frequency of sync for persistent cache", uwsgi_opt_set_int, &uwsgi.cache_store_sync,0},
{"cache-server", required_argument, 0, "enable the threaded cache server", uwsgi_opt_set_str, &uwsgi.cache_server, 0},
{"cache-server-threads", required_argument, 0, "set the number of threads for the cache server", uwsgi_opt_set_int, &uwsgi.cache_server_threads,0},
{"cache-no-expire", no_argument, 0, "disable auto sweep of expired items", uwsgi_opt_true, &uwsgi.cache_no_expire,0},
{"cache-expire-freq", required_argument, 0, "set the frequency of cache sweeper scans (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.cache_expire_freq,0},
{"cache-report-freed-items", no_argument, 0, "constantly report the cache item freed by the sweeper (use only for debug)", uwsgi_opt_true, &uwsgi.cache_report_freed_items,0},
{"queue", required_argument, 0, "enable shared queue", uwsgi_opt_set_int, &uwsgi.queue_size, 0},
{"queue-blocksize", required_argument, 0, "set queue blocksize", uwsgi_opt_set_int, &uwsgi.queue_store_sync, 0},
@@ -169,6 +176,8 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"spooler-ordered", no_argument, 0, "try to order the execution of spooler tasks", uwsgi_opt_true, &uwsgi.spooler_ordered,0},
{"spooler-chdir", required_argument, 0, "chdir() to specified directory before each spooler task", uwsgi_opt_set_str, &uwsgi.spooler_chdir,0},
{"spooler-processes", required_argument, 0, "set the number of processes for spoolers", uwsgi_opt_set_int, &uwsgi.spooler_numproc, 0},
{"spooler-quiet", no_argument, 0, "do not be verbose with spooler tasks", uwsgi_opt_true, &uwsgi.spooler_quiet, 0},
{"spooler-max-tasks", required_argument, 0, "set the maximum number of tasks to run before recycling a spooler", uwsgi_opt_set_int, &uwsgi.spooler_max_tasks, 0},
#endif
{"mule", optional_argument, 0, "add a mule", uwsgi_opt_add_mule, NULL, UWSGI_OPT_MASTER},
{"mules", required_argument, 0, "add the specified number of mules", uwsgi_opt_add_mules, NULL, UWSGI_OPT_MASTER},
@@ -258,6 +267,12 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"upload-progress", required_argument, 0, "enable creation of .json files in the specified directory during a file upload", uwsgi_opt_set_str, &uwsgi.upload_progress,0},
{"no-default-app", no_argument, 0, "do not fallback to default app", uwsgi_opt_true, &uwsgi.no_default_app, 0},
{"manage-script-name", no_argument, 0, "automatically rewrite SCRIPT_NAME and PATH_INFO", uwsgi_opt_true, &uwsgi.manage_script_name, 0},
{"ignore-script-name", no_argument, 0, "ignore SCRIPT_NAME", uwsgi_opt_true, &uwsgi.ignore_script_name, 0},
{"catch-exceptions", no_argument, 0, "report exception has http output (discouraged)", uwsgi_opt_true, &uwsgi.catch_exceptions, 0},
{"reload-on-exception", no_argument, 0, "reload a worker when an exception is raised", uwsgi_opt_true, &uwsgi.reload_on_exception, 0},
{"reload-on-exception-type", required_argument, 0, "reload a worker when a specific exception type is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_type, 0},
{"reload-on-exception-value", required_argument, 0, "reload a worker when a specific exception value is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_value, 0},
{"reload-on-exception-repr", required_argument, 0, "reload a worker when a specific exception type+value (language-specific) is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_repr, 0},
#ifdef UWSGI_UDP
{"udp", required_argument, 0, "run the udp server on the specified address", uwsgi_opt_set_str, &uwsgi.udp_socket, UWSGI_OPT_MASTER},
#endif
@@ -322,7 +337,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"lazy", no_argument, 0, "set lazy mode (load apps in workers instead of master)", uwsgi_opt_true, &uwsgi.lazy, 0},
{"cheap", no_argument, 0, "set cheap mode (spawn workers only after the first request)", uwsgi_opt_true, &uwsgi.cheap, 0},
{"cheaper", required_argument, 0, "set cheaper mode (adaptive process spawning)", uwsgi_opt_set_int, &uwsgi.cheaper_count, UWSGI_OPT_MASTER|UWSGI_OPT_CHEAPER},
{"cheaper-algo", required_argument, 0, "choose to algorithm used for adaptive process spawning)", uwsgi_opt_set_str, &uwsgi.requested_cheaper_algo, UWSGI_OPT_MASTER|UWSGI_OPT_CHEAPER},
{"cheaper-algo", required_argument, 0, "choose to algorithm used for adaptive process spawning)", uwsgi_opt_set_str, &uwsgi.requested_cheaper_algo, UWSGI_OPT_MASTER},
{"cheaper-step", required_argument, 0, "number of additional processes to spawn at each overload", uwsgi_opt_set_int, &uwsgi.cheaper_step, UWSGI_OPT_MASTER|UWSGI_OPT_CHEAPER},
{"cheaper-overload", required_argument, 0, "increase workers after specified overload", uwsgi_opt_set_64bit, &uwsgi.cheaper_overload, UWSGI_OPT_MASTER|UWSGI_OPT_CHEAPER},
{"idle", required_argument, 0, "set idle mode (put uWSGI in cheap mode after inactivity)", uwsgi_opt_set_int, &uwsgi.idle, 0},
@@ -363,7 +378,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"check-cache", no_argument, 0, "check for response data in the cache", uwsgi_opt_true, &uwsgi.check_cache, 0},
{"close-on-exec", no_argument, 0, "set close-on-exec on sockets (could be required for spawning processes in requests)", uwsgi_opt_true, &uwsgi.close_on_exec, 0},
{"mode", required_argument, 0, "set uWSGI custom mode", uwsgi_opt_set_str, &uwsgi.mode,0},
{"env", required_argument, 0, "set environment variable", uwsgi_opt_set_env, NULL, UWSGI_OPT_IMMEDIATE},
{"env", required_argument, 0, "set environment variable", uwsgi_opt_set_env, NULL, 0},
{"vacuum", no_argument, 0, "try to remove all of the generated file/sockets", uwsgi_opt_true, &uwsgi.vacuum,0},
#ifdef __linux__
{"cgroup", required_argument, 0, "put the processes in the specified cgroup", uwsgi_opt_add_string_list, &uwsgi.cgroup,0},
@@ -439,6 +454,9 @@ restart:
continue;
uwsgi.dirty_config = 0;
uwsgi.exported_opts[i]->configured = uwsgi_manage_opt(uwsgi.exported_opts[i]->key, uwsgi.exported_opts[i]->value);
if (uwsgi.exported_opts[i]->configured == 0 && uwsgi.autoload) {
uwsgi.dirty_config = uwsgi_try_autoload(uwsgi.exported_opts[i]->key);
}
if (uwsgi.dirty_config) goto restart;
}
@@ -860,6 +878,7 @@ void what_i_am_doing() {
struct wsgi_request *wsgi_req;
int i;
char ctime_storage[26];
uwsgi_backtrace(uwsgi.backtrace_depth);
@@ -867,11 +886,16 @@ void what_i_am_doing() {
for (i = 0; i < uwsgi.cores; i++) {
wsgi_req = uwsgi.wsgi_requests[i];
if (wsgi_req->uri_len > 0) {
#ifdef __sun__
ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, ctime_storage, 26);
#else
ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, ctime_storage);
#endif
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0 && uwsgi.workers[uwsgi.mywid].harakiri < time(NULL)) {
uwsgi_log("HARAKIRI: --- uWSGI worker %d core %d (pid: %d) WAS managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, i, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime((const time_t *) &wsgi_req->start_of_request.tv_sec));
uwsgi_log("HARAKIRI: --- uWSGI worker %d core %d (pid: %d) WAS managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, i, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
else {
uwsgi_log("SIGUSR2: --- uWSGI worker %d core %d (pid: %d) is managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, i, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime((const time_t *) &wsgi_req->start_of_request.tv_sec));
uwsgi_log("SIGUSR2: --- uWSGI worker %d core %d (pid: %d) is managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, i, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
}
}
@@ -879,11 +903,16 @@ void what_i_am_doing() {
else {
wsgi_req = uwsgi.wsgi_requests[0];
if (wsgi_req->uri_len > 0) {
#ifdef __sun__
ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, ctime_storage, 26);
#else
ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, ctime_storage);
#endif
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0 && uwsgi.workers[uwsgi.mywid].harakiri < time(NULL)) {
uwsgi_log("HARAKIRI: --- uWSGI worker %d (pid: %d) WAS managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime((const time_t *) &wsgi_req->start_of_request.tv_sec));
uwsgi_log("HARAKIRI: --- uWSGI worker %d (pid: %d) WAS managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
else {
uwsgi_log("SIGUSR2: --- uWSGI worker %d (pid: %d) is managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime((const time_t *) &wsgi_req->start_of_request.tv_sec));
uwsgi_log("SIGUSR2: --- uWSGI worker %d (pid: %d) is managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
}
else if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0 && uwsgi.workers[uwsgi.mywid].harakiri < time(NULL) && uwsgi.workers[uwsgi.mywid].sig) {
@@ -1083,7 +1112,7 @@ void uwsgi_plugins_atexit(void) {
}
}
for (j = 0; j<0xFF; j++) {
for (j = 0; j<256; j++) {
if (uwsgi.p[j]->atexit) {
uwsgi.p[j]->atexit();
}
@@ -1093,7 +1122,7 @@ void uwsgi_plugins_atexit(void) {
void uwsgi_backtrace(int depth) {
#if defined(__linux__) || defined(__APPLE__)
#if defined(__linux__) || defined(__APPLE__) || defined(UWSGI_HAS_EXECINFO)
#include <execinfo.h>
@@ -1191,8 +1220,6 @@ int main(int argc, char *argv[], char *envp[]) {
int i;
int rlen;
FILE *pidfile;
char *env_reloads;
char env_reload_buf[11];
@@ -1257,7 +1284,7 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.shared->spooler_frequency = 30;
#endif
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
uwsgi.p[i] = &unconfigured_plugin;
}
@@ -1494,7 +1521,7 @@ int main(int argc, char *argv[], char *envp[]) {
}
}
if (!magic) {
for (j = 0; j < 0xFF; j++) {
for (j = 0; j < 256; j++) {
if (uwsgi.p[j]->magic) {
if (uwsgi.p[j]->magic(NULL, lazy)) {
magic = 1;
@@ -1621,16 +1648,7 @@ int main(int argc, char *argv[], char *envp[]) {
}
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
uwsgi_log("writing pidfile to %s\n", uwsgi.pidfile);
pidfile = fopen(uwsgi.pidfile, "w");
if (!pidfile) {
uwsgi_error_open(uwsgi.pidfile);
exit(1);
}
if (fprintf(pidfile, "%d\n", (int) getpid()) < 0) {
uwsgi_log("could not write pidfile.\n");
}
fclose(pidfile);
uwsgi_write_pidfile(uwsgi.pidfile);
}
uwsgi_log_initial("detected binary path: %s\n", uwsgi.binary_path);
@@ -1783,16 +1801,7 @@ int uwsgi_start(void *v_argv) {
}
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
uwsgi_log("writing pidfile2 to %s\n", uwsgi.pidfile2);
FILE *pidfile2 = fopen(uwsgi.pidfile2, "w");
if (!pidfile2) {
uwsgi_error_open(uwsgi.pidfile2);
exit(1);
}
if (fprintf(pidfile2, "%d\n", (int) getpid()) < 0) {
uwsgi_log("could not write pidfile2.\n");
}
fclose(pidfile2);
uwsgi_write_pidfile(uwsgi.pidfile2);
}
if (!uwsgi.master_process && !uwsgi.command_mode) {
@@ -2066,19 +2075,18 @@ int uwsgi_start(void *v_argv) {
}
}
struct uwsgi_string_list *zn = uwsgi.zerg_node;
while (zn) {
if (uwsgi_zerg_attach(zn->value)) {
if (!uwsgi.zerg_fallback) {
exit(1);
if (!uwsgi.is_a_reload) {
struct uwsgi_string_list *zn = uwsgi.zerg_node;
while (zn) {
if (uwsgi_zerg_attach(zn->value)) {
if (!uwsgi.zerg_fallback) {
exit(1);
}
}
zn = zn->next;
}
zn = zn->next;
}
//check for inherited sockets
if (uwsgi.is_a_reload || uwsgi.zerg) {
if (uwsgi.zerg) {
#ifdef UWSGI_DEBUG
@@ -2098,6 +2106,10 @@ int uwsgi_start(void *v_argv) {
uwsgi_log("zerg sockets attached\n");
}
}
//check for inherited sockets
if (uwsgi.is_a_reload) {
uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
@@ -2142,6 +2154,31 @@ int uwsgi_start(void *v_argv) {
continue;
}
struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
int found = 0;
while (ugs) {
if (ugs->fd == j) {
found = 1;break;
}
ugs = ugs->next;
}
if (found) continue;
int y;
found = 0;
for(y=0;y<ushared->gateways_cnt;y++) {
if (ushared->gateways[y].internal_subscription_pipe[0] == j) {
found = 1; break;
}
if (ushared->gateways[y].internal_subscription_pipe[1] == j) {
found = 1; break;
}
}
if (found) continue;
socket_type_len = sizeof(struct sockaddr_un);
gsa.sa = (struct sockaddr *) &usa;
if (!getsockname(j, gsa.sa, &socket_type_len)) {
@@ -2154,14 +2191,16 @@ int uwsgi_start(void *v_argv) {
uwsgi_sock = uwsgi_sock->next;
}
}
if (useless)
if (useless) {
close(j);
}
}
}
//now bind all the unbound sockets
uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (!uwsgi_sock->bound) {
if (!uwsgi_sock->bound && !uwsgi_socket_is_already_bound(uwsgi_sock->name)) {
char *tcp_port = strchr(uwsgi_sock->name, ':');
if (tcp_port == NULL) {
uwsgi_sock->fd = bind_to_unix(uwsgi_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
@@ -2220,10 +2259,16 @@ int uwsgi_start(void *v_argv) {
if (!getsockname(0, gsa.sa, &socket_type_len)) {
if (gsa.sa->sa_family == AF_UNIX) {
uwsgi_sock = uwsgi_new_socket(usa.sa_un.sun_path);
uwsgi_sock->family = AF_UNIX;
uwsgi_sock->fd = 0;
uwsgi_sock->bound = 1;
uwsgi_log("uwsgi socket %d inherited UNIX address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
}
else {
uwsgi_sock = uwsgi_new_socket(uwsgi_concat2("::",""));
uwsgi_sock->family = AF_INET;
uwsgi_sock->fd = 0;
uwsgi_sock->bound = 1;
uwsgi_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
}
}
@@ -2264,6 +2309,7 @@ skipzero:
// put listening socket in non-blocking state and set the protocol
uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (!uwsgi_sock->bound || uwsgi_sock->fd == -1) goto nextsock;
if (!uwsgi_sock->per_core) {
uwsgi_sock->arg = fcntl(uwsgi_sock->fd, F_GETFL, NULL);
if (uwsgi_sock->arg < 0) {
@@ -2285,10 +2331,10 @@ skipzero:
if (requested_protocol && !strcmp("http", requested_protocol)) {
uwsgi_sock->proto = uwsgi_proto_http_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_write = uwsgi_proto_http_write;
uwsgi_sock->proto_writev = uwsgi_proto_http_writev;
uwsgi_sock->proto_write_header = uwsgi_proto_http_write_header;
uwsgi_sock->proto_writev_header = uwsgi_proto_http_writev_header;
uwsgi_sock->proto_write = uwsgi_proto_uwsgi_write;
uwsgi_sock->proto_writev = uwsgi_proto_uwsgi_writev;
uwsgi_sock->proto_write_header = uwsgi_proto_uwsgi_write_header;
uwsgi_sock->proto_writev_header = uwsgi_proto_uwsgi_writev_header;
uwsgi_sock->proto_sendfile = NULL;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
}
@@ -2332,7 +2378,7 @@ skipzero:
uwsgi_sock->proto_sendfile = NULL;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
}
nextsock:
uwsgi_sock = uwsgi_sock->next;
}
@@ -2357,7 +2403,7 @@ skipzero:
// initialize request plugin only if workers or master are available
if (uwsgi.sockets || uwsgi.master_process || uwsgi.no_server || uwsgi.command_mode) {
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->init) {
uwsgi.p[i]->init();
}
@@ -2373,7 +2419,7 @@ skipzero:
// again check for workers/sockets...
if (uwsgi.sockets || uwsgi.master_process || uwsgi.no_server || uwsgi.command_mode) {
for (i = 0; i < 0xff; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->post_init) {
uwsgi.p[i]->post_init();
}
@@ -2401,7 +2447,7 @@ skipzero:
// again check for workers/sockets...
if (uwsgi.sockets || uwsgi.master_process || uwsgi.no_server || uwsgi.command_mode) {
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->enable_threads)
uwsgi.p[i]->enable_threads();
}
@@ -2606,7 +2652,7 @@ skipzero:
}
// preinit apps (create the language environment)
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->preinit_apps) {
uwsgi.p[i]->preinit_apps();
}
@@ -2640,6 +2686,14 @@ skipzero:
masterpid = uwsgi.mypid;
uwsgi.workers[0].pid = masterpid;
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
uwsgi_write_pidfile(uwsgi.pidfile);
}
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
uwsgi_write_pidfile(uwsgi.pidfile2);
}
}
if (uwsgi.no_server) {
@@ -2681,7 +2735,7 @@ skipzero:
// security in multiuser environment: allow only a subset of modifiers
if (uwsgi.allowed_modifiers) {
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (!uwsgi_list_has_num(uwsgi.allowed_modifiers, i)) {
uwsgi.p[i]->request = unconfigured_hook;
uwsgi.p[i]->after_request = unconfigured_after_hook;
@@ -2690,7 +2744,7 @@ skipzero:
}
// master fixup
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(0);
}
@@ -2804,9 +2858,8 @@ skipzero:
}
if (!enabled) {
int fd = uwsgi_sock->fd;
close(fd);
fd = open("/dev/null", O_RDONLY);
close(uwsgi_sock->fd);
int fd = open("/dev/null", O_RDONLY);
if (fd < 0) {
uwsgi_error_open("/dev/null");
exit(1);
@@ -2891,7 +2944,7 @@ skipzero:
uwsgi_init_all_apps();
}
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->post_fork) {
uwsgi.p[i]->post_fork();
}
@@ -3025,7 +3078,7 @@ skipzero:
//initialization done
// run fixup handler
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->fixup) {
uwsgi.p[i]->fixup();
}
@@ -3091,7 +3144,7 @@ void uwsgi_ignition() {
uwsgi_log("[snapshot] process %d is the new worker %d\n", (int) getpid(), uwsgi.mywid);
}
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->hijack_worker) {
uwsgi.p[i]->hijack_worker();
}
@@ -3197,7 +3250,7 @@ void build_options() {
op++;
}
for(i=0;i<0xFF;i++) {
for(i=0;i<256;i++) {
if (uwsgi.p[i]->options) {
options_count += uwsgi_count_options(uwsgi.p[i]->options);
}
@@ -3220,7 +3273,7 @@ void build_options() {
op++;
}
for(i=0;i<0xFF;i++) {
for(i=0;i<256;i++) {
if (uwsgi.p[i]->options) {
int c = uwsgi_count_options(uwsgi.p[i]->options);
memcpy(&uwsgi.options[pos], uwsgi.p[i]->options, sizeof(struct uwsgi_option) * c);
@@ -3353,7 +3406,7 @@ void uwsgi_init_all_apps() {
}
for (i = 0; i < 0xFF; i++) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->init_apps) {
uwsgi.p[i]->init_apps();
}
@@ -3371,7 +3424,7 @@ void uwsgi_init_all_apps() {
what[0] = 0;
what++;
uwsgi_log("mounting %s on %s\n", what, uwsgi.mounts[i]);
for (j = 0; j < 0xFF; j++) {
for (j = 0; j < 256; j++) {
if (uwsgi.p[j]->mount_app) {
if (!uwsgi_startswith(uwsgi.mounts[i], "regexp://", 9)) {
if (uwsgi.p[j]->mount_app(uwsgi.mounts[i]+9, what, 1) != -1)
@@ -3730,9 +3783,11 @@ void uwsgi_opt_signal(char *opt, char *value, void *foobar) {
void uwsgi_opt_log_date(char *opt, char *value, void *foobar) {
uwsgi.logdate = 1;
if (value) {
uwsgi.log_strftime = value;
}
if (value) {
if (strcasecmp("true", value) && strcasecmp("1", value) && strcasecmp("on", value) && strcasecmp("yes", value)) {
uwsgi.log_strftime = value;
}
}
}
void uwsgi_opt_chmod_socket(char *opt, char *value, void *foobar) {
+35 -9
View File
@@ -11,6 +11,7 @@ extern "C" {
#define UMAX64_STR "18446744073709551616"
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_error_realpath(x) uwsgi_log("realpath() of %s failed: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_log_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log(x);
#define uwsgi_error_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_log_initial if (!uwsgi.no_initial_output) uwsgi_log
@@ -548,6 +549,7 @@ struct uwsgi_opt {
#define UWSGI_EXILE_CODE 26
#define UWSGI_FAILED_APP_CODE 22
#define UWSGI_DE_HIJACKED_CODE 173
#define UWSGI_EXCEPTION_CODE 5
#define UWSGI_QUIET_CODE 29
#define MAX_VARS 64
@@ -670,7 +672,6 @@ struct uwsgi_app {
void *interpreter;
void *callable;
#ifdef UWSGI_ASYNC
void **args;
void **environ;
@@ -718,6 +719,7 @@ struct uwsgi_spooler {
char dir[PATH_MAX];
pid_t pid;
uint64_t respawned;
uint64_t tasks;
struct uwsgi_lock_item *lock;
time_t harakiri;
@@ -915,6 +917,7 @@ struct wsgi_request {
int async_plagued;
int suspended;
int write_errors;
int *ovector;
size_t post_cl;
@@ -1104,6 +1107,7 @@ struct uwsgi_server {
int emperor_fd_config;
int early_emperor;
int emperor_throttle;
int emperor_magic_exec;
char *emperor_dir;
pid_t emperor_pid;
int emperor_broodlord;
@@ -1185,6 +1189,9 @@ struct uwsgi_server {
#endif
int ignore_sigpipe;
int ignore_write_errors;
int write_errors_tolerance;
int write_errors_exception_only;
// still working on it
char *profiler;
@@ -1205,6 +1212,13 @@ struct uwsgi_server {
int ignore_script_name;
int manage_script_name;
int reload_on_exception;
int catch_exceptions;
struct uwsgi_string_list *reload_on_exception_type;
struct uwsgi_string_list *reload_on_exception_value;
struct uwsgi_string_list *reload_on_exception_repr;
int no_default_app;
// exit if no-app is loaded
int need_app;
@@ -1331,7 +1345,9 @@ struct uwsgi_server {
int spooler_numproc;
struct uwsgi_spooler *i_am_a_spooler;
char *spooler_chdir;
int spooler_max_tasks;
int spooler_ordered;
int spooler_quiet;
#endif
#ifdef UWSGI_SNMP
@@ -1448,7 +1464,6 @@ struct uwsgi_server {
char *chdir;
char *chdir2;
int catch_exceptions;
int vacuum;
int no_server;
@@ -1529,7 +1544,7 @@ struct uwsgi_server {
struct uwsgi_loop loops[MAX_LOOPS];
int loops_cnt;
struct uwsgi_plugin *p[0xFF];
struct uwsgi_plugin *p[256];
struct uwsgi_plugin *gp[MAX_GENERIC_PLUGINS];
int gp_cnt;
@@ -1561,6 +1576,9 @@ struct uwsgi_server {
char *cache_store;
size_t cache_filesize;
int cache_store_sync;
int cache_no_expire;
int cache_expire_freq;
int cache_report_freed_items;
char *cache_server;
int cache_server_threads;
@@ -2105,7 +2123,7 @@ ssize_t uwsgi_send_message(int, uint8_t, uint8_t, char *, uint16_t, int, ssize_t
char *uwsgi_cluster_best_node(void);
int uwsgi_cache_set(char *, uint16_t, char *, uint64_t, uint64_t, uint16_t);
int uwsgi_cache_del(char *, uint16_t);
int uwsgi_cache_del(char *, uint16_t, uint64_t);
char *uwsgi_cache_get(char *, uint16_t, uint64_t *);
uint32_t uwsgi_cache_exists(char *, uint16_t);
@@ -2362,10 +2380,6 @@ ssize_t uwsgi_proto_sctp_read_body(struct wsgi_request *, char *, size_t);
#endif
int uwsgi_proto_http_parser(struct wsgi_request *);
ssize_t uwsgi_proto_http_writev_header(struct wsgi_request *, struct iovec *, size_t);
ssize_t uwsgi_proto_http_writev(struct wsgi_request *, struct iovec *, size_t);
ssize_t uwsgi_proto_http_write(struct wsgi_request *, char *, size_t);
ssize_t uwsgi_proto_http_write_header(struct wsgi_request *, char *, size_t);
int uwsgi_proto_fastcgi_parser(struct wsgi_request *);
ssize_t uwsgi_proto_fastcgi_writev_header(struct wsgi_request *, struct iovec *, size_t);
@@ -2753,6 +2767,19 @@ void uwsgi_setup_post_buffering(void);
struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *);
void uwsgi_write_pidfile(char *);
int uwsgi_manage_exception(char *, char *, char *);
void uwsgi_protected_close(int);
ssize_t uwsgi_protected_read(int, void *, size_t);
int uwsgi_socket_uniq(struct uwsgi_socket *, struct uwsgi_socket *);
int uwsgi_socket_is_already_bound(char *name);
char *uwsgi_expand_path(char *, int, char *);
int uwsgi_try_autoload(char *);
uint64_t uwsgi_micros(void);
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);
#endif
@@ -2761,4 +2788,3 @@ int uwsgi_init(int, char **, char **);
}
#endif
+28 -6
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '1.1'
uwsgi_version = '1.2-rc1'
import os
import re
@@ -383,6 +383,22 @@ class uConf(object):
if self.has_include('ifaddrs.h'):
self.cflags.append('-DUWSGI_HAS_IFADDRS')
if uwsgi_os in ('FreeBSD', 'OpenBSD'):
if self.has_include('execinfo.h') or os.path.exists('/usr/local/include/execinfo.h'):
if os.path.exists('/usr/local/include/execinfo.h'):
self.cflags.append('-I/usr/local/include')
self.cflags.append('-DUWSGI_HAS_EXECINFO')
self.libs.append('-lexecinfo')
if uwsgi_os == 'OpenBSD':
try:
obsd_major = int(uwsgi_os_k.split('.')[0])
obsd_minor = int(uwsgi_os_k.split('.')[1])
if obsd_major >= 5 and obsd_minor > 0:
self.cflags.append('-DUWSGI_NEW_OPENBSD')
except:
pass
if uwsgi_os == 'SunOS':
self.libs.append('-lsendfile')
self.gcc_list.append('lib/sun_fixes')
@@ -415,16 +431,22 @@ class uConf(object):
if uwsgi_os == 'Linux' or uwsgi_os == 'SunOS':
locking_mode = 'pthread_mutex'
# FreeBSD umtx is still not ready for process shared locking
#elif uwsgi_os == 'FreeBSD':
# locking_mode = 'umtx'
# starting from FreeBSD 9 posix semaphores can be shared between processes
elif uwsgi_os == 'FreeBSD':
try:
fbsd_major = int(uwsgi_os_k.split('.')[0])
if fbsd_major >= 9:
locking_mode = 'posix_sem'
except:
pass
elif uwsgi_os == 'Darwin':
locking_mode = 'osx_spinlock'
if locking_mode == 'pthread_mutex':
self.cflags.append('-DUWSGI_LOCK_USE_MUTEX')
# FreeBSD umtx is still not ready for process shared locking
#elif locking_mode == 'umtx':
# self.cflags.append('-DUWSGI_LOCK_USE_UMTX')
elif locking_mode == 'posix_sem':
self.cflags.append('-DUWSGI_LOCK_USE_POSIX_SEM')
elif locking_mode == 'osx_spinlock':
self.cflags.append('-DUWSGI_LOCK_USE_OSX_SPINLOCK')
@@ -588,7 +610,7 @@ class uConf(object):
if self.has_include('uuid/uuid.h'):
has_uuid = True
self.cflags.append("-DUWSGI_UUID")
if os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
if uwsgi_os == 'Linux' or os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
self.libs.append('-luuid')
if self.get('append_version'):
+4 -2
View File
@@ -3,7 +3,10 @@ import os
import gc
import sys
from uwsgidecorators import *
gc.set_debug(gc.DEBUG_SAVEALL)
print(sys.version)
print(sys.version_info)
if 'set_debug' in gc.__dict__:
gc.set_debug(gc.DEBUG_SAVEALL)
print(os.environ)
print(sys.modules)
@@ -64,7 +67,6 @@ def setprocname():
uwsgi.setprocname("i am the worker %d" % uwsgi.worker_id())
def application(env, start_response):
try:
uwsgi.mule_msg(env['REQUEST_URI'], 1)
except: