Compare commits

..
1 Commits
Author SHA1 Message Date
Unbit 41bc23bb40 backports from 1.9.19 2013-10-16 20:58:20 +02:00
145 changed files with 1908 additions and 7962 deletions
+3 -11
View File
@@ -1,16 +1,8 @@
PYTHON := python
all:
$(PYTHON) uwsgiconfig.py --build $(PROFILE)
python uwsgiconfig.py --build
clean:
$(PYTHON) uwsgiconfig.py --clean
python uwsgiconfig.py --clean
check:
$(PYTHON) uwsgiconfig.py --check
plugin.%:
$(PYTHON) uwsgiconfig.py --plugin plugins/$* $(PROFILE)
%:
$(PYTHON) uwsgiconfig.py --build $@
python uwsgiconfig.py --check
+2 -4
View File
@@ -1,5 +1,3 @@
The uWSGI project
surprise i am empty !
For official documentation check: https://uwsgi-docs.readthedocs.org/en/latest/
For commercial support check: http://unbit.com/
Look in the online documentation on https://uwsgi-docs.readthedocs.org/en/latest/
+1 -1
View File
@@ -1,3 +1,3 @@
[uwsgi]
main_plugin = python,gevent,psgi,lua,php,rack,jvm,jwsgi,ring,mono,transformation_toupper,coroae,v8,cgi,xslt,webdav,ssi,ldap,gccgo,rados,pypy
main_plugin = python,gevent,psgi,lua,php,rack,jvm,jwsgi,ring,mono,transformation_toupper,coroae,v8,cgi,xslt,webdav,ssi,ldap,gccgo,rados
inherit = base
+3 -1
View File
@@ -2,9 +2,11 @@
xml = auto
yaml = true
json = auto
zeromq = auto
ssl = auto
pcre = auto
routing = auto
matheval = auto
debug = false
unbit = false
xml_implementation = libxml2
@@ -15,7 +17,7 @@ plugins =
bin_name = uwsgi
append_version =
plugin_dir = .
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash, router_expires, router_metrics, transformation_template, stats_pusher_socket
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash, router_expires
as_shared_library = false
locking = auto
+2 -1
View File
@@ -1,3 +1,4 @@
[uwsgi]
main_plugin = psgi,rack,lua,python,gevent,php,cgi,glusterfs,pty,xslt,msgpack,geoip,v8,pam,ldap,mono,jvm,ring,jwsgi,servlet,rados,coroae,pypy,gccgo
# pypy,jvm,ring,jwsgi
main_plugin = erlang,psgi,rack,lua,python,gevent,php,cgi,mono,pyerl,go
inherit = base
-3
View File
@@ -1,3 +0,0 @@
[uwsgi]
main_plugin = gccgo
inherit = base
+1
View File
@@ -1,3 +1,4 @@
[uwsgi]
main_plugin = glusterfs
inherit = base
matheval = false
+5
View File
@@ -0,0 +1,5 @@
[uwsgi]
main_plugin = go
inherit = base
bin_name = libuwsgi.so
as_shared_library = true
+2
View File
@@ -2,9 +2,11 @@
xml = false
yaml = false
json = false
zeromq = false
ssl = false
pcre = false
routing = false
matheval = false
debug = false
unbit = false
xml_implementation = none
+1
View File
@@ -2,6 +2,7 @@
xml = true
yaml = true
json = true
zeromq = true
ssl = true
pcre = true
routing = true
+1
View File
@@ -2,6 +2,7 @@
xml = true
yaml = true
json = false
zeromq = false
ssl = true
pcre = true
routing = true
+37 -86
View File
@@ -4,18 +4,18 @@ extern struct uwsgi_server uwsgi;
/*
This is a general-purpose async loop engine (it expects a coroutine-based approach)
This is a general purpose async loop engine (it expects a coroutine based approach)
You can see it as an hub holding the following structures:
1) the runqueue, cores ready to be run are appended to this list
1) the runqueue, cores ready to be run are appended in this list
2) the fd list, this is a list of monitored file descriptors, a core can wait for all the file descriptors it needs
3) the timeout value, if set, the current core will timeout after the specified number of seconds (unless an event cancels it)
3) the timeout value, if set the current core will timeout aftert he specified number of seconds (unless an event cancel it)
IMPORTANT: this is not a callback-based engine !!!
IMPORTANT: this is not a callback based engine !!!
*/
@@ -28,6 +28,7 @@ void uwsgi_async_queue_is_full(time_t now) {
}
void uwsgi_async_init() {
int i;
uwsgi.async_queue = event_queue_init();
@@ -39,9 +40,16 @@ void uwsgi_async_init() {
uwsgi.rb_async_timeouts = uwsgi_init_rb_timer();
// optimization, this array maps file descriptor to requests
uwsgi.async_waiting_fd_table = uwsgi_calloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
uwsgi.async_proto_fd_table = uwsgi_calloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
// a stack of unused cores
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async);
// fill it with default values
for (i = 0; i < uwsgi.async; i++) {
uwsgi.async_queue_unused[i] = &uwsgi.workers[uwsgi.mywid].cores[i].req;
}
// the first available core is the last one
uwsgi.async_queue_unused_ptr = uwsgi.async - 1;
}
@@ -151,7 +159,7 @@ static void async_expire_timeouts(uint64_t now) {
wsgi_req = (struct wsgi_request *) urbt->data;
// timeout expired
wsgi_req->async_timed_out = 1;
// reset the request
// reset teh request
async_reset_request(wsgi_req);
// push it in the runqueue
runqueue_push(wsgi_req);
@@ -165,11 +173,6 @@ static void async_expire_timeouts(uint64_t now) {
int async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
if (uwsgi.async < 2 || !uwsgi.async_waiting_fd_table){
uwsgi_log_verbose("ASYNC call without async mode !!!\n");
return -1;
}
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
if (fd < 0)
@@ -221,47 +224,8 @@ static int async_wait_fd_read(int fd, int timeout) {
return 1;
}
static int async_wait_fd_read2(int fd0, int fd1, int timeout, int *fd) {
struct wsgi_request *wsgi_req = current_wsgi_req();
wsgi_req->async_ready_fd = 0;
if (async_add_fd_read(wsgi_req, fd0, timeout)) {
return -1;
}
if (async_add_fd_read(wsgi_req, fd1, timeout)) {
// reset already registered fd
async_reset_request(wsgi_req);
return -1;
}
if (uwsgi.schedule_to_main) {
uwsgi.schedule_to_main(wsgi_req);
}
if (wsgi_req->async_timed_out) {
wsgi_req->async_timed_out = 0;
return 0;
}
if (wsgi_req->async_ready_fd) {
*fd = wsgi_req->async_last_ready_fd;
return 1;
}
return -1;
}
void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
if (uwsgi.async < 2 || !uwsgi.rb_async_timeouts) {
uwsgi_log_verbose("ASYNC call without async mode !!!\n");
return;
}
wsgi_req->async_ready_fd = 0;
if (timeout > 0 && wsgi_req->async_timeout == NULL) {
@@ -272,11 +236,6 @@ void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
int async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) {
if (uwsgi.async < 2 || !uwsgi.async_waiting_fd_table) {
uwsgi_log_verbose("ASYNC call without async mode !!!\n");
return -1;
}
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
if (fd < 0)
@@ -336,8 +295,9 @@ void async_schedule_to_req(void) {
// a trick to avoid calling routes again
uwsgi.wsgi_req->is_routing = 1;
#endif
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req);
if (uwsgi.wsgi_req->async_status <= UWSGI_OK) goto end;
if (uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req) <= UWSGI_OK) {
goto end;
}
if (uwsgi.schedule_to_main) {
uwsgi.schedule_to_main(uwsgi.wsgi_req);
@@ -348,42 +308,29 @@ end:
async_reset_request(uwsgi.wsgi_req);
uwsgi_close_request(uwsgi.wsgi_req);
uwsgi.wsgi_req->async_status = UWSGI_OK;
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
}
void async_schedule_to_req_green(void) {
struct wsgi_request *wsgi_req = uwsgi.wsgi_req;
#ifdef UWSGI_ROUTING
if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
if (uwsgi_apply_routes(uwsgi.wsgi_req) == UWSGI_ROUTE_BREAK) {
goto end;
}
#endif
for(;;) {
if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) {
if (uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req) <= UWSGI_OK) {
break;
}
wsgi_req->switches++;
if (uwsgi.schedule_fix) {
uwsgi.schedule_fix(wsgi_req);
}
uwsgi.wsgi_req->switches++;
// switch after each yield
uwsgi.schedule_to_main(wsgi_req);
uwsgi.schedule_to_main(uwsgi.wsgi_req);
}
#ifdef UWSGI_ROUTING
end:
#endif
// re-set the global state
uwsgi.wsgi_req = wsgi_req;
async_reset_request(wsgi_req);
uwsgi_close_request(wsgi_req);
// re-set the global state (routing could have changed it)
uwsgi.wsgi_req = wsgi_req;
wsgi_req->async_status = UWSGI_OK;
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req;
async_reset_request(uwsgi.wsgi_req);
uwsgi_close_request(uwsgi.wsgi_req);
uwsgi.wsgi_req->async_status = UWSGI_OK;
}
void async_loop() {
@@ -406,13 +353,10 @@ void async_loop() {
void *events = event_queue_alloc(64);
struct uwsgi_socket *uwsgi_sock;
uwsgi_async_init();
uwsgi.async_runqueue = NULL;
uwsgi.wait_write_hook = async_wait_fd_write;
uwsgi.wait_read_hook = async_wait_fd_read;
uwsgi.wait_read2_hook = async_wait_fd_read2;
if (uwsgi.signal_socket > -1) {
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.signal_socket);
@@ -521,8 +465,7 @@ void async_loop() {
// remove fd from event poll and fd proto table
uwsgi.async_proto_fd_table[interesting_fd] = NULL;
event_queue_del_fd(uwsgi.async_queue, interesting_fd, event_queue_read());
// put request in the runqueue (set it as UWSGI_OK to signal the first run)
uwsgi.wsgi_req->async_status = UWSGI_OK;
// put request in the runqueue
runqueue_push(uwsgi.wsgi_req);
continue;
}
@@ -568,11 +511,19 @@ void async_loop() {
uwsgi.wsgi_req->switches++;
// request ended ?
if (uwsgi.wsgi_req->async_status <= UWSGI_OK ||
uwsgi.wsgi_req->waiting_fds || uwsgi.wsgi_req->async_timeout) {
if (uwsgi.wsgi_req->async_status <= UWSGI_OK) {
// remove from the runqueue
runqueue_remove(current_request);
// push wsgi_request in the unused stack
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
}
else if (uwsgi.wsgi_req->waiting_fds || uwsgi.wsgi_req->async_timeout) {
// remove this request from the runqueue
runqueue_remove(current_request);
}
current_request = next_request;
}
-13
View File
@@ -204,19 +204,6 @@ int uwsgi_buffer_u64be(struct uwsgi_buffer *ub, uint64_t num) {
return uwsgi_buffer_append(ub, (char *) buf, 8);
}
int uwsgi_buffer_u64le(struct uwsgi_buffer *ub, uint64_t num) {
uint8_t buf[8];
buf[0] = (uint8_t) (num & 0xff);
buf[1] = (uint8_t) ((num >> 8) & 0xff);
buf[2] = (uint8_t) ((num >> 16) & 0xff);
buf[3] = (uint8_t) ((num >> 24) & 0xff);
buf[4] = (uint8_t) ((num >> 32) & 0xff);
buf[5] = (uint8_t) ((num >> 40) & 0xff);
buf[6] = (uint8_t) ((num >> 48) & 0xff);
buf[7] = (uint8_t) ((num >> 56) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 8);
}
int uwsgi_buffer_f64be(struct uwsgi_buffer *ub, double num) {
uint8_t buf[8];
+3 -3
View File
@@ -762,7 +762,7 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
}
// mark used blocks;
uint64_t needed_blocks = cache_mark_blocks(uc, uci->first_block, vallen);
// optimize the scan
// optimize teh scan
if (uc->blocks_bitmap_pos + (needed_blocks+1) > uc->blocks) {
uc->blocks_bitmap_pos = 0;
}
@@ -1432,7 +1432,7 @@ static int cache_magic_send_and_manage(int fd, struct uwsgi_buffer *ub, char *st
// ok now wait for the response, using the same buffer of the request
// NOTE: after using a uwsgi_buffer in that way we basically destroy (even if we can safely free it)
size_t rlen = ub->pos;
if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, timeout, NULL, NULL)) return -1;
if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, timeout)) return -1;
// try to fix the buffer to maintain size info
ub->pos = rlen;
@@ -1867,7 +1867,7 @@ void uwsgi_cache_sync_from_nodes(struct uwsgi_cache *uc) {
}
size_t rlen = ub->pos;
if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL, NULL)) {
if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
uwsgi_buffer_destroy(ub);
uwsgi_log("[cache-sync] unable to read from the cache server\n");
close(fd);
-5
View File
@@ -2,11 +2,6 @@
extern struct uwsgi_server uwsgi;
int uwsgi_simple_wait_milliseconds_hook(int timeout) {
return poll(NULL, 0, timeout);
}
// in the future we will need to use the best clock source for each os/system
time_t uwsgi_now() {
return uwsgi.clock->seconds();
-170
View File
@@ -493,10 +493,6 @@ add:
if (op->flags & UWSGI_OPT_MIME) {
uwsgi.build_mime_dict = 1;
}
// enable metrics ?
if (op->flags & UWSGI_OPT_METRICS) {
uwsgi.has_metrics = 1;
}
// immediate ?
if (op->flags & UWSGI_OPT_IMMEDIATE) {
op->func(key, value, op->data);
@@ -633,169 +629,3 @@ clear:
}
char *uwsgi_get_exported_opt(char *key) {
int i;
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
if (!strcmp(uwsgi.exported_opts[i]->key, key)) {
return uwsgi.exported_opts[i]->value;
}
}
return NULL;
}
char *uwsgi_get_optname_by_index(int index) {
struct uwsgi_option *op = uwsgi.options;
while (op->name) {
if (op->shortcut == index) {
return op->name;
}
op++;
}
return NULL;
}
/*
this works as a pipeline
processes = 2
cpu_cores = 8
foobar = %(processes cpu_cores + 2)
translate as:
step1 = proceses cpu_cores = 2 8 = 28 (string concatenation)
step1 + = step1_apply_func_plus (func token)
step1_apply_func_plus 2 = 28 + 2 = 30 (math)
*/
char *uwsgi_manage_placeholder(char *key) {
enum {
concat = 0,
sum,
sub,
mul,
div,
} state;
state = concat;
char *current_value = NULL;
char *space = strchr(key, ' ');
if (!space) {
return uwsgi_get_exported_opt(key);
}
// let's start the heavy metal here
char *tmp_value = uwsgi_str(key);
char *p, *ctx = NULL;
uwsgi_foreach_token(tmp_value, " ", p, ctx) {
char *value = NULL;
if (is_a_number(p)) {
value = uwsgi_str(p);
}
else if (!strcmp(p, "+")) {
state = sum;
continue;
}
else if (!strcmp(p, "-")) {
state = sub;
continue;
}
else if (!strcmp(p, "*")) {
state = mul;
continue;
}
else if (!strcmp(p, "/")) {
state = div;
continue;
}
else if (!strcmp(p, "++")) {
if (current_value) {
int64_t tmp_num = strtoll(current_value, NULL, 10);
free(current_value);
current_value = uwsgi_64bit2str(tmp_num+1);
}
state = concat;
continue;
}
else if (!strcmp(p, "--")) {
if (current_value) {
int64_t tmp_num = strtoll(current_value, NULL, 10);
free(current_value);
current_value = uwsgi_64bit2str(tmp_num-1);
}
state = concat;
continue;
}
// find the option
else {
char *ov = uwsgi_get_exported_opt(p);
if (!ov) ov = "";
value = uwsgi_str(ov);
}
int64_t arg1n = 0, arg2n = 0;
char *arg1 = "", *arg2 = "";
switch(state) {
case concat:
if (current_value) arg1 = current_value;
if (value) arg2 = value;
char *ret = uwsgi_concat2(arg1, arg2);
if (current_value) free(current_value);
current_value = ret;
break;
case sum:
if (current_value) arg1n = strtoll(current_value, NULL, 10);
if (value) arg2n = strtoll(value, NULL, 10);
if (current_value) free(current_value);
current_value = uwsgi_64bit2str(arg1n + arg2n);
break;
case sub:
if (current_value) arg1n = strtoll(current_value, NULL, 10);
if (value) arg2n = strtoll(value, NULL, 10);
if (current_value) free(current_value);
current_value = uwsgi_64bit2str(arg1n - arg2n);
break;
case mul:
if (current_value) arg1n = strtoll(current_value, NULL, 10);
if (value) arg2n = strtoll(value, NULL, 10);
if (current_value) free(current_value);
current_value = uwsgi_64bit2str(arg1n * arg2n);
break;
case div:
if (current_value) arg1n = strtoll(current_value, NULL, 10);
if (value) arg2n = strtoll(value, NULL, 10);
if (current_value) free(current_value);
// avoid division by zero
if (arg2n == 0) {
current_value = uwsgi_64bit2str(0);
}
else {
current_value = uwsgi_64bit2str(arg1n / arg2n);
}
break;
default:
break;
}
// over engineering
if (value)
free(value);
// reset state to concat
state = concat;
}
free(tmp_value);
return current_value;
}
+10 -12
View File
@@ -6,7 +6,7 @@ extern struct uwsgi_server uwsgi;
External uwsgi daemons
There are 3 kinds of daemons (read: external applications) that can be managed
There are 3 kind of daemons (read: external applications) that can be managed
by uWSGI.
1) dumb daemons (attached with --attach-daemon)
@@ -14,12 +14,12 @@ extern struct uwsgi_server uwsgi;
and the process is respawned
2) smart daemons with daemonization
you specify a pidfile and a command
- on startup - if the pidfile does not exist or contains a non-available pid (checked with kill(pid, 0))
the daemon is respawned
- on master check - if the pidfile does not exist or if it points to a non-existent pid
the daemon is respawned
- on startup - if the pidfile does not exists or contains a not-available pid (checked with kill(pid, 0))
the daemon is respawned
- on master ckeck - if the pidfile does not exist or if it point to a non-existent pid
the daemon is respawned
3) smart daemons without daemonization
same as 2, but the daemonization and pidfile creation are managed by uWSGI
same as 2, but the daemonization and pidfile creation is managed by uWSGI
status:
@@ -232,8 +232,8 @@ void uwsgi_detach_daemons() {
if (ud->pid > 0 && !ud->pidfile) {
#endif
uwsgi_log("[uwsgi-daemons] stopping daemon (pid: %d): %s\n", (int) ud->pid, ud->command);
// try to stop daemon gracefully, kill it if it won't die
// if mercy is not set then wait up to 3 seconds
// try to gracefully stop daemon, kill it if it won't die
// if mercy is not set than wait up to 3 seconds
time_t timeout = uwsgi_now() + (uwsgi.reload_mercy ? uwsgi.reload_mercy : 3);
int waitpid_status;
while (!kill(ud->pid, 0)) {
@@ -241,7 +241,7 @@ void uwsgi_detach_daemons() {
sleep(1);
waitpid(-ud->pid, &waitpid_status, WNOHANG);
if (uwsgi_now() >= timeout) {
uwsgi_log("[uwsgi-daemons] daemon did not die in time, killing (pid: %d): %s\n", (int) ud->pid, ud->command);
uwsgi_log("[uwsgi-daemons] daemon did not died in time, killing (pid: %d): %s\n", (int) ud->pid, ud->command);
kill(-ud->pid, SIGKILL);
break;
}
@@ -263,8 +263,6 @@ void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {
if (uwsgi.current_time - ud->last_spawn <= 3) {
throttle = ud->respawns - (uwsgi.current_time - ud->last_spawn);
// if ud->respawns == 0 then we can end up with throttle < 0
if (throttle <= 0) throttle = 1;
}
pid_t pid = uwsgi_fork("uWSGI external daemon");
@@ -325,7 +323,7 @@ void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {
if (throttle) {
uwsgi_log("[uwsgi-daemons] throttling \"%s\" for %d seconds\n", ud->command, throttle);
sleep((unsigned int) throttle);
sleep(throttle);
}
uwsgi_log("[uwsgi-daemons] %sspawning \"%s\"\n", ud->respawns > 0 ? "re" : "", ud->command);
+8 -55
View File
@@ -59,12 +59,12 @@ void uwsgi_emperor_blacklist_add(char *id) {
uebi->throttle_level += (uwsgi.emperor_throttle * 1000);
}
else {
uwsgi_log_verbose("[emperor] maximum throttle level for vassal %s reached !!!\n", id);
uwsgi_log("[emperor] maximum throttle level for vassal %s reached !!!\n", id);
uebi->throttle_level = uebi->throttle_level / 2;
}
uebi->attempt++;
if (uebi->attempt == 2) {
uwsgi_log_verbose("[emperor] unloyal bad behaving vassal found: %s throttling it...\n", id);
uwsgi_log("[emperor] unloyal bad behaving vassal found: %s throttling it...\n", id);
}
return;
}
@@ -603,7 +603,7 @@ void emperor_del(struct uwsgi_instance *c_ui) {
uwsgi_log("[emperor] %s stop-hook returned %d\n", c_ui->name, stop_hook_ret);
}
uwsgi_log_verbose("[emperor] removed uwsgi instance %s\n", c_ui->name);
uwsgi_log("[emperor] removed uwsgi instance %s\n", c_ui->name);
// put the instance in the blacklist (or update its throttling value)
if (!c_ui->loyal) {
uwsgi_emperor_blacklist_add(c_ui->name);
@@ -632,7 +632,7 @@ void emperor_stop(struct uwsgi_instance *c_ui) {
c_ui->status = 1;
c_ui->cursed_at = uwsgi_now();
uwsgi_log_verbose("[emperor] stop the uwsgi instance %s\n", c_ui->name);
uwsgi_log("[emperor] stop the uwsgi instance %s\n", c_ui->name);
}
void emperor_curse(struct uwsgi_instance *c_ui) {
@@ -642,7 +642,7 @@ void emperor_curse(struct uwsgi_instance *c_ui) {
c_ui->status = 1;
c_ui->cursed_at = uwsgi_now();
uwsgi_log_verbose("[emperor] curse the uwsgi instance %s (pid: %d)\n", c_ui->name, (int) c_ui->pid);
uwsgi_log("[emperor] curse the uwsgi instance %s (pid: %d)\n", c_ui->name, (int) c_ui->pid);
}
@@ -675,12 +675,8 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
c_ui->respawns++;
c_ui->last_mod = mod;
c_ui->last_run = uwsgi_now();
// reset readyness
c_ui->ready = 0;
// reset accepting
c_ui->accepting = 0;
uwsgi_log_verbose("[emperor] reload the uwsgi instance %s\n", c_ui->name);
uwsgi_log("[emperor] reload the uwsgi instance %s\n", c_ui->name);
}
void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid, char *socket_name) {
@@ -767,9 +763,6 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
n_ui->uid = uid;
n_ui->gid = gid;
n_ui->last_mod = born;
// start non-ready
n_ui->last_ready = 0;
n_ui->ready = 0;
// start without loyalty
n_ui->last_loyal = 0;
n_ui->loyal = 0;
@@ -981,7 +974,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
#endif
#ifdef UWSGI_CAP
#if defined(CAP_LAST_CAP) && defined(PR_CAPBSET_READ) && defined(PR_CAPBSET_DROP)
if (uwsgi.emperor_cap && uwsgi.emperor_cap_count > 0) {
int i;
for(i=0;i<=CAP_LAST_CAP;i++) {
@@ -1018,7 +1010,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
uwsgi_log("capabilities applied for vassal %s (pid: %d)\n", n_ui->name, (int) getpid());
}
#endif
#endif
#endif
if (uwsgi.emperor_tyrant) {
@@ -1109,7 +1100,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
struct uwsgi_string_list *uct;
uwsgi_foreach(uct, uwsgi.vassals_templates_before) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_includes_before) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_set) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_templates) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_includes) counter += 2;
@@ -1132,12 +1122,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
counter += 2;
}
uwsgi_foreach (uct, uwsgi.vassals_set) {
vassal_argv[counter] = "--set";
vassal_argv[counter + 1] = uct->value;
counter += 2;
}
char *colon = NULL;
if (uwsgi.emperor_broodlord) {
colon = strchr(n_ui->name, ':');
@@ -1559,7 +1543,7 @@ void emperor_loop() {
if (byte == 17) {
ui_current->loyal = 1;
ui_current->last_loyal = uwsgi_now();
uwsgi_log_verbose("[emperor] vassal %s is now loyal\n", ui_current->name);
uwsgi_log("[emperor] vassal %s is now loyal\n", ui_current->name);
// remove it from the blacklist
uwsgi_emperor_blacklist_remove(ui_current->name);
// TODO post-start hook
@@ -1572,22 +1556,12 @@ void emperor_loop() {
emperor_stop(ui_current);
}
else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
uwsgi_log_verbose("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
uwsgi_log("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
char *zerg_name = uwsgi_concat3(ui_current->name, ":", "zerg");
// here we discard socket name as broodlord/zerg cannot be on demand
emperor_add(ui_current->scanner, zerg_name, uwsgi_now(), NULL, 0, ui_current->uid, ui_current->gid, NULL);
free(zerg_name);
}
else if (byte == 5) {
ui_current->accepting = 1;
ui_current->last_accepting = uwsgi_now();
uwsgi_log_verbose("[emperor] vassal %s is ready to accept requests\n", ui_current->name);
}
else if (byte == 1) {
ui_current->ready = 1;
ui_current->last_ready = uwsgi_now();
uwsgi_log_verbose("[emperor] vassal %s has been spawned\n", ui_current->name);
}
}
}
else {
@@ -1790,16 +1764,8 @@ void emperor_send_stats(int fd) {
goto end0;
if (uwsgi_stats_keylong_comma(us, "loyal", (unsigned long long) c_ui->loyal))
goto end0;
if (uwsgi_stats_keylong_comma(us, "ready", (unsigned long long) c_ui->ready))
goto end0;
if (uwsgi_stats_keylong_comma(us, "accepting", (unsigned long long) c_ui->accepting))
goto end0;
if (uwsgi_stats_keylong_comma(us, "last_loyal", (unsigned long long) c_ui->last_loyal))
goto end0;
if (uwsgi_stats_keylong_comma(us, "last_ready", (unsigned long long) c_ui->last_ready))
goto end0;
if (uwsgi_stats_keylong_comma(us, "last_accepting", (unsigned long long) c_ui->last_accepting))
goto end0;
if (uwsgi_stats_keylong_comma(us, "first_run", (unsigned long long) c_ui->first_run))
goto end0;
if (uwsgi_stats_keylong_comma(us, "last_run", (unsigned long long) c_ui->last_run))
@@ -2130,16 +2096,3 @@ void uwsgi_master_manage_emperor_proxy() {
close(ep_client);
}
static void emperor_notify_ready() {
if (!uwsgi.has_emperor) return;
char byte = 1;
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
uwsgi_error("emperor_notify_ready()/write()");
}
}
void uwsgi_setup_emperor() {
if (!uwsgi.has_emperor) return;
uwsgi.notify_ready = emperor_notify_ready;
}
-23
View File
@@ -1,30 +1,9 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
static int error_page(struct wsgi_request *wsgi_req, struct uwsgi_string_list *l) {
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, l) {
struct stat st;
if (!stat(usl->value, &st)) {
int fd = open(usl->value, O_RDONLY);
if (fd >= 0) {
if (uwsgi_response_add_header(wsgi_req, "Content-Type", 12, "text/html", 9)) { close(fd); return 0;}
if (uwsgi_response_add_content_length(wsgi_req, st.st_size)) { close(fd); return 0;}
uwsgi_response_sendfile_do(wsgi_req, fd, 0, st.st_size);
return -1;
}
}
}
return 0;
}
// generate internal server error message
void uwsgi_500(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "500 Internal Server Error", 25)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
if (error_page(wsgi_req, uwsgi.error_page_500)) return;
if (uwsgi_response_add_header(wsgi_req, "Content-Type", 12, "text/plain", 10)) return;
uwsgi_response_write_body_do(wsgi_req, "Internal Server Error", 21);
}
@@ -32,7 +11,6 @@ void uwsgi_500(struct wsgi_request *wsgi_req) {
void uwsgi_404(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "404 Not Found", 13)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
if (error_page(wsgi_req, uwsgi.error_page_404)) return;
if (uwsgi_response_add_header(wsgi_req, "Content-Type", 12, "text/plain", 10)) return;
uwsgi_response_write_body_do(wsgi_req, "Not Found", 9);
}
@@ -40,7 +18,6 @@ void uwsgi_404(struct wsgi_request *wsgi_req) {
void uwsgi_403(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "403 Forbidden", 13)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
if (error_page(wsgi_req, uwsgi.error_page_403)) return;
if (uwsgi_response_add_content_type(wsgi_req, "text/plain", 10)) return;
uwsgi_response_write_body_do(wsgi_req, "Forbidden", 9);
}
-6
View File
@@ -1231,8 +1231,6 @@ static int timerfd_create(clockid_t __clock_id, int __flags) {
return syscall(283, __clock_id, __flags);
#elif defined(__i386__)
return syscall(322, __clock_id, __flags);
#elif defined(__arm__)
return syscall(350, __clock_id, __flags);
#else
return -1;
#endif
@@ -1243,10 +1241,6 @@ static int timerfd_settime(int __ufd, int __flags, __const struct itimerspec *__
return syscall(286, __ufd, __flags, __utmr, __otmr);
#elif defined(__i386__)
return syscall(325, __ufd, __flags, __utmr, __otmr);
#elif defined(__arm__)
return syscall(353, __ufd, __flags, __utmr, __otmr);
#else
return -1;
#endif
}
#endif
+11 -25
View File
@@ -24,29 +24,16 @@ static char *uwsgi_fifo_by_slot() {
return uwsgi.master_fifo->value;
}
#define announce_fifo uwsgi_log_verbose("active master fifo is now %s\n", uwsgi_fifo_by_slot())
static void uwsgi_fifo_set_slot_zero() { uwsgi.master_fifo_slot = 0; announce_fifo; }
static void uwsgi_fifo_set_slot_one() { uwsgi.master_fifo_slot = 1; announce_fifo; }
static void uwsgi_fifo_set_slot_two() { uwsgi.master_fifo_slot = 2; announce_fifo; }
static void uwsgi_fifo_set_slot_three() { uwsgi.master_fifo_slot = 3; announce_fifo; }
static void uwsgi_fifo_set_slot_four() { uwsgi.master_fifo_slot = 4; announce_fifo; }
static void uwsgi_fifo_set_slot_five() { uwsgi.master_fifo_slot = 5; announce_fifo; }
static void uwsgi_fifo_set_slot_six() { uwsgi.master_fifo_slot = 6; announce_fifo; }
static void uwsgi_fifo_set_slot_seven() { uwsgi.master_fifo_slot = 7; announce_fifo; }
static void uwsgi_fifo_set_slot_eight() { uwsgi.master_fifo_slot = 8; announce_fifo; }
static void uwsgi_fifo_set_slot_nine() { uwsgi.master_fifo_slot = 9; announce_fifo; }
static void subscriptions_blocker() {
if (uwsgi.subscriptions_blocked) {
uwsgi_log_verbose("subscriptions re-enabled\n");
uwsgi.subscriptions_blocked = 0;
}
else {
uwsgi.subscriptions_blocked = 1;
uwsgi_log_verbose("subscriptions blocked\n");
}
}
static void uwsgi_fifo_set_slot_zero() { uwsgi.master_fifo_slot = 0; }
static void uwsgi_fifo_set_slot_one() { uwsgi.master_fifo_slot = 1; }
static void uwsgi_fifo_set_slot_two() { uwsgi.master_fifo_slot = 2; }
static void uwsgi_fifo_set_slot_three() { uwsgi.master_fifo_slot = 3; }
static void uwsgi_fifo_set_slot_four() { uwsgi.master_fifo_slot = 4; }
static void uwsgi_fifo_set_slot_five() { uwsgi.master_fifo_slot = 5; }
static void uwsgi_fifo_set_slot_six() { uwsgi.master_fifo_slot = 6; }
static void uwsgi_fifo_set_slot_seven() { uwsgi.master_fifo_slot = 7; }
static void uwsgi_fifo_set_slot_eight() { uwsgi.master_fifo_slot = 8; }
static void uwsgi_fifo_set_slot_nine() { uwsgi.master_fifo_slot = 9; }
/*
@@ -84,7 +71,6 @@ void uwsgi_master_fifo_prepare() {
uwsgi_fifo_table['r'] = grace_them_all;
uwsgi_fifo_table['R'] = reap_them_all;
uwsgi_fifo_table['s'] = stats;
uwsgi_fifo_table['S'] = subscriptions_blocker;
uwsgi_fifo_table['w'] = uwsgi_reload_workers;
uwsgi_fifo_table['W'] = uwsgi_brutally_reload_workers;
@@ -113,7 +99,7 @@ int uwsgi_master_fifo() {
}
int uwsgi_master_fifo_manage(int fd) {
unsigned char cmd;
char cmd;
ssize_t rlen = read(fd, &cmd, 1);
if (rlen < 0) {
if (uwsgi_is_again()) return 0;
-1
View File
@@ -38,7 +38,6 @@ void uwsgi_fsmon_setup() {
char *space = strchr(copy, ' ');
if (!space) {
uwsgi_log("[uwsgi-fsmon] invalid syntax: \"%s\"\n", usl->value);
free(copy);
goto next;
}
*space = 0;
+1 -21
View File
@@ -17,7 +17,7 @@ uint32_t djb33x_hash(char *key, uint64_t keylen) {
// Murmur2 hash Copyright (C) Austin Appleby
// adapted from nginx
static uint32_t murmur2_hash(char *key, uint64_t keylen) {
uint32_t murmur2_hash(char *key, uint64_t keylen) {
uint32_t h, k;
uint8_t *ukey = (uint8_t *) key;
@@ -56,23 +56,6 @@ static uint32_t murmur2_hash(char *key, uint64_t keylen) {
return h;
}
static uint32_t random_hash(char *key, uint64_t keylen) {
return (uint32_t) rand();
}
/*
not atomic, avoid its use in multithreaded modes
*/
static uint32_t rr_hash(char *key, uint64_t keylen) {
static uint32_t rr = 0;
uint32_t max_value = uwsgi_str_num(key, keylen);
uint32_t ret = rr;
rr++;
if (rr > max_value) {
rr = 0;
}
return ret;
}
struct uwsgi_hash_algo *uwsgi_hash_algo_get(char *name) {
struct uwsgi_hash_algo *uha = uwsgi.hash_algos;
@@ -107,7 +90,4 @@ void uwsgi_hash_algo_register(char *name, uint32_t (*func)(char *, uint64_t)) {
void uwsgi_hash_algo_register_all() {
uwsgi_hash_algo_register("djb33x", djb33x_hash);
uwsgi_hash_algo_register("murmur2", murmur2_hash);
uwsgi_hash_algo_register("random", random_hash);
uwsgi_hash_algo_register("rand", random_hash);
uwsgi_hash_algo_register("rr", rr_hash);
}
-65
View File
@@ -78,67 +78,6 @@ static int uwsgi_hook_print(char *arg) {
return 0;
}
static int uwsgi_hook_unlink(char *arg) {
int ret = unlink(arg);
if (ret) {
uwsgi_error("uwsgi_hook_unlink()/unlink()");
}
return ret;
}
static int uwsgi_hook_writefifo(char *arg) {
char *space = strchr(arg, ' ');
if (!space) {
uwsgi_log("invalid hook writefifo syntax, must be: <file> <string>\n");
return -1;
}
*space = 0;
int fd = open(arg, O_WRONLY|O_NONBLOCK);
if (fd < 0) {
uwsgi_error_open(arg);
*space = ' ';
if (errno == ENODEV) return 0;
#ifdef ENXIO
if (errno == ENXIO) return 0;
#endif
return -1;
}
*space = ' ';
size_t l = strlen(space+1);
if (write(fd, space+1, l) != (ssize_t) l) {
uwsgi_error("uwsgi_hook_writefifo()/write()");
close(fd);
return -1;
}
close(fd);
return 0;
}
static int uwsgi_hook_write(char *arg) {
char *space = strchr(arg, ' ');
if (!space) {
uwsgi_log("invalid hook write syntax, must be: <file> <string>\n");
return -1;
}
*space = 0;
int fd = open(arg, O_WRONLY);
if (fd < 0) {
uwsgi_error_open(arg);
*space = ' ';
return -1;
}
*space = ' ';
size_t l = strlen(space+1);
if (write(fd, space+1, l) != (ssize_t) l) {
uwsgi_error("uwsgi_hook_write()/write()");
close(fd);
return -1;
}
close(fd);
return 0;
}
static int uwsgi_hook_callint(char *arg) {
char *space = strchr(arg, ' ');
if (space) {
@@ -238,10 +177,6 @@ void uwsgi_register_base_hooks() {
uwsgi_register_hook("cd", uwsgi_hook_chdir);
uwsgi_register_hook("exec", uwsgi_hook_exec);
uwsgi_register_hook("write", uwsgi_hook_write);
uwsgi_register_hook("writefifo", uwsgi_hook_writefifo);
uwsgi_register_hook("unlink", uwsgi_hook_unlink);
uwsgi_register_hook("mount", uwsgi_mount_hook);
uwsgi_register_hook("umount", uwsgi_umount_hook);
+6 -3
View File
@@ -51,7 +51,6 @@ struct http_status_codes hsc[] = {
{"503", "Service Unavailable"},
{"504", "Gateway Timeout"},
{"505", "HTTP Version Not Supported"},
{"509", "Bandwidth Limit Exceeded"},
{"", NULL},
};
@@ -170,8 +169,6 @@ void uwsgi_init_default() {
uwsgi.wait_read_hook = uwsgi_simple_wait_read_hook;
uwsgi.wait_write_hook = uwsgi_simple_wait_write_hook;
uwsgi.wait_milliseconds_hook = uwsgi_simple_wait_milliseconds_hook;
uwsgi.wait_read2_hook = uwsgi_simple_wait_read2_hook;
uwsgi_websockets_init();
@@ -348,6 +345,7 @@ void uwsgi_setup_workers() {
uwsgi.workers[i].signal_pipe[0] = -1;
uwsgi.workers[i].signal_pipe[1] = -1;
snprintf(uwsgi.workers[i].name, 0xff, "uWSGI worker %d", i);
snprintf(uwsgi.workers[i].snapshot_name, 0xff, "uWSGI snapshot %d", i);
}
uint64_t total_memory = (sizeof(struct uwsgi_app) * uwsgi.max_apps) + (sizeof(struct uwsgi_core) * uwsgi.cores) + (sizeof(void *) * uwsgi.max_apps * uwsgi.cores) + (uwsgi.buffer_size * uwsgi.cores) + (sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
@@ -449,6 +447,11 @@ void sanitize_args() {
}
}
if (uwsgi.auto_snapshot > 0 && uwsgi.auto_snapshot > uwsgi.numproc) {
uwsgi_log("invalid auto-snapshot value: must be <= than processes\n");
exit(1);
}
if (uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] > 0 && uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME] >= uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME]) {
uwsgi_log("invalid min-worker-lifetime value (%d), must be lower than max-worker-lifetime (%d)\n",
uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME], uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME]);
+8 -14
View File
@@ -270,7 +270,7 @@ static char *uwsgi_scheme_emperor(char *url, size_t *size, int add_zero) {
}
rlen = read(uwsgi.emperor_fd_config, ptr, remains);
if (rlen <= 0) {
uwsgi_log("[uwsgi-vassal] error reading config header from %s !!!\n", url);
uwsgi_log("[uwsgi-vassal] error reading config header from !!!\n", url);
exit(1);
}
ptr+=rlen;
@@ -293,7 +293,7 @@ static char *uwsgi_scheme_emperor(char *url, size_t *size, int add_zero) {
}
rlen = read(uwsgi.emperor_fd_config, ptr, remains);
if (rlen <= 0) {
uwsgi_log("[uwsgi-vassal] error reading config from %s !!!\n", url);
uwsgi_log("[uwsgi-vassal] error reading config from !!!\n", url);
exit(1);
}
ptr+=rlen;
@@ -364,7 +364,6 @@ static char *uwsgi_scheme_data(char *url, size_t *size, int add_zero) {
}
}
}
close(fd);
return buffer;
}
@@ -756,12 +755,11 @@ int uwsgi_write_true_nb(int fd, char *buf, size_t remains, int timeout) {
int ret;
while(remains > 0) {
errno = 0;
ssize_t len = write(fd, ptr, remains);
if (len > 0) goto written;
if (len == 0) return -1;
if (len < 0) {
if (uwsgi_is_again()) goto wait;
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait;
return -1;
}
wait:
@@ -912,7 +910,7 @@ ssize_t uwsgi_read_true_nb(int fd, char *buf, size_t len, int timeout) {
}
if (rlen == 0) return -1;
if (rlen < 0) {
if (uwsgi_is_again()) goto wait;
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait;
}
return -1;
wait:
@@ -944,12 +942,12 @@ int uwsgi_read_whole_true_nb(int fd, char *buf, size_t remains, int timeout) {
}
/*
this is a pretty magic function used for reading a full uwsgi response
this is a pretty magic function used for read a full uwsgi response
it is true non blocking, so you can use it in request plugins
buffer is expected to be at least 4 bytes, rlen is a get/set value
*/
int uwsgi_read_with_realloc(int fd, char **buffer, size_t *rlen, int timeout, uint8_t *modifier1, uint8_t *modifier2) {
int uwsgi_read_with_realloc(int fd, char **buffer, size_t *rlen, int timeout) {
if (*rlen < 4) return -1;
char *buf = *buffer;
int ret;
@@ -962,7 +960,7 @@ int uwsgi_read_with_realloc(int fd, char **buffer, size_t *rlen, int timeout, ui
if (len > 0) goto readok;
if (len == 0) return -1;
if (len < 0) {
if (uwsgi_is_again()) goto wait;
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait;
return -1;
}
wait:
@@ -980,10 +978,6 @@ readok:
struct uwsgi_header *uh = (struct uwsgi_header *) buf;
uint16_t pktsize = uh->pktsize;
if (modifier1)
*modifier1 = uh->modifier1;
if (modifier2)
*modifier2 = uh->modifier2;
if (pktsize > *rlen) {
char *tmp_buf = realloc(buf, pktsize);
@@ -1004,7 +998,7 @@ readok:
if (len > 0) goto readok2;
if (len == 0) return -1;
if (len < 0) {
if (uwsgi_is_again()) goto wait2;
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait2;
return -1;
}
wait2:
-1
View File
@@ -647,7 +647,6 @@ void *uwsgi_robust_mutexes_watchdog_loop(void *arg) {
for(;;) {
uwsgi_lock(uwsgi.the_thunder_lock);
uwsgi_unlock(uwsgi.the_thunder_lock);
sleep(1);
}
return NULL;
}
+203 -147
View File
@@ -211,6 +211,49 @@ void create_logpipe(void) {
}
#ifdef UWSGI_ZEROMQ
// the zeromq logger
ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *ul, char *message, size_t len) {
if (!ul->configured) {
if (!ul->arg) {
uwsgi_log_safe("invalid zeromq syntax\n");
exit(1);
}
void *ctx = uwsgi_zeromq_init();
ul->data = zmq_socket(ctx, ZMQ_PUSH);
if (ul->data == NULL) {
uwsgi_error_safe("zmq_socket()");
exit(1);
}
if (zmq_connect(ul->data, ul->arg) < 0) {
uwsgi_error_safe("zmq_connect()");
exit(1);
}
ul->configured = 1;
}
zmq_msg_t msg;
if (zmq_msg_init_size(&msg, len) == 0) {
memcpy(zmq_msg_data(&msg), message, len);
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
zmq_sendmsg(ul->data, &msg, 0);
#else
zmq_send(ul->data, &msg, 0);
#endif
zmq_msg_close(&msg);
}
return 0;
}
#endif
// log to the specified file or udp address
void logto(char *logfile) {
@@ -455,7 +498,7 @@ void uwsgi_check_logrotate(void) {
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
}
if (uwsgi.log_maxsize > 0 && (uint64_t) uwsgi.shared->logsize > uwsgi.log_maxsize) {
if (uwsgi.log_maxsize > 0 && uwsgi.shared->logsize > uwsgi.log_maxsize) {
need_rotation = 1;
}
@@ -532,7 +575,6 @@ void uwsgi_log_reopen() {
if (uwsgi.original_log_fd < 0) {
uwsgi_error_open(uwsgi.logfile);
grace_them_all(0);
return;
}
ret = snprintf(message, 1024, "[%d] %s reopened.\n", (int) uwsgi_now(), uwsgi.logfile);
if (ret > 0) {
@@ -575,9 +617,6 @@ void log_request(struct wsgi_request *wsgi_req) {
if (uwsgi.shared->options[UWSGI_OPTION_LOG_SENDFILE] && wsgi_req->via == UWSGI_VIA_SENDFILE) {
goto logit;
}
if (uwsgi.shared->options[UWSGI_OPTION_LOG_IOERROR] && wsgi_req->read_errors > 0 && wsgi_req->write_errors > 0) {
goto logit;
}
if (!log_it)
return;
@@ -941,20 +980,6 @@ void uwsgi_logit_lf(struct wsgi_request *wsgi_req) {
uwsgi.logvectors[wsgi_req->async_id][pos].iov_len = 0;
}
}
// var
else if (logchunk->type == 5) {
uint16_t value_len = 0;
char *value = uwsgi_get_var(wsgi_req, logchunk->ptr, logchunk->len, &value_len);
// could be NULL
uwsgi.logvectors[wsgi_req->async_id][pos].iov_base = value;
uwsgi.logvectors[wsgi_req->async_id][pos].iov_len = (size_t) value_len;
}
// metric
else if (logchunk->type == 4) {
int64_t metric = uwsgi_metric_get(logchunk->ptr, NULL);
uwsgi.logvectors[wsgi_req->async_id][pos].iov_base = uwsgi_64bit2str(metric);
uwsgi.logvectors[wsgi_req->async_id][pos].iov_len = strlen(uwsgi.logvectors[wsgi_req->async_id][pos].iov_base);
}
if (uwsgi.logvectors[wsgi_req->async_id][pos].iov_len == 0 && logchunk->type != 0) {
uwsgi.logvectors[wsgi_req->async_id][pos].iov_base = (char *) empty_var;
@@ -980,6 +1005,10 @@ void uwsgi_logit_lf(struct wsgi_request *wsgi_req) {
}
}
void uwsgi_logit_lf_strftime(struct wsgi_request *wsgi_req) {
uwsgi_log("lf strftime\n");
}
void uwsgi_build_log_format(char *format) {
int state = 0;
char *ptr = format;
@@ -1103,16 +1132,6 @@ static ssize_t uwsgi_lf_ftime(struct wsgi_request * wsgi_req, char **buf) {
return ret;
}
static ssize_t uwsgi_lf_tmsecs(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_64bit2str(wsgi_req->start_of_request / (int64_t) 1000);
return strlen(*buf);
}
static ssize_t uwsgi_lf_tmicros(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_64bit2str(wsgi_req->start_of_request);
return strlen(*buf);
}
static ssize_t uwsgi_lf_micros(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->end_of_request - wsgi_req->start_of_request);
return strlen(*buf);
@@ -1188,54 +1207,6 @@ static ssize_t uwsgi_lf_headers(struct wsgi_request * wsgi_req, char **buf) {
return strlen(*buf);
}
static ssize_t uwsgi_lf_werr(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str((int) wsgi_req->write_errors);
return strlen(*buf);
}
static ssize_t uwsgi_lf_rerr(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str((int) wsgi_req->read_errors);
return strlen(*buf);
}
static ssize_t uwsgi_lf_ioerr(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str((int) (wsgi_req->write_errors + wsgi_req->read_errors));
return strlen(*buf);
}
struct uwsgi_logchunk *uwsgi_register_logchunk(char *name, ssize_t (*func)(struct wsgi_request *, char **), int need_free) {
struct uwsgi_logchunk *old_logchunk = NULL, *logchunk = uwsgi.registered_logchunks;
while(logchunk) {
if (!strcmp(logchunk->name, name)) goto found;
old_logchunk = logchunk;
logchunk = logchunk->next;
}
logchunk = uwsgi_calloc(sizeof(struct uwsgi_logchunk));
logchunk->name = name;
if (old_logchunk) {
old_logchunk->next = logchunk;
}
else {
uwsgi.registered_logchunks = logchunk;
}
found:
logchunk->func = func;
logchunk->free = need_free;
logchunk->type = 3;
return logchunk;
}
struct uwsgi_logchunk *uwsgi_get_logchunk_by_name(char *name, size_t name_len) {
struct uwsgi_logchunk *logchunk = uwsgi.registered_logchunks;
while(logchunk) {
if (!uwsgi_strncmp(name, name_len, logchunk->name, strlen(logchunk->name))) {
return logchunk;
}
logchunk = logchunk->next;
}
return NULL;
}
void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
struct uwsgi_logchunk *logchunk = uwsgi.logchunks;
@@ -1256,12 +1227,10 @@ void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
}
/*
0 -> raw text
0 -> raw test
1 -> offsetof variable
2 -> logvar
3 -> func
4 -> metric
5 -> request variable
*/
logchunk->type = variable;
@@ -1271,29 +1240,161 @@ void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
logchunk->len = len;
// variable
if (variable) {
struct uwsgi_logchunk *rlc = uwsgi_get_logchunk_by_name(ptr, len);
if (rlc) {
if (rlc->type == 1) {
logchunk->pos = rlc->pos;
logchunk->pos_len = rlc->pos_len;
}
else if (rlc->type == 3) {
logchunk->type = 3;
logchunk->func = rlc->func;
logchunk->free = rlc->free;
}
if (!uwsgi_strncmp(ptr, len, "uri", 3)) {
logchunk->pos = offsetof(struct wsgi_request, uri);
logchunk->pos_len = offsetof(struct wsgi_request, uri_len);
}
// var
else if (!uwsgi_starts_with(ptr, len, "var.", 4)) {
logchunk->type = 5;
logchunk->ptr = ptr+4;
logchunk->len = len-4;
logchunk->free = 0;
else if (!uwsgi_strncmp(ptr, len, "method", 6)) {
logchunk->pos = offsetof(struct wsgi_request, method);
logchunk->pos_len = offsetof(struct wsgi_request, method_len);
}
// metric
else if (!uwsgi_starts_with(ptr, len, "metric.", 7)) {
logchunk->type = 4;
logchunk->ptr = uwsgi_concat2n(ptr+7, len - 7, "", 0);
else if (!uwsgi_strncmp(ptr, len, "user", 4)) {
logchunk->pos = offsetof(struct wsgi_request, remote_user);
logchunk->pos_len = offsetof(struct wsgi_request, remote_user_len);
}
else if (!uwsgi_strncmp(ptr, len, "addr", 4)) {
logchunk->pos = offsetof(struct wsgi_request, remote_addr);
logchunk->pos_len = offsetof(struct wsgi_request, remote_addr_len);
}
else if (!uwsgi_strncmp(ptr, len, "host", 4)) {
logchunk->pos = offsetof(struct wsgi_request, host);
logchunk->pos_len = offsetof(struct wsgi_request, host_len);
}
else if (!uwsgi_strncmp(ptr, len, "proto", 5)) {
logchunk->pos = offsetof(struct wsgi_request, protocol);
logchunk->pos_len = offsetof(struct wsgi_request, protocol_len);
}
else if (!uwsgi_strncmp(ptr, len, "uagent", 6)) {
logchunk->pos = offsetof(struct wsgi_request, user_agent);
logchunk->pos_len = offsetof(struct wsgi_request, user_agent_len);
}
else if (!uwsgi_strncmp(ptr, len, "referer", 7)) {
logchunk->pos = offsetof(struct wsgi_request, referer);
logchunk->pos_len = offsetof(struct wsgi_request, referer_len);
}
else if (!uwsgi_strncmp(ptr, len, "status", 6)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_status;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "rsize", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_rsize;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "hsize", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_hsize;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "size", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_size;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "cl", 2)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_cl;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "micros", 6)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_micros;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "msecs", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_msecs;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "time", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_time;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "ltime", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_ltime;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "ftime", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_ftime;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "ctime", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_ctime;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "epoch", 5)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_epoch;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "pid", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_pid;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "wid", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_wid;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "switches", 8)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_switches;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "vars", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_vars;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "core", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_core;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "vsz", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_vsz;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "rss", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_rss;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "vszM", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_vszM;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "rssM", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_rssM;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "pktsize", 7)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_pktsize;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "modifier1", 9)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_modifier1;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "modifier2", 9)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_modifier2;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "headers", 7)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_headers;
logchunk->free = 1;
}
// logvar
@@ -1740,7 +1841,7 @@ void uwsgi_log_encoder_parse_vars(struct uwsgi_log_encoder *ule) {
/*
// format: foo ${var} bar
msg (the logline)
msgnl (the logline with newline)
msgnl (the logine with newline)
unix (the time_t value)
micros (current microseconds)
strftime (strftime)
@@ -1866,51 +1967,6 @@ end:
return buf;
}
#define r_logchunk(x) uwsgi_register_logchunk(#x, uwsgi_lf_ ## x, 1)
#define r_logchunk_offset(x, y) { struct uwsgi_logchunk *lc = uwsgi_register_logchunk(#x, NULL, 0); lc->pos = offsetof(struct wsgi_request, y); lc->pos_len = offsetof(struct wsgi_request, y ## _len); lc->type = 1; lc->free=0;}
void uwsgi_register_logchunks() {
// offsets
r_logchunk_offset(uri, uri);
r_logchunk_offset(method, method);
r_logchunk_offset(user, remote_user);
r_logchunk_offset(addr, remote_addr);
r_logchunk_offset(host, host);
r_logchunk_offset(proto, protocol);
r_logchunk_offset(uagent, user_agent);
r_logchunk_offset(referer, referer);
// funcs
r_logchunk(status);
r_logchunk(rsize);
r_logchunk(hsize);
r_logchunk(size);
r_logchunk(cl);
r_logchunk(micros);
r_logchunk(msecs);
r_logchunk(tmsecs);
r_logchunk(tmicros);
r_logchunk(time);
r_logchunk(ltime);
r_logchunk(ftime);
r_logchunk(ctime);
r_logchunk(epoch);
r_logchunk(pid);
r_logchunk(wid);
r_logchunk(switches);
r_logchunk(vars);
r_logchunk(core);
r_logchunk(vsz);
r_logchunk(rss);
r_logchunk(vszM);
r_logchunk(rssM);
r_logchunk(pktsize);
r_logchunk(modifier1);
r_logchunk(modifier2);
r_logchunk(headers);
r_logchunk(werr);
r_logchunk(rerr);
r_logchunk(ioerr);
}
void uwsgi_log_encoders_register_embedded() {
uwsgi_register_log_encoder("prefix", uwsgi_log_encoder_prefix);
+66 -69
View File
@@ -2,29 +2,14 @@
extern struct uwsgi_server uwsgi;
void uwsgi_update_load_counters() {
void uwsgi_restore_auto_snapshot(int signum) {
int i;
uint64_t busy_workers = 0;
uint64_t idle_workers = 0;
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
if (uwsgi_worker_is_busy(i) == 0) {
idle_workers++;
}
else {
busy_workers++;
}
}
}
if (busy_workers >= (uint64_t) uwsgi.numproc) {
ushared->overloaded++;
if (uwsgi.workers[1].snapshot > 0) {
uwsgi.restore_snapshot = 1;
}
else {
uwsgi_log("[WARNING] no snapshot available\n");
}
ushared->busy_workers = busy_workers;
ushared->idle_workers = idle_workers;
}
@@ -47,25 +32,24 @@ void uwsgi_unblock_signal(int signum) {
}
void uwsgi_master_manage_udp(int udp_fd) {
char buf[4096];
struct sockaddr_in udp_client;
char udp_client_addr[16];
int i;
socklen_t udp_len = sizeof(udp_client);
ssize_t rlen = recvfrom(udp_fd, buf, 4096, 0, (struct sockaddr *) &udp_client, &udp_len);
ssize_t rlen = recvfrom(udp_fd, uwsgi.wsgi_req->buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len);
if (rlen < 0) {
uwsgi_error("uwsgi_master_manage_udp()/recvfrom()");
uwsgi_error("recvfrom()");
}
else if (rlen > 0) {
memset(udp_client_addr, 0, 16);
if (inet_ntop(AF_INET, &udp_client.sin_addr.s_addr, udp_client_addr, 16)) {
if (buf[0] == UWSGI_MODIFIER_MULTICAST_ANNOUNCE) {
if (uwsgi.wsgi_req->buffer[0] == UWSGI_MODIFIER_MULTICAST_ANNOUNCE) {
}
else if (buf[0] == 0x30 && uwsgi.snmp) {
manage_snmp(udp_fd, (uint8_t *) buf, rlen, &udp_client);
else if (uwsgi.wsgi_req->buffer[0] == 0x30 && uwsgi.snmp) {
manage_snmp(udp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client);
}
else {
@@ -73,7 +57,7 @@ void uwsgi_master_manage_udp(int udp_fd) {
int udp_managed = 0;
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, buf, rlen)) {
if (uwsgi.p[i]->manage_udp(udp_client_addr, udp_client.sin_port, uwsgi.wsgi_req->buffer, rlen)) {
udp_managed = 1;
break;
}
@@ -82,17 +66,42 @@ void uwsgi_master_manage_udp(int udp_fd) {
// else a simple udp logger
if (!udp_managed) {
uwsgi_log("[udp:%s:%d] %.*s", udp_client_addr, ntohs(udp_client.sin_port), (int) rlen, buf);
uwsgi_log("[udp:%s:%d] %.*s", udp_client_addr, ntohs(udp_client.sin_port), (int) rlen, uwsgi.wsgi_req->buffer);
}
}
}
else {
uwsgi_error("uwsgi_master_manage_udp()/inet_ntop()");
uwsgi_error("inet_ntop()");
}
}
}
void uwsgi_master_restore_snapshot() {
int i, waitpid_status;
uwsgi_log("[snapshot] restoring workers...\n");
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].pid == 0)
continue;
kill(uwsgi.workers[i].pid, SIGKILL);
if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
uwsgi_error("waitpid()");
}
if (uwsgi.auto_snapshot > 0 && i > uwsgi.auto_snapshot) {
uwsgi.workers[i].pid = 0;
uwsgi.workers[i].snapshot = 0;
}
else {
uwsgi.workers[i].pid = uwsgi.workers[i].snapshot;
uwsgi.workers[i].snapshot = 0;
kill(uwsgi.workers[i].pid, SIGURG);
uwsgi_log("Restored uWSGI worker %d (pid: %d)\n", i, (int) uwsgi.workers[i].pid);
}
}
uwsgi.restore_snapshot = 0;
}
void suspend_resume_them_all(int signum) {
int i;
@@ -290,6 +299,9 @@ int master_loop(char **argv, char **environ) {
}
uwsgi_unix_signal(SIGINT, kill_them_all);
uwsgi_unix_signal(SIGUSR1, stats);
if (uwsgi.auto_snapshot) {
uwsgi_unix_signal(SIGURG, uwsgi_restore_auto_snapshot);
}
atexit(uwsgi_master_cleanup_hooks);
@@ -334,7 +346,6 @@ int master_loop(char **argv, char **environ) {
#ifdef UWSGI_SSL
uwsgi_start_legions();
#endif
uwsgi_metrics_start_collector();
uwsgi_add_reload_fds();
@@ -475,28 +486,6 @@ int master_loop(char **argv, char **environ) {
// fsmon
uwsgi_fsmon_setup();
uwsgi_foreach(usl, uwsgi.signal_timers) {
char *space = strchr(usl->value, ' ');
if (!space) {
uwsgi_log("invalid signal timer syntax, must be: <signal> <seconds>\n");
exit(1);
}
*space = 0;
uwsgi_add_timer(atoi(usl->value), atoi(space+1));
*space = ' ';
}
uwsgi_foreach(usl, uwsgi.rb_signal_timers) {
char *space = strchr(usl->value, ' ');
if (!space) {
uwsgi_log("invalid redblack signal timer syntax, must be: <signal> <seconds>\n");
exit(1);
}
*space = 0;
uwsgi_signal_add_rb_timer(atoi(usl->value), atoi(space+1), 0);
*space = ' ';
}
// setup cheaper algos (can be stacked)
uwsgi.cheaper_algo = uwsgi_cheaper_algo_spare;
if (uwsgi.requested_cheaper_algo) {
@@ -550,6 +539,21 @@ int master_loop(char **argv, char **environ) {
// check for daemons (smart and dumb)
uwsgi_daemons_smart_check();
if (uwsgi.respawn_snapshots) {
for (i = 1; i <= uwsgi.respawn_snapshots; i++) {
if (uwsgi_respawn_worker(i))
return 0;
}
uwsgi.respawn_snapshots = 0;
}
if (uwsgi.restore_snapshot) {
uwsgi_master_restore_snapshot();
continue;
}
// cheaper management
if (uwsgi.cheaper && !uwsgi.status.is_cheap && !uwsgi_instance_is_reloading && !uwsgi_instance_is_dying && !uwsgi.workers[0].suspended) {
if (!uwsgi_calc_cheaper())
@@ -579,10 +583,8 @@ int master_loop(char **argv, char **environ) {
/* all processes ok, doing status scan after N seconds */
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval) {
if (!check_interval)
check_interval = 1;
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = 1;
}
// add unregistered file monitors
@@ -617,14 +619,14 @@ int master_loop(char **argv, char **environ) {
if (ushared->rb_timers_cnt > 0) {
min_timeout = uwsgi_min_rb_timer(rb_timers, NULL);
if (min_timeout) {
int delta = min_timeout->value - uwsgi_now();
if (delta <= 0) {
if (min_timeout == NULL) {
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
}
else {
check_interval = min_timeout->value - uwsgi_now();
if (check_interval <= 0) {
expire_rb_timeouts(rb_timers);
}
// if the timer expires before the check_interval, override it
else if (delta < check_interval) {
check_interval = delta;
check_interval = 0;
}
}
}
@@ -638,9 +640,6 @@ int master_loop(char **argv, char **environ) {
}
}
// update load counter
uwsgi_update_load_counters();
// check uwsgi-cron table
if (ushared->cron_cnt) {
@@ -681,10 +680,8 @@ int master_loop(char **argv, char **environ) {
uwsgi_master_check_idle();
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval) {
if (!check_interval)
check_interval = 1;
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = 1;
}
// get listen_queue status
-2
View File
@@ -48,8 +48,6 @@ void uwsgi_master_check_chain() {
}
uwsgi_block_signal(SIGHUP);
for(i=1;i<=uwsgi.numproc;i++) {
// do not curse a worker until the old one is ready
if (uwsgi.workers[i].accepting == 0) break;
if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].cursed_at == 0 && i == uwsgi.status.chain_reloading) {
uwsgi_curse(i, SIGHUP);
break;
-1
View File
@@ -118,7 +118,6 @@ int uwsgi_master_manage_events(int interesting_fd) {
reap_them_all(0);
uwsgi_unblock_signal(SIGTERM);
}
if (usl->custom2 > 8) free(tmp);
return 0;
}
usl = usl->next;
-71
View File
@@ -592,8 +592,6 @@ void uwsgi_fixup_fds(int wid, int muleid, struct uwsgi_gateway *ug) {
int uwsgi_respawn_worker(int wid) {
int respawns = uwsgi.workers[wid].respawn_count;
// the workers is not accepting (obviously)
uwsgi.workers[wid].accepting = 0;
// we count the respawns before errors...
uwsgi.workers[wid].respawn_count++;
// ... same for update time
@@ -873,70 +871,6 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
goto end;
}
if (uwsgi.has_metrics) {
if (uwsgi_stats_key(us, "metrics"))
goto end;
if (uwsgi_stats_object_open(us))
goto end;
uwsgi_rlock(uwsgi.metrics_lock);
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
int64_t um_val = *um->value;
if (uwsgi_stats_key(us, um->name)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_object_open(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_keylong(us, "type", (long long) um->type)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_comma(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_keyval_comma(us, "oid", um->oid ? um->oid : "")) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_keyslong(us, "value", (long long) um_val)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_object_close(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
um = um->next;
if (um) {
if (uwsgi_stats_comma(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
}
}
uwsgi_rwunlock(uwsgi.metrics_lock);
if (uwsgi_stats_object_close(us))
goto end;
if (uwsgi_stats_comma(us))
goto end;
}
if (uwsgi_stats_key(us, "sockets"))
goto end;
@@ -992,8 +926,6 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
goto end;
if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) uwsgi.workers[i + 1].pid))
goto end;
if (uwsgi_stats_keylong_comma(us, "accepting", (unsigned long long) uwsgi.workers[i + 1].accepting))
goto end;
if (uwsgi_stats_keylong_comma(us, "requests", (unsigned long long) uwsgi.workers[i + 1].requests))
goto end;
if (uwsgi_stats_keylong_comma(us, "delta_requests", (unsigned long long) uwsgi.workers[i + 1].delta_requests))
@@ -1133,9 +1065,6 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
if (uwsgi_stats_keylong_comma(us, "write_errors", (unsigned long long) uc->write_errors))
goto end;
if (uwsgi_stats_keylong_comma(us, "read_errors", (unsigned long long) uc->read_errors))
goto end;
if (uwsgi_stats_keylong_comma(us, "in_request", (unsigned long long) uc->in_request))
goto end;
+54 -964
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -77,7 +77,6 @@ void uwsgi_mule(int id) {
}
}
uwsgi_hooks_run(uwsgi.hook_as_mule, "as-mule", 1);
uwsgi_mule_run();
}
+1 -1
View File
@@ -1,4 +1,4 @@
#include <uwsgi.h>
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
-112
View File
@@ -1,112 +0,0 @@
#include <uwsgi.h>
#define UWSGI_BUILD_DIR ".uwsgi_plugins_builder"
/*
steps:
mkdir(.uwsgi_plugin_builder)
generate .uwsgi_plugin_builder/uwsgi.h
generate .uwsgi_plugin_builder/uwsgiconfig.py
setenv(UWSGI_PLUGINS_BUILDER_CFLAGS=uwsgi_cflags)
exec PYTHON .uwsgi_plugin_builder/uwsgiconfig.py --extra-plugin <directory> [name]
*/
void uwsgi_build_plugin(char *directory) {
if (!uwsgi_file_exists(UWSGI_BUILD_DIR)) {
if (mkdir(UWSGI_BUILD_DIR, S_IRWXU) < 0) {
uwsgi_error("uwsgi_build_plugin()/mkdir() " UWSGI_BUILD_DIR "/");
_exit(1);
}
}
char *dot_h = uwsgi_get_dot_h();
if (!dot_h) {
uwsgi_log("unable to generate uwsgi.h");
_exit(1);
}
if (strlen(dot_h) == 0) {
free(dot_h);
uwsgi_log("invalid uwsgi.h");
_exit(1);
}
int dot_h_fd = open(UWSGI_BUILD_DIR "/uwsgi.h", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if (dot_h_fd < 0) {
uwsgi_error_open(UWSGI_BUILD_DIR "/uwsgi.h");
free(dot_h);
_exit(1);
}
ssize_t dot_h_len = (ssize_t) strlen(dot_h);
if (write(dot_h_fd, dot_h, dot_h_len) != dot_h_len) {
uwsgi_error("uwsgi_build_plugin()/write()");
_exit(1);
}
char *config_py = uwsgi_get_config_py();
if (!config_py) {
uwsgi_log("unable to generate uwsgiconfig.py");
_exit(1);
}
if (strlen(config_py) == 0) {
uwsgi_log("invalid uwsgiconfig.py");
_exit(1);
}
int config_py_fd = open(UWSGI_BUILD_DIR "/uwsgiconfig.py", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if (config_py_fd < 0) {
uwsgi_error_open(UWSGI_BUILD_DIR "/uwsgiconfig.py");
_exit(1);
}
ssize_t config_py_len = (ssize_t) strlen(config_py);
if (write(config_py_fd, config_py, config_py_len) != config_py_len) {
uwsgi_error("uwsgi_build_plugin()/write()");
_exit(1);
}
char *cflags = uwsgi_get_cflags();
if (!cflags) {
uwsgi_log("unable to find cflags\n");
_exit(1);
}
if (strlen(cflags) == 0) {
uwsgi_log("invalid cflags\n");
_exit(1);
}
if (setenv("UWSGI_PLUGINS_BUILDER_CFLAGS", cflags, 1)) {
uwsgi_error("uwsgi_build_plugin()/setenv()");
_exit(1);
}
// now run the python script
char *argv[6];
argv[0] = getenv("PYTHON");
if (!argv[0]) argv[0] = "python";
argv[1] = UWSGI_BUILD_DIR "/uwsgiconfig.py";
argv[2] = "--extra-plugin";
char *space = strchr(directory, ' ');
if (space) {
*space = 0;
argv[3] = directory;
argv[4] = space+1;
argv[5] = NULL;
}
else {
argv[3] = directory;
argv[4] = NULL;
}
execvp(argv[0], argv);
// never here...
_exit(1);
}
+12 -67
View File
@@ -24,39 +24,6 @@ int uwsgi_simple_wait_read_hook(int fd, int timeout) {
return ret;
}
int uwsgi_simple_wait_read2_hook(int fd0, int fd1, int timeout, int *fd) {
struct pollfd upoll[2];
timeout = timeout * 1000;
upoll[0].fd = fd0;
upoll[0].events = POLLIN;
upoll[0].revents = 0;
upoll[1].fd = fd1;
upoll[1].events = POLLIN;
upoll[1].revents = 0;
int ret = poll(upoll, 2, timeout);
if (ret > 0) {
if (upoll[0].revents & POLLIN) {
*fd = fd0;
return 1;
}
if (upoll[1].revents & POLLIN) {
*fd = fd1;
return 1;
}
return -1;
}
if (ret < 0) {
uwsgi_error("uwsgi_simple_wait_read_hook2()/poll()");
}
return ret;
}
/*
seek()/rewind() language-independent implementations.
*/
@@ -65,16 +32,14 @@ void uwsgi_request_body_seek(struct wsgi_request *wsgi_req, off_t pos) {
if (wsgi_req->post_file) {
if (pos < 0) {
if (fseek(wsgi_req->post_file, pos, SEEK_CUR)) {
uwsgi_req_error("uwsgi_request_body_seek()/fseek()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_request_body_seek()/fseek()");
}
wsgi_req->post_pos = ftell(wsgi_req->post_file);
return;
}
if (fseek(wsgi_req->post_file, pos, SEEK_SET)) {
uwsgi_req_error("uwsgi_request_body_seek()/fseek()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_request_body_seek()/fseek()");
}
wsgi_req->post_pos = ftell(wsgi_req->post_file);
return;
@@ -130,7 +95,7 @@ static int consume_body_for_readline(struct wsgi_request *wsgi_req) {
if (wsgi_req->post_readline_size - wsgi_req->post_readline_watermark < remains) {
char *tmp_buf = realloc(wsgi_req->post_readline_buf, wsgi_req->post_readline_size + remains);
if (!tmp_buf) {
uwsgi_req_error("consume_body_for_readline()/realloc()");
uwsgi_error("consume_body_for_readline()/realloc()");
return -1;
}
wsgi_req->post_readline_buf = tmp_buf;
@@ -149,7 +114,7 @@ static int consume_body_for_readline(struct wsgi_request *wsgi_req) {
if (wsgi_req->post_file) {
size_t ret = fread(wsgi_req->post_readline_buf + wsgi_req->post_readline_watermark, remains, 1, wsgi_req->post_file);
if (ret == 0) {
uwsgi_req_error("consume_body_for_readline()/fread()");
uwsgi_error("consume_body_for_readline()/fread()");
return -1;
}
wsgi_req->post_pos += remains;
@@ -175,7 +140,6 @@ static int consume_body_for_readline(struct wsgi_request *wsgi_req) {
}
if (len == 0) {
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return -1;
}
if (len < 0) {
@@ -183,7 +147,6 @@ static int consume_body_for_readline(struct wsgi_request *wsgi_req) {
goto wait;
}
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return -1;
}
wait:
@@ -196,7 +159,6 @@ wait:
return 0;
}
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return -1;
}
// 0 means timeout
@@ -205,7 +167,6 @@ wait:
return -1;
}
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return -1;
}
@@ -243,8 +204,7 @@ char *uwsgi_request_body_readline(struct wsgi_request *wsgi_req, ssize_t hint, s
size_t amount = UMIN(uwsgi.buffer_size, wsgi_req->post_cl);
wsgi_req->post_readline_buf = malloc(amount);
if (!wsgi_req->post_readline_buf) {
uwsgi_req_error("uwsgi_request_body_readline()/malloc()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_request_body_readline()/malloc()");
*rlen = -1;
return NULL;
}
@@ -257,7 +217,6 @@ char *uwsgi_request_body_readline(struct wsgi_request *wsgi_req, ssize_t hint, s
if (wsgi_req->post_pos >= wsgi_req->post_cl) break;
if (consume_body_for_readline(wsgi_req)) {
wsgi_req->read_errors++;
*rlen = -1;
return NULL;
}
@@ -313,9 +272,8 @@ char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize
if (avail > wsgi_req->post_read_buf_size) {
char *tmp_buf = realloc(wsgi_req->post_read_buf, avail);
if (!tmp_buf) {
uwsgi_req_error("uwsgi_request_body_read()/realloc()");
uwsgi_error("uwsgi_request_body_read()/realloc()");
*rlen = -1;
wsgi_req->read_errors++;
return NULL;
}
wsgi_req->post_read_buf = tmp_buf;
@@ -362,8 +320,7 @@ char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize
if (!wsgi_req->post_read_buf) {
wsgi_req->post_read_buf = malloc(remains);
if (!wsgi_req->post_read_buf) {
uwsgi_req_error("uwsgi_request_body_read()/malloc()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_request_body_read()/malloc()");
*rlen = -1;
return NULL;
}
@@ -374,8 +331,7 @@ char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize
if ((remains+*rlen) > wsgi_req->post_read_buf_size) {
char *tmp_buf = realloc(wsgi_req->post_read_buf, (remains+*rlen));
if (!tmp_buf) {
uwsgi_req_error("uwsgi_request_body_read()/realloc()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_request_body_read()/realloc()");
*rlen = -1;
return NULL;
}
@@ -392,8 +348,7 @@ char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize
if (wsgi_req->post_file) {
if (fread(wsgi_req->post_read_buf + *rlen, remains, 1, wsgi_req->post_file) != 1) {
*rlen = -1;
uwsgi_req_error("uwsgi_request_body_read()/fread()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_request_body_read()/fread()");
return NULL;
}
*rlen += remains;
@@ -423,7 +378,6 @@ char *uwsgi_request_body_read(struct wsgi_request *wsgi_req, ssize_t hint, ssize
}
*rlen = -1;
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return NULL;
}
wait:
@@ -435,7 +389,7 @@ wait:
remains -= len;
*rlen += len;
continue;
}else if (len < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS)) {
}else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
goto wait;
}
*rlen = -1;
@@ -444,7 +398,6 @@ wait:
}
else {
uwsgi_read_error(remains);
wsgi_req->read_errors++;
}
return NULL;
}
@@ -456,7 +409,6 @@ wait:
}
*rlen = -1;
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return NULL;
}
@@ -495,7 +447,6 @@ int uwsgi_postbuffer_do_in_mem(struct wsgi_request *wsgi_req) {
goto wait;
}
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return -1;
}
@@ -511,7 +462,6 @@ wait:
}
if (ret < 0) {
uwsgi_read_error(remains);
wsgi_req->read_errors++;
return -1;
}
uwsgi_read_timeout(remains);
@@ -532,8 +482,7 @@ int uwsgi_postbuffer_do_in_disk(struct wsgi_request *wsgi_req) {
wsgi_req->post_file = uwsgi_tmpfile();
if (!wsgi_req->post_file) {
uwsgi_req_error("uwsgi_postbuffer_do_in_disk()/uwsgi_tmpfile()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_postbuffer_do_in_disk()/uwsgi_tmpfile()");
return -1;
}
@@ -569,7 +518,6 @@ int uwsgi_postbuffer_do_in_disk(struct wsgi_request *wsgi_req) {
goto wait;
}
uwsgi_read_error(remains);
wsgi_req->read_errors++;
goto end;
}
@@ -583,13 +531,11 @@ wait:
}
else {
uwsgi_read_error(remains);
wsgi_req->read_errors++;
}
goto end;
}
if (ret < 0) {
uwsgi_read_error(remains);
wsgi_req->read_errors++;
goto end;
}
uwsgi_read_timeout(remains);
@@ -597,8 +543,7 @@ wait:
write:
if (fwrite(wsgi_req->post_buffering_buf, rlen, 1, wsgi_req->post_file) != 1) {
uwsgi_req_error("uwsgi_postbuffer_do_in_disk()/fwrite()");
wsgi_req->read_errors++;
uwsgi_error("uwsgi_postbuffer_do_in_disk()/fwrite()");
goto end;
}
+50 -101
View File
@@ -582,88 +582,6 @@ static int uwsgi_router_break(struct uwsgi_route *ur, char *arg) {
return 0;
}
// simple math router
static int uwsgi_router_simple_math_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
uint16_t var_vallen = 0;
char *var_value = uwsgi_get_var(wsgi_req, ur->data, ur->data_len, &var_vallen);
if (!var_value) return UWSGI_ROUTE_BREAK;
int64_t base_value = uwsgi_str_num(var_value, var_vallen);
int64_t value = 1;
if (ur->data2_len) {
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data2, ur->data2_len);
if (!ub) return UWSGI_ROUTE_BREAK;
value = uwsgi_str_num(ub->buf, ub->pos);
uwsgi_buffer_destroy(ub);
}
char out[sizeof(UMAX64_STR)+1];
int64_t total = 0;
switch(ur->custom) {
// -
case 1:
total = base_value - value;
break;
// *
case 2:
total = base_value * value;
break;
// /
case 3:
if (value == 0) total = 0;
else {
total = base_value/value;
}
break;
default:
total = base_value + value;
break;
}
int ret = uwsgi_long2str2n(total, out, sizeof(UMAX64_STR)+1);
if (ret <= 0) return UWSGI_ROUTE_BREAK;
if (!uwsgi_req_append(wsgi_req, ur->data, ur->data_len, out, ret)) {
return UWSGI_ROUTE_BREAK;
}
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_simple_math_plus(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_simple_math_func;
char *comma = strchr(arg, ',');
if (comma) {
ur->data = arg;
ur->data_len = comma - arg;
ur->data2 = comma+1;
ur->data2_len = strlen(ur->data);
}
else {
ur->data = arg;
ur->data_len = strlen(arg);
}
return 0;
}
static int uwsgi_router_simple_math_minus(struct uwsgi_route *ur, char *arg) {
ur->custom = 1;
return uwsgi_router_simple_math_plus(ur, arg);
}
static int uwsgi_router_simple_math_multiply(struct uwsgi_route *ur, char *arg) {
ur->custom = 2;
return uwsgi_router_simple_math_plus(ur, arg);
}
static int uwsgi_router_simple_math_divide(struct uwsgi_route *ur, char *arg) {
ur->custom = 2;
return uwsgi_router_simple_math_plus(ur, arg);
}
// harakiri router
static int uwsgi_router_harakiri_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
@@ -722,6 +640,7 @@ static int uwsgi_router_fixcl(struct uwsgi_route *ur, char *arg) {
return 0;
}
// log route
static int uwsgi_router_log_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
@@ -962,7 +881,7 @@ static int uwsgi_router_chdir_func(struct wsgi_request *wsgi_req, struct uwsgi_r
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
if (!ub) return UWSGI_ROUTE_BREAK;
if (chdir(ub->buf)) {
uwsgi_req_error("uwsgi_router_chdir_func()/chdir()");
uwsgi_error("uwsgi_router_chdir_func()/chdir()");
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
@@ -1280,21 +1199,10 @@ static int uwsgi_router_alarm(struct uwsgi_route *ur, char *arg) {
// send route
static int uwsgi_router_send_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
char **subject = (char **) (((char *)(wsgi_req))+route->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+route->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, route, *subject, *subject_len, route->data, route->data_len);
if (!ub) {
return UWSGI_ROUTE_BREAK;
}
uwsgi_response_write_body_do(wsgi_req, route->data, route->data_len);
if (route->custom) {
if (uwsgi_buffer_append(ub, "\r\n", 2)) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
uwsgi_response_write_body_do(wsgi_req, "\r\n", 2);
}
uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_send(struct uwsgi_route *ur, char *arg) {
@@ -1721,6 +1629,48 @@ static char *uwsgi_route_var_hex(struct wsgi_request *wsgi_req, char *key, uint1
return ret;
}
#ifdef UWSGI_MATHEVAL
static char *uwsgi_route_var_math(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
char *ret = NULL;
// avoid crash
if (!wsgi_req->var_cnt) return NULL;
// we make a bit of fun here, we do a copy of the vars buffer (+1 byte for final zero) and zeor-pad all of the strings
char *vars_buf = uwsgi_malloc(wsgi_req->uh->pktsize + keylen + 1);
char **names = uwsgi_malloc(sizeof(char *) * (wsgi_req->var_cnt/2));
double *values = uwsgi_calloc(sizeof(double) * (wsgi_req->var_cnt/2));
int i,j = 0;
char *ptr = vars_buf;
for (i = wsgi_req->var_cnt-1; i > 0; i -= 2) {
memcpy(ptr, wsgi_req->hvec[i-1].iov_base, wsgi_req->hvec[i-1].iov_len);
names[j] = ptr;
ptr += wsgi_req->hvec[i-1].iov_len;
*ptr++=0;
char *num = ptr;
memcpy(ptr, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
ptr += wsgi_req->hvec[i].iov_len;
*ptr++=0;
values[j] = strtod(num, NULL);
j++;
}
char *expr = ptr;
memcpy(ptr, key, keylen); ptr += keylen;
*ptr++=0;
void *e = evaluator_create(expr);
if (!e) goto end;
double n = evaluator_evaluate(e, j, names, values);
evaluator_destroy(e);
ret = uwsgi_num2str((int)n);
*vallen = strlen(ret);
end:
free(vars_buf);
free(names);
free(values);
return ret;
}
#endif
// register embedded routers
void uwsgi_register_embedded_routers() {
uwsgi_register_router("continue", uwsgi_router_continue);
@@ -1753,11 +1703,6 @@ void uwsgi_register_embedded_routers() {
uwsgi_register_router("setprocname", uwsgi_router_setprocname);
uwsgi_register_router("alarm", uwsgi_router_alarm);
uwsgi_register_router("+", uwsgi_router_simple_math_plus);
uwsgi_register_router("-", uwsgi_router_simple_math_minus);
uwsgi_register_router("*", uwsgi_router_simple_math_multiply);
uwsgi_register_router("/", uwsgi_router_simple_math_divide);
uwsgi_register_router("flush", uwsgi_router_flush);
uwsgi_register_router("fixcl", uwsgi_router_fixcl);
@@ -1801,6 +1746,10 @@ void uwsgi_register_embedded_routers() {
urv->need_free = 1;
urv = uwsgi_register_route_var("httptime", uwsgi_route_var_httptime);
urv->need_free = 1;
#ifdef UWSGI_MATHEVAL
urv = uwsgi_register_route_var("math", uwsgi_route_var_math);
urv->need_free = 1;
#endif
urv = uwsgi_register_route_var("base64", uwsgi_route_var_base64);
urv->need_free = 1;
+8 -36
View File
@@ -59,11 +59,11 @@ already:
return ret;
}
uint64_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], char **output) {
uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], char *output) {
struct uwsgi_rpc *urpc = NULL;
uint64_t i;
uint64_t ret = 0;
uint16_t ret = 0;
int pos = (uwsgi.mywid * uwsgi.rpc_max);
@@ -85,15 +85,8 @@ uint64_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], cha
return ret;
}
static void rpc_context_hook(char *key, uint16_t kl, char *value, uint16_t vl, void *data) {
size_t *r = (size_t *) data;
if (!uwsgi_strncmp(key, kl, "CONTENT_LENGTH", 14)) {
*r = uwsgi_str_num(value, vl);
}
}
char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t argvs[], uint64_t * len) {
char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t argvs[], uint16_t * len) {
uint8_t i;
uint16_t ulen;
@@ -104,10 +97,9 @@ char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t
if (node == NULL || !strcmp(node, "")) {
// allocate the whole buffer
*len = uwsgi_rpc(func, argc, argv, argvs, &buffer);
if (*buffer)
return buffer;
return NULL;
buffer = uwsgi_malloc(UMAX16);
*len = uwsgi_rpc(func, argc, argv, argvs, buffer);
return buffer;
}
@@ -155,37 +147,17 @@ char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t
bufptr += ulen;
}
// ok the request is ready, let's send it in non blocking way
// ok the reuqest is ready, let's send it in non blocking way
if (uwsgi_write_true_nb(fd, buffer, buffer_size+4, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
goto error;
}
// ok time to wait for the response in non blocking way
size_t rlen = buffer_size+4;
uint8_t modifier2 = 0;
if (uwsgi_read_with_realloc(fd, &buffer, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL, &modifier2)) {
if (uwsgi_read_with_realloc(fd, &buffer, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
goto error;
}
// 64bit response ?
if (modifier2 == 5) {
size_t content_len = 0;
if (uwsgi_hooked_parse(buffer, rlen, rpc_context_hook, &content_len )) goto error;
if (content_len > rlen) {
char *tmp_buf = realloc(buffer, content_len);
if (!tmp_buf) goto error;
buffer = tmp_buf;
}
rlen = content_len;
// read the raw value from the socket
if (uwsgi_read_whole_true_nb(fd, buffer, rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
goto error;
}
}
close(fd);
*len = rlen;
if (*len == 0) {
-366
View File
@@ -1,366 +0,0 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
/*
This is an high-performance memory area shared by all workers/cores/threads
Contrary to the caching subsystem it is 1-copy (caching for non-c apps is 2-copy)
Languages not allowing that kind of access should emulate it calling uwsgi_malloc and then copying it back to
the language object.
The memory areas could be monitored for changes (read: cores can be suspended while waiting for values)
You can configure multiple areas specifying multiple --sharedarea options
This is a very low-level api, try to use it to build higher-level primitives or rely on the caching subsystem
*/
struct uwsgi_sharedarea *uwsgi_sharedarea_get_by_id(int id, uint64_t pos) {
if (id > uwsgi.sharedareas_cnt-1) return NULL;
struct uwsgi_sharedarea *sa = uwsgi.sharedareas[id];
if (pos > sa->max_pos) return NULL;
return sa;
}
int uwsgi_sharedarea_update(int id) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) return -1;
sa->updates++;
return 0;
}
int uwsgi_sharedarea_rlock(int id) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) return -1;
uwsgi_rlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_wlock(int id) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) return -1;
uwsgi_wlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_unlock(int id) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) return -1;
uwsgi_rwunlock(sa->lock);
return 0;
}
int64_t uwsgi_sharedarea_read(int id, uint64_t pos, char *blob, uint64_t len) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + len > sa->max_pos + 1) return -1;
if (len == 0) len = (sa->max_pos + 1) - pos;
if (sa->honour_used && sa->used-pos < len) len = sa->used-pos ;
uwsgi_rlock(sa->lock);
memcpy(blob, sa->area + pos, len);
sa->hits++;
uwsgi_rwunlock(sa->lock);
return len;
}
int uwsgi_sharedarea_write(int id, uint64_t pos, char *blob, uint64_t len) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + len > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
memcpy(sa->area + pos, blob, len);
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_read64(int id, uint64_t pos, int64_t *value) {
int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 8);
return rlen == 8 ? 0 : -1;
}
int uwsgi_sharedarea_write64(int id, uint64_t pos, int64_t *value) {
return uwsgi_sharedarea_write(id, pos, (char *) value, 8);
}
int uwsgi_sharedarea_read8(int id, uint64_t pos, int8_t *value) {
int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 1);
return rlen == 1 ? 0 : -1;
}
int uwsgi_sharedarea_write8(int id, uint64_t pos, int8_t *value) {
return uwsgi_sharedarea_write(id, pos, (char *) value, 1);
}
int uwsgi_sharedarea_read16(int id, uint64_t pos, int16_t *value) {
int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 2);
return rlen == 2 ? 0 : -1;
}
int uwsgi_sharedarea_write16(int id, uint64_t pos, int16_t *value) {
return uwsgi_sharedarea_write(id, pos, (char *) value, 2);
}
int uwsgi_sharedarea_read32(int id, uint64_t pos, int32_t *value) {
int64_t rlen = uwsgi_sharedarea_read(id, pos, (char *) value, 4);
return rlen == 4 ? 0 : -1;
}
int uwsgi_sharedarea_write32(int id, uint64_t pos, int32_t *value) {
return uwsgi_sharedarea_write(id, pos, (char *) value, 4);
}
int uwsgi_sharedarea_inc8(int id, uint64_t pos, int8_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 1 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int8_t *n_ptr = (int8_t *) (sa->area + pos);
*n_ptr+=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_inc16(int id, uint64_t pos, int16_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 2 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int16_t *n_ptr = (int16_t *) (sa->area + pos);
*n_ptr+=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_inc32(int id, uint64_t pos, int32_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 4 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int32_t *n_ptr = (int32_t *) (sa->area + pos);
*n_ptr+=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_inc64(int id, uint64_t pos, int64_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 4 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int64_t *n_ptr = (int64_t *) (sa->area + pos);
*n_ptr+=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_dec8(int id, uint64_t pos, int8_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 1 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int8_t *n_ptr = (int8_t *) (sa->area + pos);
*n_ptr-=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_dec16(int id, uint64_t pos, int16_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 2 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int16_t *n_ptr = (int16_t *) (sa->area + pos);
*n_ptr-=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_dec32(int id, uint64_t pos, int32_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 4 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int32_t *n_ptr = (int32_t *) (sa->area + pos);
*n_ptr-=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
int uwsgi_sharedarea_dec64(int id, uint64_t pos, int64_t amount) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (pos + 4 > sa->max_pos + 1) return -1;
uwsgi_wlock(sa->lock);
int64_t *n_ptr = (int64_t *) (sa->area + pos);
*n_ptr-=amount;
sa->updates++;
uwsgi_rwunlock(sa->lock);
return 0;
}
/*
returns:
0 -> on updates
-1 -> on error
-2 -> on timeout
*/
int uwsgi_sharedarea_wait(int id, int freq, int timeout) {
int waiting = 0;
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) return -1;
if (!freq) freq = 100;
uwsgi_rlock(sa->lock);
uint64_t updates = sa->updates;
uwsgi_rwunlock(sa->lock);
while(timeout == 0 || (timeout > 0 && (waiting/1000) >= timeout)) {
uwsgi.wait_milliseconds_hook(freq);
waiting += freq;
// lock sa
uwsgi_rlock(sa->lock);
if (sa->updates != updates) {
uwsgi_rwunlock(sa->lock);
return 0;
}
// unlock sa
uwsgi_rwunlock(sa->lock);
}
return -2;
}
int uwsgi_sharedarea_new_id() {
int id = uwsgi.sharedareas_cnt;
uwsgi.sharedareas_cnt++;
if (!uwsgi.sharedareas) {
uwsgi.sharedareas = uwsgi_malloc(sizeof(struct uwsgi_sharedarea *));
}
else {
struct uwsgi_sharedarea **usa = realloc(uwsgi.sharedareas, ((sizeof(struct uwsgi_sharedarea *)) * uwsgi.sharedareas_cnt));
if (!usa) {
uwsgi_error("uwsgi_sharedarea_init()/realloc()");
exit(1);
}
uwsgi.sharedareas = usa;
}
return id;
}
static struct uwsgi_sharedarea *announce_sa(struct uwsgi_sharedarea *sa) {
uwsgi_log("sharedarea %d created at %p (%d pages, area at %p)\n", sa->id, sa, sa->pages, sa->area);
return sa;
}
struct uwsgi_sharedarea *uwsgi_sharedarea_init(int pages) {
int id = uwsgi_sharedarea_new_id();
uwsgi.sharedareas[id] = uwsgi_calloc_shared(uwsgi.page_size * (pages + 1));
uwsgi.sharedareas[id]->area = ((char *) uwsgi.sharedareas[id]) + uwsgi.page_size;
uwsgi.sharedareas[id]->id = id;
uwsgi.sharedareas[id]->fd = -1;
uwsgi.sharedareas[id]->pages = pages;
uwsgi.sharedareas[id]->max_pos = (uwsgi.page_size * pages) -1;
char *id_str = uwsgi_num2str(id);
uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
free(id_str);
return announce_sa(uwsgi.sharedareas[id]);
}
struct uwsgi_sharedarea *uwsgi_sharedarea_init_ptr(char *area, uint64_t len) {
int id = uwsgi_sharedarea_new_id();
uwsgi.sharedareas[id] = uwsgi_calloc_shared(sizeof(struct uwsgi_sharedarea));
uwsgi.sharedareas[id]->area = area;
uwsgi.sharedareas[id]->id = id;
uwsgi.sharedareas[id]->fd = -1;
uwsgi.sharedareas[id]->pages = len / uwsgi.page_size;
if (len % uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
uwsgi.sharedareas[id]->max_pos = len-1;
char *id_str = uwsgi_num2str(id);
uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
free(id_str);
return announce_sa(uwsgi.sharedareas[id]);
}
struct uwsgi_sharedarea *uwsgi_sharedarea_init_keyval(char *arg) {
char *s_pages = NULL;
char *s_file = NULL;
char *s_fd = NULL;
char *s_ptr = NULL;
char *s_size = NULL;
if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=',
"pages", &s_pages,
"file", &s_file,
"fd", &s_fd,
"ptr", &s_ptr,
"size", &s_size,
NULL)) {
uwsgi_log("invalid sharedarea keyval syntax\n");
exit(1);
}
uint64_t len = 0;
int pages = 0;
if (s_size) {
len = uwsgi_n64(s_size);
pages = len / uwsgi.page_size;
if (len % uwsgi.page_size != 0) pages++;
}
if (s_pages) {
pages = atoi(s_pages);
}
char *area = NULL;
struct uwsgi_sharedarea *sa = NULL;
if (s_file) {
}
else if (s_fd) {
}
else if (s_ptr) {
}
if (pages) {
if (!area) {
sa = uwsgi_sharedarea_init(pages);
}
else {
uwsgi_sharedarea_init_ptr(area, len);
}
}
if (s_pages) free(s_pages);
if (s_file) free(s_file);
if (s_fd) free(s_fd);
if (s_ptr) free(s_ptr);
if (s_size) free(s_size);
return sa;
}
void uwsgi_sharedareas_init() {
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, uwsgi.sharedareas_list) {
char *is_keyval = strchr(usl->value, '=');
if (!is_keyval) {
uwsgi_sharedarea_init(atoi(usl->value));
}
else {
uwsgi_sharedarea_init_keyval(usl->value);
}
}
}
-2
View File
@@ -301,10 +301,8 @@ int uwsgi_signal_send(int fd, uint8_t sig) {
else {
uwsgi_error("uwsgi_signal_send()");
}
uwsgi.shared->unrouted_signals++;
return -1;
}
uwsgi.shared->routed_signals++;
return 0;
}
+14 -55
View File
@@ -23,7 +23,6 @@ static uint64_t get_uwsgi_custom_snmp_value(uint64_t, uint8_t *);
static uint8_t snmp_int_to_snmp(uint64_t, uint8_t, uint8_t *);
static ssize_t build_snmp_response(uint8_t, uint8_t, uint8_t *, int, uint8_t *, uint8_t *, uint8_t *);
static ssize_t build_snmp_metric_response(int64_t, uint8_t, uint8_t *, int, uint8_t *, uint8_t *, uint8_t *);
void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_addr) {
@@ -72,7 +71,7 @@ void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_
uwsgi_debug("SNMP version: %d\n", version);
#endif
// check for community string (this must be set from the api using uwsgi.snmp_community or with --snmp-community arg)
// check for community string (this must be set from the python vm using uwsgi.snmp_community or with --snmp-community arg)
if (*ptr != SNMP_STRING)
return;
ptr++;
@@ -197,7 +196,7 @@ void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_
ptr++;
oidlen = *ptr;
if (oidlen < 11)
if (oidlen != 11)
return;
ptr++;
@@ -209,33 +208,21 @@ void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_
oid_part[0] = *ptr;
// old-style SNMP metrics
if (oid_part[0] == 1 || oid_part[0] == 2) {
ptr++;
if (oid_part[0] != 1 && oid_part[0] != 2)
return;
ptr++;
oid_part[1] = *ptr;
if (oid_part[1] < 1 || oid_part[1] > 100)
return;
ptr++;
oid_part[1] = *ptr;
if (oid_part[1] < 1 || oid_part[1] > 100)
return;
ptr++;
// check for null
if (memcmp((char *) ptr, "\x05\x00", 2))
return;
ptr += 2;
size = build_snmp_response(oid_part[0], oid_part[1], buffer, size, seq1, seq2, seq3);
}
// metrics subsystem
else {
size_t metric_asn_len = oidlen - 9;
char *metric_asn = (char *) ptr;
struct uwsgi_metric *um = uwsgi_metric_find_by_asn(metric_asn, metric_asn_len);
if (!um) return;
uwsgi_rlock(uwsgi.metrics_lock);
int64_t value = *um->value;
uwsgi_rwunlock(uwsgi.metrics_lock);
size = build_snmp_metric_response(value, um->type, buffer, size, seq1, seq2, seq3);
}
// check for null
if (memcmp((char *) ptr, "\x05\x00", 2))
return;
ptr += 2;
size = build_snmp_response(oid_part[0], oid_part[1], buffer, size, seq1, seq2, seq3);
if (size > 0) {
if (sendto(fd, buffer, size, 0, (struct sockaddr *) client_addr, sizeof(struct sockaddr_in)) < 0) {
@@ -305,7 +292,6 @@ static uint8_t snmp_int_to_snmp(uint64_t snmp_val, uint8_t oid_type, uint8_t * b
uint8_t tlen;
int i, j;
uint8_t *ptr = (uint8_t *) & snmp_val;
int32_t val32 = (int32_t) snmp_val;
// check for counter, counter64 or gauge
@@ -317,7 +303,6 @@ static uint8_t snmp_int_to_snmp(uint64_t snmp_val, uint8_t oid_type, uint8_t * b
}
else {
tlen = 4;
ptr = (uint8_t *) &val32;
}
buffer[0] = tlen;
@@ -367,32 +352,6 @@ static ssize_t build_snmp_response(uint8_t oid1, uint8_t oid2, uint8_t * buffer,
}
static ssize_t build_snmp_metric_response(int64_t value, uint8_t type, uint8_t * buffer, int size, uint8_t * seq1, uint8_t * seq2, uint8_t * seq3) {
uint8_t oid_sz;
if (type == UWSGI_METRIC_GAUGE) {
buffer[size - 2] = SNMP_GAUGE;
oid_sz = snmp_int_to_snmp(value, SNMP_GAUGE, buffer + (size - 1));
}
else {
buffer[size - 2] = SNMP_COUNTER64;
oid_sz = snmp_int_to_snmp(value, SNMP_COUNTER64, buffer + (size - 1));
}
if (oid_sz < 1)
return -1;
oid_sz--;
buffer[1] += oid_sz;
*seq1 += oid_sz;
*seq2 += oid_sz;
*seq3 += oid_sz;
return size + oid_sz;
}
void uwsgi_opt_snmp(char *opt, char *value, void *foobar) {
uwsgi.snmp = 1;
if (value) {
+104 -59
View File
@@ -6,22 +6,6 @@ static int connect_to_unix(char *, int, int);
static int connect_to_tcp(char *, int, int, int);
static int connect_to_udp(char *, int);
void uwsgi_socket_setup_protocol(struct uwsgi_socket *uwsgi_sock, char *protocol) {
if (!protocol) protocol = "uwsgi";
struct uwsgi_protocol *up = uwsgi.protocols;
while(up) {
if (!strcmp(protocol, up->name)) {
up->func(uwsgi_sock);
return;
}
up = up->next;
}
uwsgi_log("unable to find protocol %s\n", protocol);
exit(1);
}
static int uwsgi_socket_strcmp(char *sock1, char *sock2) {
size_t sock1_len = strlen(sock1);
size_t sock2_len = strlen(sock2);
@@ -1382,7 +1366,7 @@ void uwsgi_add_sockets_to_queue(int queue, int async_id) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->fd_threads && async_id > -1 && uwsgi_sock->fd_threads[async_id] > -1) {
if (uwsgi_sock->fd_threads && async_id > -1) {
event_queue_add_fd_read(queue, uwsgi_sock->fd_threads[async_id]);
}
else if (uwsgi_sock->fd > -1) {
@@ -1869,8 +1853,109 @@ void uwsgi_set_sockets_protocols() {
setup_proto:
if (!requested_protocol) requested_protocol = uwsgi.protocol;
uwsgi_socket_setup_protocol(uwsgi_sock, requested_protocol);
if (!requested_protocol) {
requested_protocol = uwsgi.protocol;
}
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_prepare_headers = uwsgi_proto_base_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body;
uwsgi_sock->proto_write = uwsgi_proto_base_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
if (uwsgi.offload_threads > 0)
uwsgi_sock->can_offload = 1;
}
else if (requested_protocol && !strcmp("raw", requested_protocol)) {
uwsgi_sock->proto = uwsgi_proto_raw_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body;
uwsgi_sock->proto_write = uwsgi_proto_base_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
if (uwsgi.offload_threads > 0)
uwsgi_sock->can_offload = 1;
}
else if (requested_protocol && (!strcmp("fastcgi", requested_protocol) || !strcmp("fcgi", requested_protocol))) {
uwsgi_sock->proto = uwsgi_proto_fastcgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_cgi_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_fastcgi_read_body;
uwsgi_sock->proto_write = uwsgi_proto_fastcgi_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_fastcgi_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_fastcgi_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_fastcgi_close;
}
else if (requested_protocol && (!strcmp("fastcgi-nph", requested_protocol) || !strcmp("fcgi-nph", requested_protocol))) {
uwsgi_sock->proto = uwsgi_proto_fastcgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_fastcgi_read_body;
uwsgi_sock->proto_write = uwsgi_proto_fastcgi_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_fastcgi_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_fastcgi_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_fastcgi_close;
}
else if (requested_protocol && (!strcmp("scgi", requested_protocol) || !strcmp("scgi", requested_protocol))) {
uwsgi_sock->proto = uwsgi_proto_scgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_cgi_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body;
uwsgi_sock->proto_write = uwsgi_proto_base_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
}
else if (requested_protocol && (!strcmp("scgi-nph", requested_protocol) || !strcmp("scgi-nph", requested_protocol))) {
uwsgi_sock->proto = uwsgi_proto_scgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body;
uwsgi_sock->proto_write = uwsgi_proto_base_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
}
#ifdef UWSGI_ZEROMQ
else if (requested_protocol && !strcmp("zmq", requested_protocol)) {
uwsgi.zeromq = 1;
}
#endif
else {
uwsgi_sock->proto = uwsgi_proto_uwsgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body;
uwsgi_sock->proto_write = uwsgi_proto_base_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_base_close;
if (uwsgi.offload_threads > 0)
uwsgi_sock->can_offload = 1;
}
nextsock:
uwsgi_sock = uwsgi_sock->next;
}
@@ -1906,43 +1991,3 @@ int uwsgi_accept(int server_fd) {
}
struct uwsgi_protocol *uwsgi_register_protocol(char *name, void (*func)(struct uwsgi_socket *)) {
struct uwsgi_protocol *old_up = NULL, *up = uwsgi.protocols;
while(up) {
if (!strcmp(name, up->name)) {
goto found;
}
old_up = up;
up = up->next;
}
up = uwsgi_calloc(sizeof(struct uwsgi_protocol));
up->name = name;
if (old_up) {
old_up->next = up;
}
else {
uwsgi.protocols = up;
}
found:
up->func = func;
return up;
}
void uwsgi_protocols_register() {
uwsgi_register_protocol("uwsgi", uwsgi_proto_uwsgi_setup);
uwsgi_register_protocol("puwsgi", uwsgi_proto_puwsgi_setup);
uwsgi_register_protocol("http", uwsgi_proto_http_setup);
#ifdef UWSGI_SSL
uwsgi_register_protocol("suwsgi", uwsgi_proto_suwsgi_setup);
uwsgi_register_protocol("https", uwsgi_proto_https_setup);
#endif
uwsgi_register_protocol("fastcgi", uwsgi_proto_fastcgi_setup);
uwsgi_register_protocol("fastcgi-nph", uwsgi_proto_fastcgi_nph_setup);
uwsgi_register_protocol("scgi", uwsgi_proto_scgi_setup);
uwsgi_register_protocol("scgi-nph", uwsgi_proto_scgi_nph_setup);
uwsgi_register_protocol("raw", uwsgi_proto_raw_setup);
}
+45 -18
View File
@@ -440,11 +440,6 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
void *events = event_queue_alloc(1);
for (;;) {
int nevents = event_queue_wait_multi(ut->queue, 1, events, 1);
if (nevents < 0) {
if (errno == EINTR) continue;
uwsgi_log_verbose("ending the stats pusher thread...\n");
return;
}
if (nevents > 0) {
int interesting_fd = event_queue_interesting_fd(events, 0);
char buf[4096];
@@ -462,8 +457,7 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
struct uwsgi_stats *us = NULL;
while (uspi) {
int delta = uspi->freq ? uspi->freq : uwsgi.stats_pusher_default_freq;
if (((uspi->last_run + delta) <= now) || (uspi->needs_retry && (uspi->next_retry <= now))) {
if (uspi->needs_retry) uspi->retries++;
if ((uspi->last_run + delta) <= now) {
if (uspi->raw) {
uspi->pusher->func(uspi, now, NULL, 0);
}
@@ -476,17 +470,6 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
uspi->pusher->func(uspi, now, us->base, us->pos);
}
uspi->last_run = now;
if (uspi->needs_retry && uspi->max_retries > 0 && uspi->retries < uspi->max_retries) {
uwsgi_log("[uwsgi-stats-pusher] %s failed (%d), retry in %ds\n", uspi->pusher->name, uspi->retries, uspi->retry_delay);
uspi->next_retry = now + uspi->retry_delay;
} else if (uspi->needs_retry && uspi->retries >= uspi->max_retries) {
uwsgi_log("[uwsgi-stats-pusher] %s failed and maximum number of retries was reached (%d)\n", uspi->pusher->name, uspi->retries);
uspi->needs_retry = 0;
uspi->retries = 0;
} else if (uspi->retries) {
uwsgi_log("[uwsgi-stats-pusher] retry succeeded for %s\n", uspi->pusher->name);
uspi->retries = 0;
}
}
next:
uspi = uspi->next;
@@ -548,6 +531,50 @@ struct uwsgi_stats_pusher *uwsgi_register_stats_pusher(char *name, void (*func)
return pusher;
}
struct uwsgi_stats_pusher_file_conf {
char *path;
char *freq;
char *separator;
};
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
struct uwsgi_stats_pusher_file_conf *uspic = (struct uwsgi_stats_pusher_file_conf *) uspi->data;
if (!uspi->configured) {
uspic = uwsgi_calloc(sizeof(struct uwsgi_stats_pusher_file_conf));
if (uspi->arg) {
if (uwsgi_kvlist_parse(uspi->arg, strlen(uspi->arg), ',', '=', "path", &uspic->path, "separator", &uspic->separator, "freq", &uspic->freq, NULL)) {
free(uspi);
return;
}
}
if (!uspic->path)
uspic->path = "uwsgi.stats";
if (!uspic->separator)
uspic->separator = "\n\n";
if (uspic->freq)
uspi->freq = atoi(uspic->freq);
uspi->configured = 1;
uspi->data = uspic;
}
int fd = open(uspic->path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
if (fd < 0) {
uwsgi_error_open(uspic->path);
return;
}
ssize_t rlen = write(fd, json, json_len);
if (rlen != (ssize_t) json_len) {
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
}
rlen = write(fd, uspic->separator, strlen(uspic->separator));
if (rlen != (ssize_t) strlen(uspic->separator)) {
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
}
close(fd);
}
static void stats_dump_var(char *k, uint16_t kl, char *v, uint16_t vl, void *data) {
struct uwsgi_stats *us = (struct uwsgi_stats *) data;
if (us->dirty) return;
-2
View File
@@ -812,8 +812,6 @@ end:
}
void uwsgi_subscribe_all(uint8_t cmd, int verbose) {
if (!uwsgi.subscriptions_blocked) return;
// -- subscribe
struct uwsgi_string_list *subscriptions = uwsgi.subscriptions;
while (subscriptions) {
+116 -221
View File
@@ -2,6 +2,7 @@
extern struct uwsgi_server uwsgi;
extern char **environ;
#ifdef __BIG_ENDIAN__
uint16_t uwsgi_swap16(uint16_t x) {
@@ -206,19 +207,17 @@ void uwsgi_set_cgroup() {
if (!uwsgi.cgroup)
return;
if (getuid()) return;
usl = uwsgi.cgroup;
while (usl) {
int mode = strtol(uwsgi.cgroup_dir_mode, 0, 8);
if (mkdir(usl->value, mode)) {
if (errno != EEXIST) {
uwsgi_error("uwsgi_set_cgroup()/mkdir()");
uwsgi_error("mkdir()");
exit(1);
}
if (chmod(usl->value, mode)) {
uwsgi_error("uwsgi_set_cgroup()/chmod()");
uwsgi_error("chmod()");
exit(1);
}
uwsgi_log("using Linux cgroup %s with mode %o\n", usl->value, mode);
@@ -726,7 +725,7 @@ void uwsgi_as_root() {
uwsgi_foreach(usl, uwsgi.call_as_root) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
}
}
@@ -944,7 +943,7 @@ void uwsgi_as_root() {
uwsgi_foreach(usl, uwsgi.call_as_user) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
exit(1);
}
}
@@ -1038,7 +1037,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
uwsgi.workers[uwsgi.mywid].requests++;
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].requests++;
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].write_errors += wsgi_req->write_errors;
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].read_errors += wsgi_req->read_errors;
// this is used for MAX_REQUESTS
uwsgi.workers[uwsgi.mywid].delta_requests++;
}
@@ -1074,13 +1072,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
if (!wsgi_req->is_raw && uwsgi.p[wsgi_req->uh->modifier1]->after_request)
uwsgi.p[wsgi_req->uh->modifier1]->after_request(wsgi_req);
// after_request custom hooks
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, uwsgi.after_request_hooks) {
void (*func)(struct wsgi_request *) = (void (*)(struct wsgi_request *)) usl->custom_ptr;
func(wsgi_req);
}
if (uwsgi.threads > 1) {
// now the thread can die...
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &tmp_id);
@@ -1145,9 +1136,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
if (wsgi_req->websocket_buf) {
uwsgi_buffer_destroy(wsgi_req->websocket_buf);
}
if (wsgi_req->websocket_send_buf) {
uwsgi_buffer_destroy(wsgi_req->websocket_send_buf);
}
// reset request
@@ -1173,7 +1161,7 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
}
// after the first request, if i am a vassal, signal Emperor about my loyalty
// ready to accept request, if i am a vassal signal Emperor about my loyalty
if (uwsgi.has_emperor && !uwsgi.loyal) {
uwsgi_log("announcing my loyalty to the Emperor...\n");
char byte = 17;
@@ -1233,7 +1221,7 @@ void uwsgi_linux_ksm_map(void) {
}
// we now have areas
if (uwsgi.ksm_mappings_last_size == 0 || uwsgi.ksm_mappings_current_size != uwsgi.ksm_mappings_last_size) {
if (uwsgi.ksm_mappings_last_size == 0 || uwsgi.ksm_mappings_current_size == 0 || uwsgi.ksm_mappings_current_size != uwsgi.ksm_mappings_last_size) {
dirty = 1;
}
else {
@@ -1301,7 +1289,7 @@ long uwsgi_num_from_file(char *filename, int quiet) {
// setup for a new request
void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_socket *uwsgi_sock) {
wsgi_req->app_id = -1;
wsgi_req->app_id = uwsgi.default_app;
wsgi_req->async_id = async_id;
wsgi_req->sendfile_fd = -1;
@@ -1561,14 +1549,14 @@ void parse_sys_envs(char **envs) {
while (*uenvs) {
if (!strncmp(*uenvs, "UWSGI_", 6) &&
strncmp(*uenvs, "UWSGI_RELOADS=", 14) &&
strncmp(*uenvs, "UWSGI_VASSALS_DIR=", 18) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD=", 17) &&
strncmp(*uenvs, "UWSGI_BROODLORD_NUM=", 20) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD_CONFIG=", 24) &&
strncmp(*uenvs, "UWSGI_EMPEROR_PROXY=", 20) &&
strncmp(*uenvs, "UWSGI_JAIL_PID=", 15) &&
strncmp(*uenvs, "UWSGI_ORIGINAL_PROC_NAME=", 25)) {
strncmp(*uenvs, "UWSGI_RELOADS=", 14) &&
strncmp(*uenvs, "UWSGI_VASSALS_DIR=", 18) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD=", 17) &&
strncmp(*uenvs, "UWSGI_BROODLORD_NUM=", 20) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD_CONFIG=", 24) &&
strncmp(*uenvs, "UWSGI_EMPEROR_PROXY=", 20) &&
strncmp(*uenvs, "UWSGI_JAIL_PID=", 15) &&
strncmp(*uenvs, "UWSGI_ORIGINAL_PROC_NAME=", 25)) {
earg = uwsgi_malloc(strlen(*uenvs + 6) + 1);
env_to_arg(*uenvs + 6, earg);
eq_pos = strchr(earg, '=');
@@ -1912,6 +1900,33 @@ void uwsgi_unix_signal(int signum, void (*func) (int)) {
}
}
char *uwsgi_get_exported_opt(char *key) {
int i;
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
if (!strcmp(uwsgi.exported_opts[i]->key, key)) {
return uwsgi.exported_opts[i]->value;
}
}
return NULL;
}
char *uwsgi_get_optname_by_index(int index) {
struct uwsgi_option *op = uwsgi.options;
while (op->name) {
if (op->shortcut == index) {
return op->name;
}
op++;
}
return NULL;
}
int uwsgi_list_has_num(char *list, int num) {
char *list2 = uwsgi_concat2(list, "");
@@ -3151,169 +3166,45 @@ void escape_json(char *src, size_t len, char *dst) {
*ptr++ = 0;
}
/*
build PATH_INFO from raw_uri
it manages:
percent encoding
dot_segments removal
stop at the first #
*/
void http_url_decode(char *buf, uint16_t * len, char *dst) {
enum {
zero = 0,
percent1,
percent2,
slash,
dot,
dotdot
} status;
uint16_t i, current_new_len, new_len = 0;
uint16_t i;
int percent = 0;
char value[2];
size_t new_len = 0;
char *ptr = dst;
value[0] = '0';
value[1] = '0';
status = zero;
int no_slash = 0;
if (*len > 0 && buf[0] != '/') {
status = slash;
no_slash = 1;
}
for (i = 0; i < *len; i++) {
char c = buf[i];
if (c == '#') break;
switch(status) {
case zero:
if (c == '%') {
status = percent1;
break;
}
if (c == '/') {
status = slash;
break;
}
*ptr++ = c;
new_len++;
break;
case percent1:
if (c == '%') {
*ptr++ = '%';
new_len++;
status = zero;
break;
}
value[0] = c;
status = percent2;
break;
case percent2:
value[1] = c;
*ptr++ = hex2num(value);
new_len++;
status = zero;
break;
case slash:
if (c == '.') {
status = dot;
break;
}
// we could be at the first round (in non slash)
if (i > 0 || !no_slash) {
*ptr++ = '/'; new_len++;
}
if (c == '%') {
status = percent1;
break;
}
if (c == '/') {
status = slash;
break;
}
*ptr++ = c; new_len++;
status = zero;
break;
case dot:
if (c == '.') {
status = dotdot;
break;
}
if (c == '/') {
status = slash;
break;
}
if (i > 1) {
*ptr++ = '/'; new_len++;
}
*ptr++ = '.'; new_len++;
if (c == '%') {
status = percent1;
break;
}
*ptr++ = c; new_len++;
status = zero;
break;
case dotdot:
// here we need to remove a segment
if (c == '/') {
current_new_len = new_len;
while(current_new_len) {
current_new_len--;
ptr--;
if (dst[current_new_len] == '/') {
break;
}
}
new_len = current_new_len;
status = slash;
break;
}
if (i > 2) {
*ptr++ = '/'; new_len++;
}
*ptr++ = '.'; new_len++;
*ptr++ = '.'; new_len++;
if (c == '%') {
status = percent1;
break;
}
*ptr++ = c; new_len++;
status = zero;
break;
// over engineering
default:
*ptr++ = c;
new_len++;
break;
}
}
switch(status) {
case slash:
case dot:
*ptr++ = '/'; new_len++;
break;
case dotdot:
current_new_len = new_len;
while(current_new_len) {
if (dst[current_new_len-1] == '/') {
break;
}
current_new_len--;
if (buf[i] == '%') {
if (percent == 0) {
percent = 1;
}
new_len = current_new_len;
break;
default:
break;
else {
*ptr++ = '%';
new_len++;
percent = 0;
}
}
else {
if (percent == 1) {
value[0] = buf[i];
percent = 2;
}
else if (percent == 2) {
value[1] = buf[i];
*ptr++ = hex2num(value);
percent = 0;
new_len++;
}
else {
*ptr++ = buf[i];
new_len++;
}
}
}
*len = new_len;
@@ -3364,10 +3255,8 @@ struct uwsgi_app *uwsgi_add_app(int id, uint8_t modifier1, char *mountpoint, int
}
}
if (!uwsgi.no_default_app) {
if ((mountpoint_len == 0 || (mountpoint_len = -1 && mountpoint[0] == '/')) && uwsgi.default_app == -1) {
uwsgi.default_app = id;
}
if ((mountpoint_len == 0 || (mountpoint_len = -1 && mountpoint[0] == '/')) && uwsgi.default_app == -1) {
uwsgi.default_app = id;
}
return wi;
@@ -3529,11 +3418,7 @@ int uwsgi_write_intfile(char *filename, int n) {
uwsgi_error_open(filename);
exit(1);
}
if (fprintf(pidfile, "%d\n", n) <= 0 || ferror(pidfile)) {
fclose(pidfile);
return -1;
}
if (fclose(pidfile)) {
if (fprintf(pidfile, "%d\n", n) <= 0 || ferror(pidfile) || fclose(pidfile)) {
return -1;
}
return 0;
@@ -3765,6 +3650,26 @@ error:
return NULL;
}
// evaluate a math expression
#ifdef UWSGI_MATHEVAL
double uwsgi_matheval(char *expr) {
#ifdef UWSGI_DEBUG
uwsgi_log("matheval expr = %s\n", expr);
#endif
double ret = 0.0;
void *e = evaluator_create(expr);
if (!e)
return ret;
ret = evaluator_evaluate(e, 0, NULL, NULL);
evaluator_destroy(e);
return ret;
}
char *uwsgi_matheval_str(char *expr) {
double ret = uwsgi_matheval(expr);
return uwsgi_num2str((int) ret);
}
#endif
int uwsgi_kvlist_parse(char *src, size_t len, char list_separator, char kv_separator, ...) {
size_t i;
va_list ap;
@@ -3933,27 +3838,32 @@ char *uwsgi_strip(char *src) {
void uwsgi_uuid(char *buf) {
#ifdef UWSGI_UUID
uuid_t uuid_value;
uuid_generate(uuid_value);
uuid_unparse(uuid_value, buf);
uuid_t uuid_zmq;
uuid_generate(uuid_zmq);
uuid_unparse(uuid_zmq, buf);
#else
int i,r[11];
if (!uwsgi_file_exists("/dev/urandom")) goto fallback;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) goto fallback;
for(i=0;i<11;i++) {
if (read(fd, &r[i], 4) != 4) {
close(fd); goto fallback;
}
}
close(fd);
goto done;
static int srand_called = 0;
if (!uwsgi_file_exists("/dev/urandom")) goto fallback;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) goto fallback;
for(i=0;i<11;i++) {
if (read(fd, &r[i], 4) != 4) {
close(fd); goto fallback;
}
}
close(fd);
goto done;
fallback:
for(i=0;i<11;i++) {
r[i] = rand();
}
if (!srand_called) {
srand((unsigned int) getpid());
srand_called = 1;
}
for(i=0;i<11;i++) {
r[i] = rand();
}
done:
snprintf(buf, 37, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10]);
snprintf(buf, 37, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10]);
#endif
}
@@ -4317,7 +4227,6 @@ void uwsgi_envdir(char *edir) {
free(content);
}
closedir(d);
}
void uwsgi_envdirs(struct uwsgi_string_list *envdirs) {
@@ -4337,17 +4246,3 @@ void uwsgi_exit(int status) {
// disable macro expansion
(exit) (status);
}
int uwsgi_base128(struct uwsgi_buffer *ub, uint64_t l, int first) {
if( l > 127 ) {
if (uwsgi_base128(ub, l/128, 0)) return -1;
}
l %= 128;
if(first) {
if (uwsgi_buffer_u8(ub, (uint8_t) l)) return -1;
}
else {
if (uwsgi_buffer_u8(ub, 0x80 | (uint8_t) l)) return -1;
}
return 0;
}
+142 -243
View File
@@ -38,21 +38,11 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS;
static struct uwsgi_option uwsgi_base_options[] = {
{"socket", required_argument, 's', "bind to the specified UNIX/TCP socket using default protocol", uwsgi_opt_add_socket, NULL, 0},
{"uwsgi-socket", required_argument, 's', "bind to the specified UNIX/TCP socket using uwsgi protocol", uwsgi_opt_add_socket, "uwsgi", 0},
#ifdef UWSGI_SSL
{"suwsgi-socket", required_argument, 's', "bind to the specified UNIX/TCP socket using uwsgi protocol over SSL", uwsgi_opt_add_ssl_socket, "suwsgi", 0},
{"ssl-socket", required_argument, 's', "bind to the specified UNIX/TCP socket using uwsgi protocol over SSL", uwsgi_opt_add_ssl_socket, "suwsgi", 0},
#endif
{"http-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using HTTP protocol", uwsgi_opt_add_socket, "http", 0},
{"http-socket-modifier1", required_argument, 0, "force the specified modifier1 when using HTTP protocol", uwsgi_opt_set_64bit, &uwsgi.http_modifier1, 0},
{"http-socket-modifier2", required_argument, 0, "force the specified modifier2 when using HTTP protocol", uwsgi_opt_set_64bit, &uwsgi.http_modifier2, 0},
#ifdef UWSGI_SSL
{"https-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using HTTPS protocol", uwsgi_opt_add_ssl_socket, "https", 0},
{"https-socket-modifier1", required_argument, 0, "force the specified modifier1 when using HTTPS protocol", uwsgi_opt_set_64bit, &uwsgi.https_modifier1, 0},
{"https-socket-modifier2", required_argument, 0, "force the specified modifier2 when using HTTPS protocol", uwsgi_opt_set_64bit, &uwsgi.https_modifier2, 0},
#endif
{"fastcgi-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using FastCGI protocol", uwsgi_opt_add_socket, "fastcgi", 0},
{"fastcgi-nph-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using FastCGI protocol (nph mode)", uwsgi_opt_add_socket, "fastcgi-nph", 0},
{"fastcgi-modifier1", required_argument, 0, "force the specified modifier1 when using FastCGI protocol", uwsgi_opt_set_64bit, &uwsgi.fastcgi_modifier1, 0},
@@ -67,8 +57,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"raw-modifier1", required_argument, 0, "force the specified modifier1 when using RAW protocol", uwsgi_opt_set_64bit, &uwsgi.raw_modifier1, 0},
{"raw-modifier2", required_argument, 0, "force the specified modifier2 when using RAW protocol", uwsgi_opt_set_64bit, &uwsgi.raw_modifier2, 0},
{"puwsgi-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using persistent uwsgi protocol (puwsgi)", uwsgi_opt_add_socket, "puwsgi", 0},
{"protocol", required_argument, 0, "force the specified protocol for default sockets", uwsgi_opt_set_str, &uwsgi.protocol, 0},
{"socket-protocol", required_argument, 0, "force the specified protocol for default sockets", uwsgi_opt_set_str, &uwsgi.protocol, 0},
{"shared-socket", required_argument, 0, "create a shared sacket for advanced jailing or ipc", uwsgi_opt_add_shared_socket, NULL, 0},
@@ -232,16 +220,13 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"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},
{"vassal-sos-backlog", required_argument, 0, "ask emperor for sos if backlog queue has more items than the value specified", uwsgi_opt_set_int, &uwsgi.vassal_sos_backlog, 0},
{"vassals-set", required_argument, 0, "automatically set the specified option (via --set) for every vassal", uwsgi_opt_add_string_list, &uwsgi.vassals_set, 0},
{"vassal-set", required_argument, 0, "automatically set the specified option (via --set) for every vassal", uwsgi_opt_add_string_list, &uwsgi.vassals_set, 0},
{"heartbeat", required_argument, 0, "announce healthiness to the emperor", uwsgi_opt_set_int, &uwsgi.heartbeat, 0},
{"heartbeat", required_argument, 0, "announce healtness to the emperor", uwsgi_opt_set_int, &uwsgi.heartbeat, 0},
{"auto-snapshot", optional_argument, 0, "automatically make workers snaphost after reload", uwsgi_opt_set_int, &uwsgi.auto_snapshot, UWSGI_OPT_LAZY},
{"reload-mercy", required_argument, 0, "set the maximum time (in seconds) we wait for workers and other processes to die during reload/shutdown", uwsgi_opt_set_int, &uwsgi.reload_mercy, 0},
{"worker-reload-mercy", required_argument, 0, "set the maximum time (in seconds) a worker can take to reload/shutdown (default is 60)", uwsgi_opt_set_int, &uwsgi.worker_reload_mercy, 0},
{"exit-on-reload", no_argument, 0, "force exit even if a reload is requested", uwsgi_opt_true, &uwsgi.exit_on_reload, 0},
{"die-on-term", no_argument, 0, "exit instead of brutal reload on SIGTERM", uwsgi_opt_true, &uwsgi.die_on_term, 0},
{"force-gateway", no_argument, 0, "force the spawn of the first registered gateway without a master", uwsgi_opt_true, &uwsgi.force_gateway, 0},
{"force-gateway", no_argument, 0, "force teh spawn of the first registered gateway without a master", uwsgi_opt_true, &uwsgi.force_gateway, 0},
{"help", no_argument, 'h', "show this help", uwsgi_help, NULL, UWSGI_OPT_IMMEDIATE},
{"usage", no_argument, 'h', "show this help", uwsgi_help, NULL, UWSGI_OPT_IMMEDIATE},
@@ -259,7 +244,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"lock-engine", required_argument, 0, "set the lock engine", uwsgi_opt_set_str, &uwsgi.lock_engine, 0},
{"ftok", required_argument, 0, "set the ipcsem key via ftok() for avoiding duplicates", uwsgi_opt_set_str, &uwsgi.ftok, 0},
{"persistent-ipcsem", no_argument, 0, "do not remove ipcsem's on shutdown", uwsgi_opt_true, &uwsgi.persistent_ipcsem, 0},
{"sharedarea", required_argument, 'A', "create a raw shared memory area of specified pages (note: it supports keyval too)", uwsgi_opt_add_string_list, &uwsgi.sharedareas_list, 0},
{"sharedarea", required_argument, 'A', "create a raw shared memory area of specified pages", uwsgi_opt_set_int, &uwsgi.sharedareasize, 0},
{"safe-fd", required_argument, 0, "do not close the specified file descriptor", uwsgi_opt_safe_fd, NULL, 0},
{"fd-safe", required_argument, 0, "do not close the specified file descriptor", uwsgi_opt_safe_fd, NULL, 0},
@@ -308,12 +293,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"signal-bufsize", required_argument, 0, "set buffer size for signal queue", uwsgi_opt_set_int, &uwsgi.signal_bufsize, 0},
{"signals-bufsize", required_argument, 0, "set buffer size for signal queue", uwsgi_opt_set_int, &uwsgi.signal_bufsize, 0},
{"signal-timer", required_argument, 0, "add a timer (syntax: <signal> <seconds>)", uwsgi_opt_add_string_list, &uwsgi.signal_timers, UWSGI_OPT_MASTER},
{"timer", required_argument, 0, "add a timer (syntax: <signal> <seconds>)", uwsgi_opt_add_string_list, &uwsgi.signal_timers, UWSGI_OPT_MASTER},
{"signal-rbtimer", required_argument, 0, "add a redblack timer (syntax: <signal> <seconds>)", uwsgi_opt_add_string_list, &uwsgi.rb_signal_timers, UWSGI_OPT_MASTER},
{"rbtimer", required_argument, 0, "add a redblack timer (syntax: <signal> <seconds>)", uwsgi_opt_add_string_list, &uwsgi.rb_signal_timers, UWSGI_OPT_MASTER},
{"rpc-max", required_argument, 0, "maximum number of rpc slots (default: 64)", uwsgi_opt_set_64bit, &uwsgi.rpc_max, 0},
{"disable-logging", no_argument, 'L', "disable request logging", uwsgi_opt_dyn_false, (void *) UWSGI_OPTION_LOGGING, 0},
@@ -373,18 +352,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"hook-as-user-atexit", required_argument, 0, "run the specified hook before app exit and reload", uwsgi_opt_add_string_list, &uwsgi.hook_as_user_atexit, 0},
{"hook-pre-app", required_argument, 0, "run the specified hook before app loading", uwsgi_opt_add_string_list, &uwsgi.hook_pre_app, 0},
{"hook-post-app", required_argument, 0, "run the specified hook after app loading", uwsgi_opt_add_string_list, &uwsgi.hook_post_app, 0},
{"hook-accepting", required_argument, 0, "run the specified hook after each worker enter the accepting phase", uwsgi_opt_add_string_list, &uwsgi.hook_accepting, 0},
{"hook-accepting1", required_argument, 0, "run the specified hook after the first worker enters the accepting phase", uwsgi_opt_add_string_list, &uwsgi.hook_accepting1, 0},
{"hook-accepting-once", required_argument, 0, "run the specified hook after each worker enter the accepting phase (once per-instance)", uwsgi_opt_add_string_list, &uwsgi.hook_accepting_once, 0},
{"hook-accepting1-once", required_argument, 0, "run the specified hook after the first worker enters the accepting phase (once per instance)", uwsgi_opt_add_string_list, &uwsgi.hook_accepting1_once, 0},
{"hook-as-vassal", required_argument, 0, "run the specified hook before exec()ing the vassal", uwsgi_opt_add_string_list, &uwsgi.hook_as_vassal, 0},
{"hook-as-emperor", required_argument, 0, "run the specified hook in the emperor after the vassal has been started", uwsgi_opt_add_string_list, &uwsgi.hook_as_emperor, 0},
{"hook-as-mule", required_argument, 0, "run the specified hook in each mule", uwsgi_opt_add_string_list, &uwsgi.hook_as_mule, 0},
{"after-request-hook", required_argument, 0, "run the specified function/symbol after each request", uwsgi_opt_add_string_list, &uwsgi.after_request_hooks, 0},
{"after-request-call", required_argument, 0, "run the specified function/symbol after each request", uwsgi_opt_add_string_list, &uwsgi.after_request_hooks, 0},
{"hook-as-vassal", required_argument, 0, "run the specified command before exec()ing the vassal", uwsgi_opt_add_string_list, &uwsgi.hook_as_vassal, 0},
{"hook-as-emperor", required_argument, 0, "run the specified command in the emperor after the vassal has been started", uwsgi_opt_add_string_list, &uwsgi.hook_as_emperor, 0},
{"exec-asap", required_argument, 0, "run the specified command as soon as possible", uwsgi_opt_add_string_list, &uwsgi.exec_asap, 0},
{"exec-pre-jail", required_argument, 0, "run the specified command before jailing", uwsgi_opt_add_string_list, &uwsgi.exec_pre_jail, 0},
@@ -458,6 +428,12 @@ static struct uwsgi_option uwsgi_base_options[] = {
#ifdef UWSGI_JSON
{"json", required_argument, 'j', "load config from json file", uwsgi_opt_load_json, NULL, UWSGI_OPT_IMMEDIATE},
{"js", required_argument, 'j', "load config from json file", uwsgi_opt_load_json, NULL, UWSGI_OPT_IMMEDIATE},
#endif
#ifdef UWSGI_ZEROMQ
{"zeromq", required_argument, 0, "create a zeromq pub/sub pair", uwsgi_opt_add_lazy_socket, "zmq", 0},
{"zmq", required_argument, 0, "create a zeromq pub/sub pair", uwsgi_opt_add_lazy_socket, "zmq", 0},
{"zeromq-socket", required_argument, 0, "create a zeromq pub/sub pair", uwsgi_opt_add_lazy_socket, "zmq", 0},
{"zmq-socket", required_argument, 0, "create a zeromq pub/sub pair", uwsgi_opt_add_lazy_socket, "zmq", 0},
#endif
{"weight", required_argument, 0, "weight of the instance (used by clustering/lb/subscriptions)", uwsgi_opt_set_64bit, &uwsgi.weight, 0},
{"auto-weight", required_argument, 0, "set weight of the instance (used by clustering/lb/subscriptions) automatically", uwsgi_opt_true, &uwsgi.auto_weight, 0},
@@ -528,22 +504,13 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"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},
{"exception-handler", required_argument, 0, "add an exception handler", uwsgi_opt_add_string_list, &uwsgi.exception_handlers_instance, UWSGI_OPT_MASTER},
{"enable-metrics", no_argument, 0, "enable metrics subsystem", uwsgi_opt_true, &uwsgi.has_metrics, UWSGI_OPT_MASTER},
{"metric", required_argument, 0, "add a custom metric", uwsgi_opt_add_string_list, &uwsgi.additional_metrics, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-threshold", required_argument, 0, "add a metric threshold/alarm", uwsgi_opt_add_string_list, &uwsgi.metrics_threshold, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-alarm", required_argument, 0, "add a metric threshold/alarm", uwsgi_opt_add_string_list, &uwsgi.metrics_threshold, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metrics-dir", required_argument, 0, "export metrics as text files to the specified directory", uwsgi_opt_set_str, &uwsgi.metrics_dir, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metrics-dir-restore", no_argument, 0, "restore last value taken from the metrics dir", uwsgi_opt_true, &uwsgi.metrics_dir_restore, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-dir", required_argument, 0, "export metrics as text files to the specified directory", uwsgi_opt_set_str, &uwsgi.metrics_dir, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-dir-restore", no_argument, 0, "restore last value taken from the metrics dir", uwsgi_opt_true, &uwsgi.metrics_dir_restore, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"udp", required_argument, 0, "run the udp server on the specified address", uwsgi_opt_set_str, &uwsgi.udp_socket, UWSGI_OPT_MASTER},
{"stats", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER},
{"stats-server", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER},
{"stats-http", no_argument, 0, "prefix stats server json output with http headers", uwsgi_opt_true, &uwsgi.stats_http, UWSGI_OPT_MASTER},
{"stats-minified", no_argument, 0, "minify statistics json output", uwsgi_opt_true, &uwsgi.stats_minified, UWSGI_OPT_MASTER},
{"stats-min", no_argument, 0, "minify statistics json output", uwsgi_opt_true, &uwsgi.stats_minified, UWSGI_OPT_MASTER},
{"stats-push", required_argument, 0, "push the stats json to the specified destination", uwsgi_opt_add_string_list, &uwsgi.requested_stats_pushers, UWSGI_OPT_MASTER|UWSGI_OPT_METRICS},
{"stats-push", required_argument, 0, "push the stats json to the specified destination", uwsgi_opt_add_string_list, &uwsgi.requested_stats_pushers, UWSGI_OPT_MASTER},
{"stats-pusher-default-freq", required_argument, 0, "set the default frequency of stats pushers", uwsgi_opt_set_int, &uwsgi.stats_pusher_default_freq, UWSGI_OPT_MASTER},
{"stats-pushers-default-freq", required_argument, 0, "set the default frequency of stats pushers", uwsgi_opt_set_int, &uwsgi.stats_pusher_default_freq, UWSGI_OPT_MASTER},
{"multicast", required_argument, 0, "subscribe to specified multicast group", uwsgi_opt_set_str, &uwsgi.multicast_group, UWSGI_OPT_MASTER},
@@ -652,13 +619,16 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"alarm-list", no_argument, 0, "list enabled alarms", uwsgi_opt_true, &uwsgi.alarms_list, 0},
{"alarms-list", no_argument, 0, "list enabled alarms", uwsgi_opt_true, &uwsgi.alarms_list, 0},
{"alarm-msg-size", required_argument, 0, "set the max size of an alarm message (default 8192)", uwsgi_opt_set_64bit, &uwsgi.alarm_msg_size, 0},
#ifdef UWSGI_ZEROMQ
{"log-zeromq", required_argument, 0, "send logs to a zeromq server", uwsgi_opt_set_logger, "zeromq", UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
#endif
{"log-master", no_argument, 0, "delegate logging to master process", uwsgi_opt_true, &uwsgi.log_master, UWSGI_OPT_MASTER},
{"log-master-bufsize", required_argument, 0, "set the buffer size for the master logger. bigger log messages will be truncated", uwsgi_opt_set_64bit, &uwsgi.log_master_bufsize, 0},
{"log-master-stream", no_argument, 0, "create the master logpipe as SOCK_STREAM", uwsgi_opt_true, &uwsgi.log_master_stream, 0},
{"log-master-req-stream", no_argument, 0, "create the master requests logpipe as SOCK_STREAM", uwsgi_opt_true, &uwsgi.log_master_req_stream, 0},
{"log-reopen", no_argument, 0, "reopen log after reload", uwsgi_opt_true, &uwsgi.log_reopen, 0},
{"log-truncate", no_argument, 0, "truncate log on startup", uwsgi_opt_true, &uwsgi.log_truncate, 0},
{"log-maxsize", required_argument, 0, "set maximum logfile size", uwsgi_opt_set_64bit, &uwsgi.log_maxsize, UWSGI_OPT_LOG_MASTER},
{"log-maxsize", required_argument, 0, "set maximum logfile size", uwsgi_opt_set_int, &uwsgi.log_maxsize, UWSGI_OPT_LOG_MASTER},
{"log-backupname", required_argument, 0, "set logfile name after rotation", uwsgi_opt_set_str, &uwsgi.log_backupname, 0},
{"logdate", optional_argument, 0, "prefix logs with date or a strftime string", uwsgi_opt_log_date, NULL, 0},
@@ -671,7 +641,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"log-5xx", no_argument, 0, "log requests with a 5xx response", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_LOG_5xx, 0},
{"log-big", required_argument, 0, "log requestes bigger than the specified size", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_LOG_BIG, 0},
{"log-sendfile", required_argument, 0, "log sendfile requests", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_LOG_SENDFILE, 0},
{"log-ioerror", required_argument, 0, "log requests with io errors", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_LOG_IOERROR, 0},
{"log-micros", no_argument, 0, "report response time in microseconds instead of milliseconds", uwsgi_opt_true, &uwsgi.log_micros, 0},
{"log-x-forwarded-for", no_argument, 0, "use the ip from X-Forwarded-For header instead of REMOTE_ADDR", uwsgi_opt_true, &uwsgi.log_x_forwarded_for, 0},
{"master-as-root", no_argument, 0, "leave master process running as root", uwsgi_opt_true, &uwsgi.master_as_root, 0},
@@ -771,11 +740,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"routers-list", no_argument, 0, "list enabled routers", uwsgi_opt_true, &uwsgi.router_list, 0},
#endif
{"error-page-403", required_argument, 0, "add an error page (html) for managed 403 response", uwsgi_opt_add_string_list, &uwsgi.error_page_403, 0},
{"error-page-404", required_argument, 0, "add an error page (html) for managed 404 response", uwsgi_opt_add_string_list, &uwsgi.error_page_404, 0},
{"error-page-500", required_argument, 0, "add an error page (html) for managed 500 response", uwsgi_opt_add_string_list, &uwsgi.error_page_500, 0},
{"websockets-ping-freq", required_argument, 0, "set the frequency (in seconds) of websockets automatic ping packets", uwsgi_opt_set_int, &uwsgi.websockets_ping_freq, 0},
{"websocket-ping-freq", required_argument, 0, "set the frequency (in seconds) of websockets automatic ping packets", uwsgi_opt_set_int, &uwsgi.websockets_ping_freq, 0},
@@ -866,7 +830,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"namespace-net", required_argument, 0, "add network namespace", uwsgi_opt_set_str, &uwsgi.ns_net, 0},
{"ns-net", required_argument, 0, "add network namespace", uwsgi_opt_set_str, &uwsgi.ns_net, 0},
#endif
{"enable-proxy-protocol", no_argument, 0, "enable PROXY1 protocol support (only for http parsers)", uwsgi_opt_true, &uwsgi.enable_proxy_protocol, 0},
{"reuse-port", no_argument, 0, "enable REUSE_PORT flag on socket (BSD only)", uwsgi_opt_true, &uwsgi.reuse_port, 0},
{"tcp-fast-open", required_argument, 0, "enable TCP_FASTOPEN flag on TCP sockets with the specified qlen value", uwsgi_opt_set_int, &uwsgi.tcp_fast_open, 0},
{"tcp-fastopen", required_argument, 0, "enable TCP_FASTOPEN flag on TCP sockets with the specified qlen value", uwsgi_opt_set_int, &uwsgi.tcp_fast_open, 0},
@@ -892,7 +855,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"worker-exec", required_argument, 0, "run the specified command as worker", uwsgi_opt_set_str, &uwsgi.worker_exec, 0},
{"worker-exec2", required_argument, 0, "run the specified command as worker (after post_fork hook)", uwsgi_opt_set_str, &uwsgi.worker_exec2, 0},
{"attach-daemon", required_argument, 0, "attach a command/daemon to the master process (the command has to not go in background)", uwsgi_opt_add_daemon, NULL, UWSGI_OPT_MASTER},
{"attach-control-daemon", required_argument, 0, "attach a command/daemon to the master process (the command has to not go in background), when the daemon dies, the master dies too", uwsgi_opt_add_daemon, NULL, UWSGI_OPT_MASTER},
{"attach-control-daemon", required_argument, 0, "attach a command/daemon to the master process (the command has to not go in background), when teh daemon dies, the master dies too", uwsgi_opt_add_daemon, NULL, UWSGI_OPT_MASTER},
{"smart-attach-daemon", required_argument, 0, "attach a command/daemon to the master process managed by a pidfile (the command has to daemonize)", uwsgi_opt_add_daemon, NULL, UWSGI_OPT_MASTER},
{"smart-attach-daemon2", required_argument, 0, "attach a command/daemon to the master process managed by a pidfile (the command has to NOT daemonize)", uwsgi_opt_add_daemon, NULL, UWSGI_OPT_MASTER},
#ifdef UWSGI_SSL
@@ -922,8 +885,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"exit", optional_argument, 0, "force exit() of the instance", uwsgi_opt_exit, NULL, UWSGI_OPT_IMMEDIATE},
{"cflags", no_argument, 0, "report uWSGI CFLAGS (useful for building external plugins)", uwsgi_opt_cflags, NULL, UWSGI_OPT_IMMEDIATE},
{"dot-h", no_argument, 0, "dump the uwsgi.h used for building the core (useful for building external plugins)", uwsgi_opt_dot_h, NULL, UWSGI_OPT_IMMEDIATE},
{"config-py", no_argument, 0, "dump the uwsgiconfig.py used for building the core (useful for building external plugins)", uwsgi_opt_config_py, NULL, UWSGI_OPT_IMMEDIATE},
{"build-plugin", required_argument, 0, "build a uWSGI plugin for the current binary", uwsgi_opt_build_plugin, NULL, UWSGI_OPT_IMMEDIATE},
{"version", no_argument, 0, "print uWSGI version", uwsgi_opt_print, UWSGI_VERSION, 0},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -1077,10 +1038,10 @@ void warn_pipe() {
struct wsgi_request *wsgi_req = current_wsgi_req();
if (uwsgi.threads < 2 && wsgi_req->uri_len > 0) {
uwsgi_log_verbose("SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request %.*s (ip %.*s) !!!\n", wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr);
uwsgi_log("SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request %.*s (ip %.*s) !!!\n", wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr);
}
else {
uwsgi_log_verbose("SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) !!!\n");
uwsgi_log("SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) !!!\n");
}
}
@@ -1228,9 +1189,7 @@ void grace_them_all(int signum) {
if (uwsgi.lazy) {
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].pid > 0) {
uwsgi_curse(i, SIGHUP);
}
uwsgi_curse(i, SIGHUP);
}
return;
}
@@ -1238,6 +1197,9 @@ void grace_them_all(int signum) {
uwsgi.status.gracefully_reloading = 1;
int waitpid_status;
uwsgi_destroy_processes();
uwsgi_log("...gracefully killing workers...\n");
@@ -1251,10 +1213,36 @@ void grace_them_all(int signum) {
}
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].pid > 0) {
if (uwsgi.auto_snapshot) {
if (uwsgi.workers[i].snapshot > 0) {
kill(uwsgi.workers[i].snapshot, SIGKILL);
if (waitpid(uwsgi.workers[i].snapshot, &waitpid_status, 0) < 0) {
uwsgi_error("waitpid()");
}
}
if (uwsgi.workers[i].pid > 0) {
if (uwsgi.auto_snapshot > 0 && i > uwsgi.auto_snapshot) {
uwsgi.workers[i].snapshot = 0;
uwsgi.workers[i].destroy = 1;
uwsgi_curse(i, SIGHUP);
}
else {
uwsgi.workers[i].snapshot = uwsgi.workers[i].pid;
kill(uwsgi.workers[i].pid, SIGURG);
}
}
}
else if (uwsgi.workers[i].pid > 0) {
uwsgi_curse(i, SIGHUP);
}
}
if (uwsgi.auto_snapshot) {
uwsgi.respawn_snapshots = uwsgi.numproc - uwsgi.auto_snapshot;
if (!uwsgi.respawn_snapshots)
uwsgi.respawn_snapshots = 1;
}
}
void uwsgi_nuclear_blast() {
@@ -1313,6 +1301,23 @@ void harakiri() {
exit(0);
}
void snapshot_me(int signum) {
// wakeup !!!
if (uwsgi.snapshot) {
uwsgi.snapshot = 0;
uwsgi_set_processname(uwsgi.workers[uwsgi.mywid].name);
return;
}
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
if (uwsgi.threads > 1) {
wait_for_threads();
}
uwsgi.snapshot = 1;
uwsgi_set_processname(uwsgi.workers[uwsgi.mywid].snapshot_name);
uwsgi_log("[snapshot] process %d taken\n", (int) getpid());
}
void stats(int signum) {
//fix this for better logging(this cause races)
struct uwsgi_app *ua = NULL;
@@ -1396,8 +1401,8 @@ void what_i_am_doing() {
int unconfigured_hook(struct wsgi_request *wsgi_req) {
if (wsgi_req->uh->modifier1 == 0 && !uwsgi.no_default_app) {
if (uwsgi_apps_cnt > 0 && uwsgi.default_app > -1) {
struct uwsgi_app *ua = &uwsgi_apps[uwsgi.default_app];
if (uwsgi_apps_cnt > 0 && wsgi_req->app_id > -1 && wsgi_req->app_id < uwsgi.max_apps) {
struct uwsgi_app *ua = &uwsgi_apps[wsgi_req->app_id];
if (uwsgi.p[ua->modifier1]->request != unconfigured_hook) {
wsgi_req->uh->modifier1 = ua->modifier1;
return uwsgi.p[ua->modifier1]->request(wsgi_req);
@@ -1436,7 +1441,7 @@ void uwsgi_exec_atexit(void) {
uwsgi_foreach(usl, uwsgi.call_as_user_atexit) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
}
}
}
@@ -1849,25 +1854,16 @@ static struct uwsgi_clock uwsgi_unix_clock = {
.microseconds = uwsgi_unix_microseconds,
};
void uwsgi_init_random() {
srand((unsigned int) (uwsgi.start_tv.tv_usec * uwsgi.start_tv.tv_sec));
}
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int argc, char *argv[], char *envp[]) {
#else
int main(int argc, char *argv[], char *envp[]) {
#endif
uwsgi_setup(argc, argv, envp);
return uwsgi_run();
}
void uwsgi_setup(int argc, char *argv[], char *envp[]) {
#ifdef UWSGI_AS_SHARED_LIBRARY
#ifdef __APPLE__
char ***envPtr = _NSGetEnviron();
environ = *envPtr;
#endif
#else
int main(int argc, char *argv[], char *envp[]) {
#endif
int i;
@@ -1888,6 +1884,7 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
//initialize masterpid with a default value
masterpid = getpid();
@@ -1930,12 +1927,6 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
// set default values
uwsgi_init_default();
// detect cpu cores
#if defined(_SC_NPROCESSORS_ONLN)
uwsgi.cpus = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(_SC_NPROCESSORS_CONF)
uwsgi.cpus = sysconf(_SC_NPROCESSORS_CONF);
#endif
// set default logit hook
uwsgi.logit = uwsgi_logit_simple;
@@ -1956,9 +1947,6 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
// get startup time
gettimeofday(&uwsgi.start_tv, NULL);
// initialize random engine
uwsgi_init_random();
setlinebuf(stdout);
uwsgi.rl.rlim_cur = 0;
@@ -2003,18 +1991,19 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
}
uwsgi.hostname_len = strlen(uwsgi.hostname);
#ifdef UWSGI_ZEROMQ
uwsgi_register_logger("zeromq", uwsgi_zeromq_logger);
uwsgi_register_logger("zmq", uwsgi_zeromq_logger);
#endif
#ifdef UWSGI_ROUTING
uwsgi_register_embedded_routers();
#endif
// call here to allows plugin to override hooks
uwsgi_register_base_hooks();
uwsgi_register_logchunks();
uwsgi_log_encoders_register_embedded();
// register base metrics (so plugins can override them)
uwsgi_metrics_collectors_setup();
//initialize embedded plugins
UWSGI_LOAD_EMBEDDED_PLUGINS
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
@@ -2031,10 +2020,7 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
// set a couple of 'static' magic vars
uwsgi.magic_table['v'] = uwsgi.cwd;
uwsgi.magic_table['h'] = uwsgi.hostname;
uwsgi.magic_table['t'] = uwsgi_64bit2str(uwsgi_now());
uwsgi.magic_table['T'] = uwsgi_64bit2str(uwsgi_micros());
uwsgi.magic_table['V'] = UWSGI_VERSION;
uwsgi.magic_table['k'] = uwsgi_num2str(uwsgi.cpus);
uwsgi.magic_table['['] = "\033";
// you can embed a ini file in the uWSGi binary with default options
@@ -2056,7 +2042,12 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
uwsgi_apply_config_pass('@', uwsgi_simple_file_read);
// last pass: REFERENCEs
uwsgi_apply_config_pass('%', uwsgi_manage_placeholder);
uwsgi_apply_config_pass('%', uwsgi_get_exported_opt);
#ifdef UWSGI_MATHEVAL
// optional pass: MATH
uwsgi_apply_config_pass('=', uwsgi_matheval_str);
#endif
// ok, the options dictionary is available, lets manage it
uwsgi_configure();
@@ -2147,6 +2138,7 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
uwsgi_register_imperial_monitor("glob", uwsgi_imperial_monitor_glob_init, uwsgi_imperial_monitor_glob);
// setup stats pushers
uwsgi_register_stats_pusher("file", uwsgi_stats_pusher_file);
uwsgi_stats_pusher_setup();
// register embedded alarms
@@ -2237,6 +2229,12 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
uwsgi_log_initial("*** big endian arch detected ***\n");
#endif
#if defined(_SC_NPROCESSORS_ONLN)
uwsgi.cpus = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(_SC_NPROCESSORS_CONF)
uwsgi.cpus = sysconf(_SC_NPROCESSORS_CONF);
#endif
uwsgi_log_initial("detected number of CPU cores: %d\n", uwsgi.cpus);
@@ -2327,6 +2325,7 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
}
}
// TODO pluginize basic Linux namespace support
#if defined(__linux__) && !defined(__ia64__)
if (uwsgi.ns) {
@@ -2339,6 +2338,10 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
#if defined(__linux__) && !defined(__ia64__)
}
#endif
// never here
return 0;
}
@@ -2530,6 +2533,9 @@ int uwsgi_start(void *v_argv) {
}
}
uwsgi_log_initial("- async cores set to %d - fd table size: %d\n", uwsgi.async, (int) uwsgi.max_fd);
// optimization, this array maps file descriptor to requests
uwsgi.async_waiting_fd_table = uwsgi_calloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
uwsgi.async_proto_fd_table = uwsgi_calloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
}
#ifdef UWSGI_DEBUG
@@ -2552,8 +2558,12 @@ int uwsgi_start(void *v_argv) {
// allocate rpc structures
uwsgi_rpc_init();
// initialize sharedareas
uwsgi_sharedareas_init();
// setup sharedarea
if (uwsgi.sharedareasize > 0) {
uwsgi.sharedarea = uwsgi_calloc_shared(uwsgi.page_size * uwsgi.sharedareasize);
uwsgi_log("shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea);
uwsgi.sa_lock = uwsgi_rwlock_init("sharedarea");
}
uwsgi.snmp_lock = uwsgi_lock_init("snmp");
@@ -2595,9 +2605,6 @@ int uwsgi_start(void *v_argv) {
// initialize the exception handlers
uwsgi_exception_setup_handlers();
// initialize socket protocols (do it after caching !!!)
uwsgi_protocols_register();
/* plugin initialization */
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->init) {
@@ -2612,7 +2619,6 @@ int uwsgi_start(void *v_argv) {
uwsgi_setup_systemd();
uwsgi_setup_upstart();
uwsgi_setup_zerg();
uwsgi_setup_emperor();
}
@@ -2837,17 +2843,13 @@ unsafe:
// set a default request structure (for loading apps...)
uwsgi.wsgi_req = &uwsgi.workers[0].cores[0].req;
// ok, let's initialize the metrics subsystem
uwsgi_setup_metrics();
// cores are allocated, lets allocate logformat (if required)
if (uwsgi.logformat) {
uwsgi_build_log_format(uwsgi.logformat);
uwsgi.logit = uwsgi_logit_lf;
// TODO check it
//if (uwsgi.logformat_strftime) {
//uwsgi.logit = uwsgi_logit_lf_strftime;
//}
if (uwsgi.logformat_strftime) {
uwsgi.logit = uwsgi_logit_lf_strftime;
}
uwsgi.logvectors = uwsgi_malloc(sizeof(struct iovec *) * uwsgi.cores);
for (j = 0; j < uwsgi.cores; j++) {
uwsgi.logvectors[j] = uwsgi_malloc(sizeof(struct iovec) * uwsgi.logformat_vectors);
@@ -2906,15 +2908,6 @@ next:
}
}
// initialize after_request hooks
uwsgi_foreach(usl, uwsgi.after_request_hooks) {
usl->custom_ptr = dlsym(RTLD_DEFAULT, usl->value);
if (!usl->custom_ptr) {
uwsgi_log("unable to find symbol/function \"%s\"\n", usl->value);
exit(1);
}
uwsgi_log("added \"%s(struct wsgi_request *)\" to the after-request chain\n", usl->value);
}
if (uwsgi.daemonize2) {
masterpid = uwsgi_daemonize2();
@@ -3058,14 +3051,9 @@ next2:
// END OF INITIALIZATION
return 0;
}
int uwsgi_run() {
// !!! from now on, we could be in the master or in a worker !!!
int i;
if (getpid() == masterpid && uwsgi.master_process == 1) {
#ifdef UWSGI_AS_SHARED_LIBRARY
@@ -3179,17 +3167,18 @@ void uwsgi_worker_run() {
// some apps could be mounted only on specific workers
uwsgi_init_worker_mount_apps();
#ifdef UWSGI_ZEROMQ
// setup zeromq context (if required) one per-worker
if (uwsgi.zeromq) {
uwsgi_zeromq_init_sockets();
}
#endif
//postpone the queue initialization as kevent
//do not pass kfd after fork()
if (uwsgi.async > 1) {
// a stack of unused cores
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async);
// fill it with default values
for (i = 0; i < uwsgi.async; i++) {
uwsgi.async_queue_unused[i] = &uwsgi.workers[uwsgi.mywid].cores[i].req;
}
// the first available core is the last one
uwsgi.async_queue_unused_ptr = uwsgi.async - 1;
uwsgi_async_init();
}
// setup UNIX signals for the worker
@@ -3200,6 +3189,11 @@ void uwsgi_worker_run() {
uwsgi_unix_signal(SIGINT, end_me);
uwsgi_unix_signal(SIGTERM, end_me);
if (uwsgi.auto_snapshot) {
uwsgi_unix_signal(SIGURG, snapshot_me);
}
uwsgi_unix_signal(SIGUSR1, stats);
signal(SIGUSR2, (void *) &what_i_am_doing);
if (!uwsgi.ignore_sigpipe) {
@@ -3263,6 +3257,15 @@ void uwsgi_ignition() {
int i;
// snapshot workers do not enter the loop until a specific signal (SIGURG) is raised...
if (uwsgi.snapshot) {
wait_for_call_of_duty:
uwsgi_sig_pause();
if (uwsgi.snapshot)
goto wait_for_call_of_duty;
uwsgi_log("[snapshot] process %d is the new worker %d\n", (int) getpid(), uwsgi.mywid);
}
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->hijack_worker) {
uwsgi.p[i]->hijack_worker();
@@ -3283,28 +3286,6 @@ void uwsgi_ignition() {
}
}
// mark the worker as "accepting" (this is a mark used by chain reloading)
uwsgi.workers[uwsgi.mywid].accepting = 1;
// ready to accept request, if i am a vassal signal Emperor about it
if (uwsgi.has_emperor && uwsgi.mywid == 1) {
char byte = 5;
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
uwsgi_error("write()");
}
}
// run accepting hooks
uwsgi_hooks_run(uwsgi.hook_accepting, "accepting", 1);
if (uwsgi.workers[uwsgi.mywid].respawn_count == 1) {
uwsgi_hooks_run(uwsgi.hook_accepting_once, "accepting-once", 1);
}
if (uwsgi.mywid == 1) {
uwsgi_hooks_run(uwsgi.hook_accepting1, "accepting1", 1);
if (uwsgi.workers[uwsgi.mywid].respawn_count == 1) {
uwsgi_hooks_run(uwsgi.hook_accepting1_once, "accepting1-once", 1);
}
}
if (uwsgi.loop) {
void (*u_loop) (void) = uwsgi_get_loop(uwsgi.loop);
@@ -3327,6 +3308,9 @@ void uwsgi_ignition() {
}
}
if (uwsgi.snapshot) {
uwsgi_ignition();
}
// end of the process...
end_me(0);
}
@@ -3524,7 +3508,7 @@ void uwsgi_init_all_apps() {
uwsgi_foreach(usl, uwsgi.call_pre_app) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
exit(1);
}
}
@@ -3592,7 +3576,7 @@ void uwsgi_init_all_apps() {
uwsgi_foreach(usl, uwsgi.call_post_app) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
}
}
@@ -3752,7 +3736,7 @@ void uwsgi_opt_set_16bit(char *opt, char *value, void *key) {
void uwsgi_opt_set_megabytes(char *opt, char *value, void *key) {
uint64_t *ptr = (uint64_t *) key;
*ptr = (uint64_t)strtoul(value, NULL, 10) * 1024 * 1024;
*ptr = (strtoul(value, NULL, 10)) * 1024 * 1024;
}
void uwsgi_opt_set_dyn(char *opt, char *value, void *key) {
@@ -3888,51 +3872,6 @@ void uwsgi_opt_add_socket(char *opt, char *value, void *protocol) {
uwsgi_sock->proto_name = protocol;
}
#ifdef UWSGI_SSL
void uwsgi_opt_add_ssl_socket(char *opt, char *value, void *protocol) {
char *client_ca = NULL;
// build socket, certificate and key file
char *sock = uwsgi_str(value);
char *crt = strchr(sock, ',');
if (!crt) {
uwsgi_log("invalid https-socket syntax must be socket,crt,key\n");
exit(1);
}
*crt = '\0'; crt++;
char *key = strchr(crt, ',');
if (!key) {
uwsgi_log("invalid https-socket syntax must be socket,crt,key\n");
exit(1);
}
*key = '\0'; key++;
char *ciphers = strchr(key, ',');
if (ciphers) {
*ciphers = '\0'; ciphers++;
client_ca = strchr(ciphers, ',');
if (client_ca) {
*client_ca = '\0'; client_ca++;
}
}
struct uwsgi_socket *uwsgi_sock = uwsgi_new_socket(generate_socket_name(sock));
uwsgi_sock->name_len = strlen(uwsgi_sock->name);
uwsgi_sock->proto_name = protocol;
// ok we have the socket, initialize ssl if required
if (!uwsgi.ssl_initialized) {
uwsgi_ssl_init();
}
// initialize ssl context
uwsgi_sock->ssl_ctx = uwsgi_ssl_new_server_context(uwsgi_sock->name, crt, key, ciphers, client_ca);
if (!uwsgi_sock->ssl_ctx) {
exit(1);
}
}
#endif
void uwsgi_opt_add_socket_no_defer(char *opt, char *value, void *protocol) {
struct uwsgi_socket *uwsgi_sock = uwsgi_new_socket(generate_socket_name(value));
uwsgi_sock->name_len = strlen(uwsgi_sock->name);
@@ -4248,7 +4187,6 @@ int uwsgi_zerg_attach(char *value) {
}
pos++;
}
free(zerg);
}
close(zerg_fd);
@@ -4552,45 +4490,6 @@ void uwsgi_opt_dot_h(char *opt, char *filename, void *foobar) {
exit(0);
}
extern char *uwsgi_config_py;
char *uwsgi_get_config_py() {
char *src = uwsgi_config_py;
size_t len = strlen(src);
char *ptr = uwsgi_malloc(len / 2);
char *base = ptr;
size_t i;
unsigned int u;
for (i = 0; i < len; i += 2) {
sscanf(src + i, "%2x", &u);
*ptr++ = (char) u;
}
#ifdef UWSGI_ZLIB
struct uwsgi_buffer *ub = uwsgi_zlib_decompress(base, ptr-base);
if (!ub) {
free(base);
return "";
}
// add final null byte
uwsgi_buffer_append(ub, "\0", 1);
free(base);
// base is the final blob
base = ub->buf;
ub->buf = NULL;
uwsgi_buffer_destroy(ub);
#endif
return base;
}
void uwsgi_opt_config_py(char *opt, char *filename, void *foobar) {
fprintf(stdout, "%s\n", uwsgi_get_config_py());
exit(0);
}
void uwsgi_opt_build_plugin(char *opt, char *directory, void *foobar) {
uwsgi_build_plugin(directory);
exit(1);
}
void uwsgi_opt_connect_and_read(char *opt, char *address, void *foobar) {
+12 -64
View File
@@ -10,17 +10,9 @@
extern struct uwsgi_server uwsgi;
static struct uwsgi_buffer *uwsgi_websocket_message(struct wsgi_request *wsgi_req, char *msg, size_t len, uint8_t opcode) {
struct uwsgi_buffer *ub = wsgi_req->websocket_send_buf;
if (!ub) {
wsgi_req->websocket_send_buf = uwsgi_buffer_new(10 + len);
ub = wsgi_req->websocket_send_buf;
}
else {
// reset the buffer
ub->pos = 0;
}
if (uwsgi_buffer_u8(ub, opcode)) goto error;
static struct uwsgi_buffer *uwsgi_websocket_message(char *msg, size_t len) {
struct uwsgi_buffer *ub = uwsgi_buffer_new(10 + len);
if (uwsgi_buffer_u8(ub, 0x81)) goto error;
if (len < 126) {
if (uwsgi_buffer_u8(ub, len)) goto error;
}
@@ -37,6 +29,7 @@ static struct uwsgi_buffer *uwsgi_websocket_message(struct wsgi_request *wsgi_re
return ub;
error:
uwsgi_buffer_destroy(ub);
return NULL;
}
@@ -66,79 +59,34 @@ static int uwsgi_websockets_check_pingpong(struct wsgi_request *wsgi_req) {
}
return 0;
}
// pong received, send another ping
// pong received, send anther ping
if (now - wsgi_req->websocket_last_ping >= uwsgi.websockets_ping_freq) {
return uwsgi_websockets_ping(wsgi_req);
}
return 0;
}
static int uwsgi_websocket_send_do(struct wsgi_request *wsgi_req, char *msg, size_t len, uint8_t opcode) {
struct uwsgi_buffer *ub = uwsgi_websocket_message(wsgi_req, msg, len, opcode);
static int uwsgi_websocket_send_do(struct wsgi_request *wsgi_req, char *msg, size_t len) {
struct uwsgi_buffer *ub = uwsgi_websocket_message(msg, len);
if (!ub) return -1;
return uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
}
static int uwsgi_websocket_send_from_sharedarea_do(struct wsgi_request *wsgi_req, int id, uint64_t pos, uint64_t len, uint8_t opcode) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) return -1;
if (!len) {
len = sa->honour_used ? sa->used-pos : ((sa->max_pos+1)-pos);
}
uwsgi_rlock(sa->lock);
sa->hits++;
struct uwsgi_buffer *ub = uwsgi_websocket_message(wsgi_req, sa->area, len, opcode);
uwsgi_rwunlock(sa->lock);
if (!ub) return -1;
return uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
ssize_t ret = uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
uwsgi_buffer_destroy(ub);
return ret;
}
int uwsgi_websocket_send(struct wsgi_request *wsgi_req, char *msg, size_t len) {
if (wsgi_req->websocket_closed) {
return -1;
}
ssize_t ret = uwsgi_websocket_send_do(wsgi_req, msg, len, 0x81);
ssize_t ret = uwsgi_websocket_send_do(wsgi_req, msg, len);
if (ret < 0) {
wsgi_req->websocket_closed = 1;
}
return ret;
}
int uwsgi_websocket_send_from_sharedarea(struct wsgi_request *wsgi_req, int id, uint64_t pos, uint64_t len) {
if (wsgi_req->websocket_closed) {
return -1;
}
ssize_t ret = uwsgi_websocket_send_from_sharedarea_do(wsgi_req, id, pos, len, 0x81);
if (ret < 0) {
wsgi_req->websocket_closed = 1;
}
return ret;
}
int uwsgi_websocket_send_binary(struct wsgi_request *wsgi_req, char *msg, size_t len) {
if (wsgi_req->websocket_closed) {
return -1;
}
ssize_t ret = uwsgi_websocket_send_do(wsgi_req, msg, len, 0x82);
if (ret < 0) {
wsgi_req->websocket_closed = 1;
}
return ret;
}
int uwsgi_websocket_send_binary_from_sharedarea(struct wsgi_request *wsgi_req, int id, uint64_t pos, uint64_t len) {
if (wsgi_req->websocket_closed) {
return -1;
}
ssize_t ret = uwsgi_websocket_send_from_sharedarea_do(wsgi_req, id, pos, len, 0x82);
if (ret < 0) {
wsgi_req->websocket_closed = 1;
}
return ret;
}
static void uwsgi_websocket_parse_header(struct wsgi_request *wsgi_req) {
uint8_t byte1 = wsgi_req->websocket_buf->buf[0];
uint8_t byte2 = wsgi_req->websocket_buf->buf[1];
+7 -244
View File
@@ -179,7 +179,7 @@ int uwsgi_response_add_header_force(struct wsgi_request *wsgi_req, char *key, ui
return uwsgi_response_add_header_do(wsgi_req, key, key_len, value, value_len);
}
static int uwsgi_response_write_headers_do0(struct wsgi_request *wsgi_req) {
int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
if (wsgi_req->headers_sent || !wsgi_req->headers || wsgi_req->response_size || wsgi_req->write_errors) {
return UWSGI_OK;
}
@@ -209,20 +209,11 @@ static int uwsgi_response_write_headers_do0(struct wsgi_request *wsgi_req) {
if (wsgi_req->socket->proto_fix_headers(wsgi_req)) { wsgi_req->write_errors++ ; return -1;}
return UWSGI_AGAIN;
}
int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
int ret = uwsgi_response_write_headers_do0(wsgi_req);
if (ret != UWSGI_AGAIN) return ret;
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_write_headers(wsgi_req, wsgi_req->headers->buf, wsgi_req->headers->pos);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_response_write_headers_do()");
uwsgi_error("uwsgi_response_write_headers_do()");
}
wsgi_req->write_errors++;
return -1;
@@ -230,7 +221,6 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
@@ -248,100 +238,6 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
return UWSGI_OK;
}
/*
private function for highly optimized writes (1 single syscall for headers and body)
*/
static int uwsgi_response_writev_headers_and_body_do(struct wsgi_request *wsgi_req, char *buf, size_t len) {
struct iovec iov[2];
int ret = uwsgi_response_write_headers_do0(wsgi_req);
if (ret != UWSGI_AGAIN) return ret;
iov[0].iov_base = wsgi_req->headers->buf;
iov[0].iov_len = wsgi_req->headers->pos;
iov[1].iov_base = buf;
iov[1].iov_len = len;
size_t iov_len = 2;
for(;;) {
errno = 0;
// no need to use writev if a single iovec remains
if (iov_len == 1) {
buf = iov[0].iov_base;
len = iov[0].iov_len;
// update counters
wsgi_req->headers_size += wsgi_req->headers->pos;
wsgi_req->headers_sent = 1;
wsgi_req->response_size += wsgi_req->write_pos - wsgi_req->headers_size;
wsgi_req->write_pos = 0;
goto fallback;
}
int ret = wsgi_req->socket->proto_writev(wsgi_req, iov, &iov_len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_response_writev_headers_and_body_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
uwsgi_log("uwsgi_response_writev_headers_and_body_do() TIMEOUT !!!\n");
wsgi_req->write_errors++;
return -1;
}
}
wsgi_req->headers_size += wsgi_req->headers->pos;
wsgi_req->response_size += len;
wsgi_req->headers_sent = 1;
// reset for the next write
wsgi_req->write_pos = 0;
return UWSGI_OK;
fallback:
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_write(wsgi_req, buf, len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
// here we use the parent name
uwsgi_req_error("uwsgi_response_write_body_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
// here we use the parent name
uwsgi_log("uwsgi_response_write_body_do() TIMEOUT !!!\n");
wsgi_req->write_errors++;
return -1;
}
}
wsgi_req->response_size += wsgi_req->write_pos;
// reset for the next write
wsgi_req->write_pos = 0;
return UWSGI_OK;
}
// this is the function called by all request plugins to send chunks to the client
int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_t len) {
@@ -382,9 +278,6 @@ int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_
write:
// send headers if not already sent
if (!wsgi_req->headers_sent) {
if (wsgi_req->socket->proto_writev && len > 0 && wsgi_req->headers) {
return uwsgi_response_writev_headers_and_body_do(wsgi_req, buf, len);
}
int ret = uwsgi_response_write_headers_do(wsgi_req);
if (ret == UWSGI_OK) goto sendbody;
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
@@ -397,11 +290,10 @@ sendbody:
if (len == 0) return UWSGI_OK;
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_write(wsgi_req, buf, len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_response_write_body_do()");
uwsgi_error("uwsgi_response_write_body_do()");
}
wsgi_req->write_errors++;
return -1;
@@ -409,7 +301,6 @@ sendbody:
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
@@ -426,130 +317,6 @@ sendbody:
return UWSGI_OK;
}
int uwsgi_response_writev_body_do(struct wsgi_request *wsgi_req, struct iovec *iov, size_t len) {
if (wsgi_req->write_errors) return -1;
if (wsgi_req->ignore_body) return UWSGI_OK;
#ifdef UWSGI_ROUTING
// special case here, we could need to set transformations before
if (!wsgi_req->headers_sent) {
// apply response routes
if (uwsgi_apply_response_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
// from now on ignore write body requests...
wsgi_req->ignore_body = 1;
return -1;
}
wsgi_req->is_response_routing = 0;
}
#endif
size_t i;
int buffering = 0;
// transformations apply to every vector
for(i=0;i<len;i++) {
// if the transformation chain returns 1, we are in buffering mode
if (wsgi_req->transformed_chunk_len == 0 && wsgi_req->transformations) {
int t_ret = uwsgi_apply_transformations(wsgi_req, iov[i].iov_base, iov[i].iov_len);
if (t_ret == 0) {
iov[i].iov_base = wsgi_req->transformed_chunk;
iov[i].iov_len = wsgi_req->transformed_chunk_len;
// reset transformation
wsgi_req->transformed_chunk = NULL;
wsgi_req->transformed_chunk_len = 0;
goto write;
}
if (t_ret == 1) {
buffering = 1;
continue;
}
wsgi_req->write_errors++;
return -1;
}
}
if (buffering) return UWSGI_OK;
write:
// send headers if not already sent
if (!wsgi_req->headers_sent) {
int ret = uwsgi_response_write_headers_do(wsgi_req);
if (ret == UWSGI_OK) goto sendbody;
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
wsgi_req->write_errors++;
return -1;
}
sendbody:
if (len == 0) return UWSGI_OK;
// unfortunately vector based I/O cannot be accomplished on all protocols
if (!wsgi_req->socket->proto_writev) goto fallback;
// we use a copy to avoid mess
size_t iov_len = len;
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_writev(wsgi_req, iov, &iov_len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_response_writev_body_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
uwsgi_log("uwsgi_response_writev_body_do() TIMEOUT !!!\n");
wsgi_req->write_errors++;
return -1;
}
}
goto done;
fallback:
for(i=0;i<len;i++) {
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_write(wsgi_req, iov[i].iov_base, iov[i].iov_len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_response_writev_body_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
uwsgi_log("uwsgi_response_writev_body_do() TIMEOUT !!!\n");
wsgi_req->write_errors++;
return -1;
}
}
}
done:
wsgi_req->response_size += wsgi_req->write_pos;
// reset for the next write
wsgi_req->write_pos = 0;
return UWSGI_OK;
}
int uwsgi_response_sendfile_do(struct wsgi_request *wsgi_req, int fd, size_t pos, size_t len) {
return uwsgi_response_sendfile_do_can_close(wsgi_req, fd, pos, len, 1);
}
@@ -582,7 +349,7 @@ sendfile:
if (len == 0) {
struct stat st;
if (fstat(fd, &st)) {
uwsgi_req_error("uwsgi_response_sendfile_do()/fstat()");
uwsgi_error("uwsgi_response_sendfile_do()/fstat()");
wsgi_req->write_errors++;
if (can_close) close(fd);
return -1;
@@ -600,7 +367,7 @@ sendfile:
if (!can_close) {
int tmp_fd = dup(fd);
if (tmp_fd < 0) {
uwsgi_req_error("uwsgi_response_sendfile_do()/dup()");
uwsgi_error("uwsgi_response_sendfile_do()/dup()");
wsgi_req->write_errors++;
return -1;
}
@@ -621,11 +388,10 @@ sendfile:
wsgi_req->via = UWSGI_VIA_SENDFILE;
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_sendfile(wsgi_req, fd, pos, len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_response_sendfile_do()");
uwsgi_error("uwsgi_response_sendfile_do()");
}
wsgi_req->write_errors++;
if (can_close) close(fd);
@@ -634,7 +400,6 @@ sendfile:
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) {
wsgi_req->write_errors++;
@@ -689,11 +454,10 @@ int uwsgi_simple_write(struct wsgi_request *wsgi_req, char *buf, size_t len) {
wsgi_req->write_pos = 0;
for(;;) {
errno = 0;
int ret = wsgi_req->socket->proto_write(wsgi_req, buf, len);
if (ret < 0) {
if (!uwsgi.ignore_write_errors) {
uwsgi_req_error("uwsgi_simple_write()");
uwsgi_error("uwsgi_simple_write()");
}
wsgi_req->write_errors++;
return -1;
@@ -701,7 +465,6 @@ int uwsgi_simple_write(struct wsgi_request *wsgi_req, char *buf, size_t len) {
if (ret == UWSGI_OK) {
break;
}
if (!uwsgi_is_again()) continue;
ret = uwsgi_wait_write_req(wsgi_req);
if (ret < 0) { wsgi_req->write_errors++; return -1;}
if (ret == 0) {
+6 -5
View File
@@ -1,4 +1,5 @@
import uwsgi
import os
def application(env, start_response):
@@ -14,12 +15,12 @@ def application(env, start_response):
]
)
yield "--%s\r\n" % boundary
yield "--%s\n" % boundary
while 1:
yield "Content-Type: image/jpeg\r\n\r\n"
print os.system('screencapture -t jpg -m -T 1 screenshot.jpg')
f = open('screenshot.jpg')
yield env['wsgi.file_wrapper'](f)
yield "\r\n--%s\r\n" % boundary
uwsgi.sendfile('screenshot.jpg')
yield "--%s\n" % boundary
#os.system('./isightcapture -w 640 -h 480 screenshot.jpg')
#os.system('screencapture -m -T 1 screenshot.jpg')
+1 -11
View File
@@ -52,11 +52,6 @@ int uwsgi_is_a_keep_mount(char *mp) {
}
static int uwsgi_ns_start(void *v_argv) {
uwsgi_start(v_argv);
return uwsgi_run();
}
void linux_namespace_start(void *argv) {
for (;;) {
char stack[PTHREAD_STACK_MIN];
@@ -66,7 +61,7 @@ void linux_namespace_start(void *argv) {
if (uwsgi.ns_net) {
clone_flags |= CLONE_NEWNET;
}
pid_t pid = clone(uwsgi_ns_start, stack + PTHREAD_STACK_MIN, clone_flags, (void *) argv);
pid_t pid = clone(uwsgi_start, stack + PTHREAD_STACK_MIN, clone_flags, (void *) argv);
if (pid == -1) {
uwsgi_error("clone()");
exit(1);
@@ -111,11 +106,6 @@ void linux_namespace_start(void *argv) {
if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == 1) {
exit(1);
}
else if (uwsgi.exit_on_reload && WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == 0) {
uwsgi_log("jailed master process exited and exit-on-reload is enabled, shutting down\n");
exit(0);
}
uwsgi_log("pid %d ended. Respawning...\n", (int) pid);
}
+33 -27
View File
@@ -26,6 +26,9 @@ struct uwsgi_carbon {
unsigned long long *last_busyness_values;
unsigned long long *current_busyness_values;
int *was_busy;
int need_retry;
time_t last_update;
time_t next_retry;
int max_retries;
int retry_delay;
char *root_node;
@@ -37,7 +40,6 @@ struct uwsgi_carbon {
int zero_avg;
uint64_t last_requests;
struct uwsgi_stats_pusher *pusher;
int use_metrics;
} u_carbon;
static struct uwsgi_option carbon_options[] = {
@@ -53,7 +55,6 @@ static struct uwsgi_option carbon_options[] = {
{"carbon-name-resolve", no_argument, 0, "allow using hostname as carbon server address (default disabled)", uwsgi_opt_true, &u_carbon.resolve_hostname, 0},
{"carbon-resolve-names", no_argument, 0, "allow using hostname as carbon server address (default disabled)", uwsgi_opt_true, &u_carbon.resolve_hostname, 0},
{"carbon-idle-avg", required_argument, 0, "average values source during idle period (no requests), can be \"last\", \"zero\", \"none\" (default is last)", uwsgi_opt_set_str, &u_carbon.idle_avg, 0},
{"carbon-use-metrics", no_argument, 0, "don't compute all statistics, use metrics subsystem data instead (warning! key names will be different)", uwsgi_opt_true, &u_carbon.use_metrics, 0},
{0, 0, 0, 0, 0, 0, 0},
};
@@ -107,7 +108,7 @@ static void carbon_post_init() {
if (u_carbon.freq < 1) u_carbon.freq = 60;
if (u_carbon.timeout < 1) u_carbon.timeout = 3;
if (u_carbon.max_retries < 0) u_carbon.max_retries = 0;
if (u_carbon.max_retries <= 0) u_carbon.max_retries = 1;
if (u_carbon.retry_delay <= 0) u_carbon.retry_delay = 7;
if (!u_carbon.id) {
u_carbon.id = uwsgi_str(uwsgi.sockets->name);
@@ -152,13 +153,14 @@ static void carbon_post_init() {
u_carbon.was_busy = uwsgi_calloc(sizeof(int) * uwsgi.numproc);
}
// set next update to now()+retry_delay, this way we will have first flush just after start
u_carbon.last_update = uwsgi_now() - u_carbon.freq + u_carbon.retry_delay;
uwsgi_log("[carbon] carbon plugin started, %is frequency, %is timeout, max retries %i, retry delay %is\n",
u_carbon.freq, u_carbon.timeout, u_carbon.max_retries, u_carbon.retry_delay);
struct uwsgi_stats_pusher_instance *uspi = uwsgi_stats_pusher_add(u_carbon.pusher, NULL);
uspi->freq = u_carbon.freq;
uspi->retry_delay = u_carbon.retry_delay;
uspi->max_retries = u_carbon.max_retries;
// no need to generate the json
uspi->raw=1;
}
@@ -183,15 +185,14 @@ static int carbon_write(int fd, char *fmt,...) {
return 1;
}
static int carbon_push_stats(int retry_cycle, time_t now) {
static void carbon_push_stats(int retry_cycle, time_t now) {
struct carbon_server_list *usl = u_carbon.servers_data;
if (!u_carbon.servers_data) return 0;
if (!u_carbon.servers_data) return;
int i;
int fd;
int wok;
char *ip;
char *carbon_address = NULL;
int needs_retry;
for (i = 0; i < uwsgi.numproc; i++) {
u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i];
@@ -199,7 +200,7 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
u_carbon.was_busy[i-1] += uwsgi_worker_is_busy(i+1);
}
needs_retry = 0;
u_carbon.need_retry = 0;
while(usl) {
if (retry_cycle && usl->healthy)
// skip healthy servers during retry cycle
@@ -227,7 +228,15 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
fd = uwsgi_connect(carbon_address, u_carbon.timeout, 0);
if (fd < 0) {
uwsgi_log("[carbon] Could not connect to carbon server at %s\n", carbon_address);
needs_retry = 1;
if (usl->errors < u_carbon.max_retries) {
u_carbon.need_retry = 1;
u_carbon.next_retry = uwsgi_now() + u_carbon.retry_delay;
} else {
uwsgi_log("[carbon] Maximum number of retries for %s (%d)\n",
carbon_address, u_carbon.max_retries);
usl->healthy = 0;
usl->errors = 0;
}
usl->healthy = 0;
usl->errors++;
free(carbon_address);
@@ -237,8 +246,6 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
// put the socket in non-blocking mode
uwsgi_socket_nb(fd);
if (u_carbon.use_metrics) goto metrics_loop;
unsigned long long total_rss = 0;
unsigned long long total_vsz = 0;
unsigned long long total_tx = 0;
@@ -373,18 +380,6 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
wok = carbon_write(fd, "%s%s.%s.harakiri %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) now);
if (!wok) goto clear;
metrics_loop:
if (u_carbon.use_metrics) {
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
uwsgi_rlock(uwsgi.metrics_lock);
wok = carbon_write(fd, "%s%s.%s.%.*s %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, um->name_len, um->name, (unsigned long long) *um->value, (unsigned long long) now);
uwsgi_rwunlock(uwsgi.metrics_lock);
if (!wok) goto clear;
um = um->next;
}
}
usl->healthy = 1;
usl->errors = 0;
@@ -395,12 +390,23 @@ clear:
nxt:
usl = usl->next;
}
return needs_retry;
if (!retry_cycle) u_carbon.last_update = uwsgi_now();
if (u_carbon.need_retry)
// timeouts and retries might cause additional lags in carbon cycles, we will adjust timer to fix that
u_carbon.last_update -= u_carbon.timeout;
}
static void carbon_push(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
uspi->needs_retry = carbon_push_stats(uspi->retries, now);
if (u_carbon.need_retry && now >= u_carbon.next_retry) {
carbon_push_stats(1, now);
}
else {
// update
u_carbon.need_retry = 0;
carbon_push_stats(0, now);
}
}
static void carbon_cleanup() {
+5 -6
View File
@@ -187,12 +187,11 @@ void uwsgi_opt_corerouter_zerg(char *opt, char *value, void *cr) {
close(zerg_fd);
for(j=0;j<count;j++) {
if (zerg[j] == -1) break;
ugs = uwsgi_new_gateway_socket_from_fd(zerg[j], ucr->name);
ugs->zerg = optarg;
}
free(zerg);
for(j=0;j<count;j++) {
if (zerg[j] == -1) break;
ugs = uwsgi_new_gateway_socket_from_fd(zerg[j], ucr->name);
ugs->zerg = optarg;
}
}
+7 -36
View File
@@ -51,7 +51,7 @@ SV * coroae_coro_new(CV *block) {
XPUSHs(sv_2mortal(newSVpv( "Coro", 4)));
XPUSHs(newRV_inc((SV *)block));
PUTBACK;
call_method("new", G_SCALAR|G_EVAL);
call_method("new", G_SCALAR);
SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV));
@@ -65,33 +65,6 @@ SV * coroae_coro_new(CV *block) {
return newobj;
}
static int coroae_wait_milliseconds(int timeout) {
int ret = -1;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(newSVnv(((double)timeout)/1000.0));
PUTBACK;
call_pv("Coro::AnyEvent::sleep", G_SCALAR|G_EVAL);
SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV));
}
else {
SV *p_ret = POPs;
if (SvTRUE(p_ret)) {
ret = 0;
}
}
PUTBACK;
FREETMPS;
LEAVE;
return ret;
}
static int coroae_wait_fd_read(int fd, int timeout) {
int ret = 0;
dSP;
@@ -101,7 +74,7 @@ static int coroae_wait_fd_read(int fd, int timeout) {
XPUSHs(newSViv(fd));
XPUSHs(newSViv(timeout));
PUTBACK;
call_pv("Coro::AnyEvent::readable", G_SCALAR|G_EVAL);
call_pv("Coro::AnyEvent::readable", G_SCALAR);
SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV));
@@ -128,14 +101,13 @@ static int coroae_wait_fd_write(int fd, int timeout) {
XPUSHs(sv_2mortal(newSViv(fd)));
XPUSHs(sv_2mortal(newSViv(timeout)));
PUTBACK;
call_pv("Coro::AnyEvent::writable", G_SCALAR|G_EVAL);
call_pv("Coro::AnyEvent::writable", G_SCALAR);
SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV));
}
else {
SV *p_ret = POPs;
if (SvTRUE(p_ret)) {
if (SvTRUE(POPs)) {
ret = 1;
}
}
@@ -303,7 +275,7 @@ static SV *coroae_add_watcher(int fd, SV *cb) {
XPUSHs(newRV_inc(cb));
PUTBACK;
call_method( "io", G_SCALAR|G_EVAL);
call_method( "io", G_SCALAR);
SPAGAIN;
if(SvTRUE(ERRSV)) {
@@ -334,7 +306,7 @@ static SV *coroae_condvar_new() {
XPUSHs(sv_2mortal(newSVpv( "AnyEvent", 8)));
PUTBACK;
call_method( "condvar", G_SCALAR|G_EVAL);
call_method( "condvar", G_SCALAR);
SPAGAIN;
if(SvTRUE(ERRSV)) {
@@ -360,7 +332,7 @@ static void coroae_wait_condvar(SV *cv) {
XPUSHs(cv);
PUTBACK;
call_method( "recv", G_DISCARD|G_EVAL);
call_method( "recv", G_DISCARD);
SPAGAIN;
if(SvTRUE(ERRSV)) {
@@ -405,7 +377,6 @@ static void coroae_loop() {
uwsgi.current_wsgi_req = coroae_current_wsgi_req;
uwsgi.wait_write_hook = coroae_wait_fd_write;
uwsgi.wait_read_hook = coroae_wait_fd_read;
uwsgi.wait_milliseconds_hook = coroae_wait_milliseconds;
I_CORO_API("uwsgi::coroae");
+1 -1
View File
@@ -14,7 +14,7 @@ if not coroapi:
NAME='coroae'
CFLAGS = os.popen('perl -MExtUtils::Embed -e ccopts').read().rstrip().split()
CFLAGS += ['-Wno-int-to-pointer-cast', '-Wno-error=format', '-Wno-error=int-to-pointer-cast', '-I%s/Coro' % coroapi]
CFLAGS += ['-Wno-int-to-pointer-cast', '-Wno-error=int-to-pointer-cast', '-I%s/Coro' % coroapi]
LDFLAGS = []
LIBS = []
+9 -7
View File
@@ -52,7 +52,9 @@ s.send_multipart(['touch','foo.ini',"[uwsgi]\nsocket=:4142"])
*/
#include <uwsgi.h>
#ifdef UWSGI_ZEROMQ
#include "../../uwsgi.h"
#include <zmq.h>
extern struct uwsgi_server uwsgi;
@@ -164,7 +166,7 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
}
}
// destroy an instance
else if (!uwsgi_strncmp(ez_cmd, ez_cmd_len, "destroy", 7)) {
else if (!uwsgi_strncmp(ez_cmd, ez_cmd_len, "destroy", 6)) {
struct uwsgi_instance *ui = emperor_get(name);
if (!ui) {
uwsgi_log("[emperor-zeromq] unknown instance \"%s\"\n", name);
@@ -213,11 +215,7 @@ static void uwsgi_imperial_monitor_zeromq_event(struct uwsgi_emperor_scanner *ue
// initialize the zmq PULL socket
static void uwsgi_imperial_monitor_zeromq_init(struct uwsgi_emperor_scanner *ues) {
void *context = zmq_init(1);
if (!context) {
uwsgi_error("uwsgi_imperial_monitor_zeromq_init()/zmq_init()");
exit(1);
}
void *context = uwsgi_zeromq_init();
ues->data = zmq_socket(context, ZMQ_PULL);
if (!ues->data) {
@@ -258,3 +256,7 @@ struct uwsgi_plugin emperor_zeromq_plugin = {
.name = "emperor_zeromq",
.on_load = emperor_zeromq_init,
};
#else
#error the uWSGI ZeroMQ imperial monitor requires uWSGI zeromq support
#endif
+13 -271
View File
@@ -2,7 +2,7 @@
/*
Soon before official Go 1.1, we understood supporting Go in a fork() heavy
Soon before official Go 1.1, we understand supporting Go in a fork() heavy
environment was not blessed by the Go community.
Instead of completely dropping support for Go, we studied how the gccgo project works and we
@@ -16,31 +16,8 @@
the uwsgi.Run() go function directly calls the uwsgi_takeover() function (it automatically
manages mules, spoolers and workers)
The plugin implements goroutines too.
On startup a goroutine is created for each socket and signals file descriptors.
For every request a new goroutine is created too.
The wsgi_request * structure is attached to the "closure" field of the goroutine (PAY ATTENTION)
even if the loop engine makes use of the async mode, pthreads could be spawned all over the place.
For such a reason a mutex is created avoiding the global wsgi_req structures to be clobbered
Contrary to the standard way Go apps are deployed, the plugin supports loading shared libraries.
While this is a common approach in other environments, the Go community prefers monolithic binaries.
As always, choose the model that best suite for you. Eventually building a single uWSGI binary with your Go
app embedded is pretty easy:
CFLAGS=-DUWSGI_GCCGO_MONOLITHIC UWSGI_ADDITIONAL_SOURCES=t/go/uploadtest.go UWSGI_PROFILE=gccgo make
or you can add the following two directives in a build profile:
cflags = -DUWSGI_GCCGO_MONOLITHIC
additional_sources = t/go/uploadtest.go
As well as before each core maps to a goroutine mapped to a real pthread. (goroutines called
from your apps are native goroutines)
*/
@@ -48,29 +25,25 @@ extern struct uwsgi_server uwsgi;
struct uwsgi_plugin gccgo_plugin;
struct uwsgi_gccgo{
// 1 if a main is loaded
int initialized;
struct uwsgi_string_list *libs;
char *args;
pthread_mutex_t wsgi_req_lock;
} ugccgo;
/*
shortcut for enabling the "goroutines" loop engine
*/
static void uwsgi_opt_setup_goroutines(char *opt, char *value, void *foobar) {
// set async mode
uwsgi_opt_set_int(opt, value, &uwsgi.async);
// set loop engine
uwsgi.loop = "goroutines";
}
*/
struct uwsgi_option uwsgi_gccgo_options[] = {
{"go-load", required_argument, 0, "load a go shared library in the process address space, eventually patching main.main and __go_init_main", uwsgi_opt_add_string_list, &ugccgo.libs, 0},
{"gccgo-load", required_argument, 0, "load a go shared library in the process address space, eventually patching main.main and __go_init_main", uwsgi_opt_add_string_list, &ugccgo.libs, 0},
{"go-args", required_argument, 0, "set go commandline arguments", uwsgi_opt_set_str, &ugccgo.args, 0},
{"gccgo-args", required_argument, 0, "set go commandline arguments", uwsgi_opt_set_str, &ugccgo.args, 0},
{"goroutines", required_argument, 0, "a shortcut setting optimal options for goroutine-based apps, takes the number of max goroutines to spawn as argument", uwsgi_opt_setup_goroutines, NULL, UWSGI_OPT_THREADS},
// {"goroutines", required_argument, 0, "a shortcut setting optimal options for goroutine-based apps, takes the number of goroutines to spawn as argument", uwsgi_opt_setup_goroutines, NULL, UWSGI_OPT_THREADS},
{0, 0, 0, 0, 0, 0, 0},
};
@@ -78,46 +51,27 @@ struct uwsgi_option uwsgi_gccgo_options[] = {
// no_split_stack is the key to avoid crashing !!!
void* runtime_m(void) __attribute__ ((noinline, no_split_stack));
// initialize runtime
void runtime_check(void);
void runtime_args(int, char **);
void runtime_osinit(void);
void runtime_schedinit(void);
void *__go_go(void *, void *);
void runtime_main(void);
void runtime_mstart(void *);
// spawn a goroutine
void *__go_go(void *, void *);
// api functions exposed
extern void uwsgigo_request(void *, void *) __asm__ ("go.uwsgi.RequestHandler");
extern void* uwsgigo_env(void *) __asm__ ("go.uwsgi.Env");
extern void* uwsgigo_env_add(void *, void *, uint16_t, void *, uint16_t) __asm__ ("go.uwsgi.EnvAdd");
extern void uwsgigo_run_core(int) __asm__ ("go.uwsgi.RunCore");
extern void uwsgigo_signal_handler(void *, uint8_t) __asm__ ("go.uwsgi.SignalHandler");
// for goroutines
void runtime_netpollinit(void);
void runtime_starttheworld(void);
void *runtime_pollOpen(int) __asm__ ("net.runtime_pollOpen");
void runtime_pollClose(void *) __asm__ ("net.runtime_pollClose");
void runtime_pollUnblock(void *) __asm__ ("net.runtime_pollUnblock");
int runtime_pollWait(void *, int) __asm__ ("net.runtime_pollWait");
void runtime_pollSetDeadline(void *, int64_t, int) __asm__ ("net.runtime_pollSetDeadline");
void runtime_gosched(void);
// the current goroutine
void *runtime_g(void);
// we use the closure field to store the wsgi_req structure
void __go_set_closure(void *);
void *__go_get_closure(void);
//extern void uwsgigo_loop(void) __asm__ ("go.uwsgi.Loop");
static void mainstart(void *arg __attribute__((unused))) {
runtime_main();
}
#ifndef UWSGI_GCCGO_MONOLITHIC
void uwsgigo_main_main(void) __asm__ ("main.main");
void uwsgigo_main_init(void) __asm__ ("__go_init_main");
#endif
void (*uwsgigo_hook_init)(void);
void (*uwsgigo_hook_main)(void);
@@ -148,14 +102,6 @@ int uwsgi_gccgo_helper_register_signal(uint8_t signum, char *receiver, void *han
}
static void uwsgi_gccgo_initialize() {
if (uwsgi.threads > 1) {
uwsgi_log("!!! the Go runtime cannot work in multithreaded modes !!!\n");
exit(1);
}
#ifdef UWSGI_GCCGO_MONOLITHIC
uwsgigo_hook_init = dlsym(RTLD_DEFAULT, "__go_init_main");
uwsgigo_hook_main = dlsym(RTLD_DEFAULT, "main.main");
#endif
struct uwsgi_string_list *usl = ugccgo.libs;
while(usl) {
void *handle = dlopen(usl->value, RTLD_NOW | RTLD_GLOBAL);
@@ -163,16 +109,9 @@ static void uwsgi_gccgo_initialize() {
uwsgi_log("unable to open go shared library: %s\n", dlerror());
exit(1);
}
void *g_init = dlsym(handle, "__go_init_main");
void *g_main = dlsym(handle, "main.main");
if (g_init && g_main) {
uwsgigo_hook_init = g_init;
uwsgigo_hook_main = g_main;
uwsgi_log("[uwsgi-gccgo] loaded %s as main\n", usl->value);
}
else {
uwsgi_log("[uwsgi-gccgo] loaded %s\n", usl->value);
}
uwsgi_log("[uwsgi-gccgo] loaded %s\n", usl->value);
uwsgigo_hook_init = dlsym(handle, "__go_init_main");
uwsgigo_hook_main = dlsym(handle, "main.main");
usl = usl->next;
}
@@ -180,8 +119,6 @@ static void uwsgi_gccgo_initialize() {
return;
}
ugccgo.initialized = 1;
// Go runtime initialization
int argc = 0;
if (ugccgo.args) {
@@ -194,7 +131,7 @@ static void uwsgi_gccgo_initialize() {
}
runtime_check();
if (argc > 0) {
char **argv = uwsgi_calloc(sizeof(char *) * (argc + 2));
char **argv = uwsgi_calloc(sizeof(char *) * (argc + 1));
char *argv_list = uwsgi_str(ugccgo.args);
char *p, *ctx = NULL;
int n = 0;
@@ -208,7 +145,6 @@ static void uwsgi_gccgo_initialize() {
char *argv[2] = {0,0};
runtime_args(0, argv);
}
runtime_osinit();
runtime_schedinit();
__go_go(mainstart, NULL);
@@ -217,10 +153,6 @@ static void uwsgi_gccgo_initialize() {
}
static int uwsgi_gccgo_request(struct wsgi_request *wsgi_req) {
if (!ugccgo.initialized) {
uwsgi_log("!!! Go runtime not initialized !!!\n");
goto end;
}
/* Standard GO request */
if (!wsgi_req->uh->pktsize) {
uwsgi_log("Empty GO request. skip.\n");
@@ -238,7 +170,6 @@ static int uwsgi_gccgo_request(struct wsgi_request *wsgi_req) {
i++;
}
uwsgigo_request(wsgi_req->async_environ, wsgi_req);
end:
return UWSGI_OK;
}
@@ -247,204 +178,15 @@ static void uwsgi_gccgo_after_request(struct wsgi_request *wsgi_req) {
}
static int uwsgi_gccgo_signal_handler(uint8_t signum, void *handler) {
if (!ugccgo.initialized) return -1;
uwsgigo_signal_handler(handler, signum);
return 0;
}
#define free_req_queue pthread_mutex_lock(&ugccgo.wsgi_req_lock);uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req; pthread_mutex_unlock(&ugccgo.wsgi_req_lock)
static void uwsgi_gccgo_request_goroutine(void *arg) {
struct wsgi_request *wsgi_req = (struct wsgi_request *) arg;
// map wsgi_req to the goroutine
__go_set_closure(wsgi_req);
int ret,status;
for(;;) {
ret = uwsgi.wait_read_hook(wsgi_req->fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
wsgi_req->switches++;
if (ret <= 0) {
goto end;
}
retry:
status = wsgi_req->socket->proto(wsgi_req);
if (status < 0) {
goto end;
}
else if (status == 0) {
break;
}
if (uwsgi_is_again()) continue;
goto retry;
}
#ifdef UWSGI_ROUTING
if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
goto end;
}
#endif
for(;;) {
if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) {
goto end;
}
wsgi_req->switches++;
// yield
runtime_gosched();
}
end:
uwsgi_close_request(wsgi_req);
free_req_queue;
}
static struct wsgi_request *uwsgi_gccgo_current_wsgi_req(void) {
return (struct wsgi_request *) __go_get_closure();
}
static int uwsgi_gccgo_wait_read_hook(int fd, int timeout) {
void *pdesc = runtime_pollOpen(fd);
int64_t t = (uwsgi_micros() * 1000LL) + (((int64_t)timeout) * 1000LL * 1000LL * 1000LL);
runtime_pollSetDeadline(pdesc, t, 'r');
int ret = runtime_pollWait(pdesc, 'r');
runtime_pollUnblock(pdesc);
runtime_pollClose(pdesc);
if (ret == 0) return 1;
// timeout
if (ret == 2) return 0;
return -1;
}
static int uwsgi_gccgo_wait_write_hook(int fd, int timeout) {
void *pdesc = runtime_pollOpen(fd);
int64_t t = (uwsgi_micros() * 1000LL) + (((int64_t)timeout) * 1000LL * 1000LL * 1000LL);
runtime_pollSetDeadline(pdesc, t, 'w');
int ret = runtime_pollWait(pdesc, 'w');
runtime_pollUnblock(pdesc);
runtime_pollClose(pdesc);
if (ret == 0) return 1;
// timeout
if (ret == 2) return 0;
return -1;
}
/*
this goroutine manages signals
*/
static void uwsgi_gccgo_signal_goroutine(void *arg) {
int *fd = (int *) arg;
void *pdesc = runtime_pollOpen(*fd);
for(;;) {
runtime_pollWait(pdesc, 'r');
retry:
uwsgi_receive_signal(*fd, "worker", uwsgi.mywid);
if (uwsgi_is_again()) continue;
goto retry;
}
}
static void uwsgi_gccgo_socket_goroutine(void *arg) {
struct uwsgi_socket *uwsgi_sock = (struct uwsgi_socket *) arg;
struct wsgi_request *wsgi_req = NULL;
void *pdesc = runtime_pollOpen(uwsgi_sock->fd);
// wait for connection
for(;;) {
runtime_pollWait(pdesc, 'r');
retry:
pthread_mutex_lock(&ugccgo.wsgi_req_lock);
wsgi_req = find_first_available_wsgi_req();
pthread_mutex_unlock(&ugccgo.wsgi_req_lock);
if (wsgi_req == NULL) {
uwsgi_async_queue_is_full(uwsgi_now());
// try rescheduling...
// we do not use runtime_gosched() as we want to call the netpoll loop too
runtime_pollUnblock(pdesc);
runtime_pollClose(pdesc);
pdesc = runtime_pollOpen(uwsgi_sock->fd);
continue;
}
// fill wsgi_request structure
wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock );
// mark core as used
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1;
// accept the connection (since uWSGI 1.5 all of the sockets are non-blocking)
if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) {
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 0;
free_req_queue;
if (uwsgi_is_again()) continue;
goto retry;
}
wsgi_req->start_of_request = uwsgi_micros();
wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request/1000000;
// enter harakiri mode
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
}
// spawn the new goroutine
__go_go(uwsgi_gccgo_request_goroutine, wsgi_req);
goto retry;
}
}
static void uwsgi_gccgo_loop() {
if (!ugccgo.initialized) {
uwsgi_log("no go.main code loaded !!!\n");
exit(1);
}
// initialize the log protecting the wsgi_req structures
pthread_mutex_init(&ugccgo.wsgi_req_lock, NULL);
// hooks
uwsgi.current_wsgi_req = uwsgi_gccgo_current_wsgi_req;
uwsgi.wait_write_hook = uwsgi_gccgo_wait_write_hook;
uwsgi.wait_read_hook = uwsgi_gccgo_wait_read_hook;
// ininitialize Go I/O loop
runtime_netpollinit();
if (uwsgi.signal_socket > -1) {
__go_go(uwsgi_gccgo_signal_goroutine, &uwsgi.signal_socket);
__go_go(uwsgi_gccgo_signal_goroutine, &uwsgi.my_signal_socket);
}
// start a goroutine for each socket
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
if (!uwsgi_sock->next) {
uwsgi_gccgo_socket_goroutine(uwsgi_sock);
}
else {
__go_go(uwsgi_gccgo_socket_goroutine, uwsgi_sock);
}
uwsgi_sock = uwsgi_sock->next;
}
// never here
}
static void uwsgi_gccgo_on_load() {
uwsgi_register_loop( (char *) "go", uwsgi_gccgo_loop);
uwsgi_register_loop( (char *) "goroutine", uwsgi_gccgo_loop);
uwsgi_register_loop( (char *) "goroutines", uwsgi_gccgo_loop);
}
struct uwsgi_plugin gccgo_plugin = {
.name = "gccgo",
.modifier1 = 11,
.options = uwsgi_gccgo_options,
.on_load = uwsgi_gccgo_on_load,
//.on_load = uwsgi_gccgo_on_load,
.request = uwsgi_gccgo_request,
.after_request = uwsgi_gccgo_after_request,
.post_fork = uwsgi_gccgo_initialize,
+2 -45
View File
@@ -1,12 +1,5 @@
package uwsgi
/*
this is a very low-level module, full of performance hacks
do not take it as a good example of go coding...
*/
import (
"strings"
"net/http"
@@ -27,27 +20,17 @@ func uwsgi_response_add_header(*interface{}, *byte, uint16, *byte, uint16) int
func uwsgi_request_body_read(*interface{}, *byte, uint64) int
//extern uwsgi_gccgo_helper_register_signal
func uwsgi_register_signal(uint8, *byte, func(uint8)) int
//extern uwsgi_cache_magic_get
func uwsgi_cache_magic_get(*byte, uint16, *uint64, *uint64, *byte) *byte;
//extern __go_byte_array_to_string
func __go_byte_array_to_string(*byte, int) string
//extern free
func free(* byte)
var uwsgi_signals_gc [256]func(uint8)
var uwsgi_env_gc map[interface{}]interface{}
func Env(wsgi_req *interface{}) *map[string]string {
var env map[string]string
env = make(map[string]string)
uwsgi_env_gc[wsgi_req] = &env
return &env
}
func EnvAdd(env *map[string]string, k *byte, kl uint16, v *byte, vl uint16) {
s_k := __go_byte_array_to_string(k, int(kl))
s_v := __go_byte_array_to_string(v, int(vl))
(*env)[ s_k ] = s_v
func EnvAdd(env *map[string]string, k *[65536]byte, kl uint16, v *[65536]byte, vl uint16) {
(*env)[ string((*k)[0:kl]) ] = string((*v)[0:vl])
}
type ResponseWriter struct {
@@ -115,13 +98,9 @@ func RequestHandler(env *map[string]string, wsgi_req *interface{}) {
w := ResponseWriter{httpReq, wsgi_req,http.Header{},false}
http.DefaultServeMux.ServeHTTP(&w, httpReq)
}
delete(uwsgi_env_gc, wsgi_req)
}
func RegisterSignal(signum uint8, receiver string, handler func(uint8)) bool {
if (receiver == "") {
receiver = "worker"
}
var b []byte = []byte(receiver)
if (uwsgi_register_signal(signum, &b[0], handler) < 0) {
return false
@@ -130,32 +109,10 @@ func RegisterSignal(signum uint8, receiver string, handler func(uint8)) bool {
return true
}
// get an item from the cache
func CacheGet(key string, cache string) string {
var b_key []byte = []byte(key)
var v_len uint64 = 0
var expires uint64 = 0
var value *byte
if (cache == "") {
value = uwsgi_cache_magic_get(&b_key[0], uint16(len(b_key)), &v_len, &expires, nil)
} else {
b_cache := []byte(cache)
value = uwsgi_cache_magic_get(&b_key[0], uint16(len(b_key)), &v_len, &expires, &b_cache[0])
}
ret := __go_byte_array_to_string(value, int(v_len))
free(value)
return ret
}
func SignalHandler(handler func(uint8), signum uint8) {
handler(signum)
}
func Run() {
uwsgi_env_gc = make(map[interface{}]interface{})
uwsgi_takeover()
}
-13
View File
@@ -1,13 +0,0 @@
import os
NAME='gccgo'
CFLAGS = ['-g']
LDFLAGS = []
LIBS = ['-lgo']
GCC_LIST = ['gccgo_plugin', 'uwsgi.go']
def post_build(config):
if os.path.exists('plugins/gccgo/uwsgi.go.o'):
if os.system("objcopy -j .go_export plugins/gccgo/uwsgi.go.o plugins/gccgo/uwsgi.gox") != 0:
os._exit(1)
print("*** uwsgi.gox available in %s/plugins/gccgo ***" % os.getcwd())
+1 -4
View File
@@ -291,9 +291,7 @@ request:
}
end:
if (greenlet_switch) {
Py_DECREF(greenlet_switch);
}
Py_DECREF(greenlet_switch);
end2:
Py_DECREF(current_greenlet);
@@ -361,7 +359,6 @@ static void gevent_loop() {
uwsgi.wait_write_hook = uwsgi_gevent_wait_write_hook;
uwsgi.wait_read_hook = uwsgi_gevent_wait_read_hook;
uwsgi.wait_milliseconds_hook = uwsgi_gevent_wait_milliseconds_hook;
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
-1
View File
@@ -2,7 +2,6 @@
int uwsgi_gevent_wait_write_hook(int, int);
int uwsgi_gevent_wait_read_hook(int, int);
int uwsgi_gevent_wait_milliseconds_hook(int);
#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)
-39
View File
@@ -98,42 +98,3 @@ int uwsgi_gevent_wait_read_hook(int fd, int timeout) {
return 1;
}
int uwsgi_gevent_wait_milliseconds_hook(int timeout) {
PyObject *ret = NULL;
PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "f", ((double) timeout)/1000.0);
if (!timer) return -1;
PyObject *current_greenlet = GET_CURRENT_GREENLET;
PyObject *current = PyObject_GetAttrString(current_greenlet, "switch");
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
if (!ret) {
Py_DECREF(current); Py_DECREF(current_greenlet);
Py_DECREF(timer);
return -1;
}
Py_DECREF(ret);
ret = PyObject_CallMethod(ugevent.hub, "switch", NULL);
if (!ret) {
ret = PyObject_CallMethod(timer, "stop", NULL);
if (ret) { Py_DECREF(ret); }
Py_DECREF(current); Py_DECREF(current_greenlet);
Py_DECREF(timer);
return -1;
}
Py_DECREF(ret);
if (ret == timer) {
ret = PyObject_CallMethod(timer, "stop", NULL);
if (ret) { Py_DECREF(ret); }
Py_DECREF(current); Py_DECREF(current_greenlet);
Py_DECREF(timer);
return 0;
}
return -1;
}
+4
View File
@@ -1,6 +1,10 @@
#include <uwsgi.h>
#include <api/glfs.h>
#ifdef UWSGI_MATHEVAL
#error currently the glusterfs plugins is not compatible with uWSGI built with matheval support
#endif
extern struct uwsgi_server uwsgi;
/*
+4 -40
View File
@@ -16,22 +16,6 @@ static struct uwsgi_option greenlet_options[] = {
{ 0, 0, 0, 0, 0, 0, 0 }
};
struct wsgi_request *uwsgi_greenlet_current_wsgi_req(void) {
struct wsgi_request *wsgi_req = NULL;
PyObject *current_greenlet = (PyObject *)PyGreenlet_GetCurrent();
PyObject *py_wsgi_req = PyObject_GetAttrString(current_greenlet, "uwsgi_wsgi_req");
// not in greenlet
if (!py_wsgi_req) {
uwsgi_log("[BUG] current_wsgi_req NOT FOUND !!!\n");
goto end;
}
wsgi_req = (struct wsgi_request*) PyLong_AsLong(py_wsgi_req);
Py_DECREF(py_wsgi_req);
end:
Py_DECREF(current_greenlet);
return wsgi_req;
}
static void gil_greenlet_get() {
pthread_setspecific(up.upt_gil_key, (void *) PyGILState_Ensure());
}
@@ -42,11 +26,9 @@ static void gil_greenlet_release() {
static PyObject *py_uwsgi_greenlet_request(PyObject * self, PyObject *args) {
struct wsgi_request *wsgi_req = uwsgi.wsgi_req;
async_schedule_to_req_green();
Py_DECREF(ugl.gl[wsgi_req->async_id]);
Py_DECREF(ugl.gl[uwsgi.wsgi_req->async_id]);
Py_INCREF(Py_None);
return Py_None;
@@ -64,7 +46,6 @@ static void greenlet_schedule_to_req() {
if (!uwsgi.wsgi_req->suspended) {
ugl.gl[id] = PyGreenlet_New(ugl.callable, NULL);
PyObject_SetAttrString((PyObject *)ugl.gl[id], "uwsgi_wsgi_req", PyLong_FromLong((long) uwsgi.wsgi_req));
uwsgi.wsgi_req->suspended = 1;
}
@@ -73,13 +54,7 @@ static void greenlet_schedule_to_req() {
uwsgi.p[modifier1]->suspend(NULL);
}
PyObject *ret = PyGreenlet_Switch(ugl.gl[id], NULL, NULL);
if (!ret) {
PyErr_Print();
uwsgi_log_verbose("[BUG] unable to switch greenlet !!!\n");
exit(1);
}
Py_DECREF(ret);
PyGreenlet_Switch(ugl.gl[id], NULL, NULL);
if (uwsgi.p[modifier1]->resume) {
uwsgi.p[modifier1]->resume(NULL);
@@ -96,13 +71,7 @@ static void greenlet_schedule_to_main(struct wsgi_request *wsgi_req) {
if (uwsgi.p[wsgi_req->uh->modifier1]->suspend) {
uwsgi.p[wsgi_req->uh->modifier1]->suspend(wsgi_req);
}
PyObject *ret = PyGreenlet_Switch(ugl.main, NULL, NULL);
if (!ret) {
PyErr_Print();
uwsgi_log_verbose("[BUG] unable to switch greenlet !!!\n");
exit(1);
}
Py_DECREF(ret);
PyGreenlet_Switch(ugl.main, NULL, NULL);
if (uwsgi.p[wsgi_req->uh->modifier1]->resume) {
uwsgi.p[wsgi_req->uh->modifier1]->resume(wsgi_req);
}
@@ -124,10 +93,7 @@ static void greenlet_init_apps(void) {
up.gil_release = gil_greenlet_release;
}
// map wsgi_req to greenlet object
uwsgi.current_wsgi_req = uwsgi_greenlet_current_wsgi_req;
// blindly call it as the stackless gil engine is already set
// blindy call it as the stackless gil engine is already set
UWSGI_GET_GIL
@@ -135,9 +101,7 @@ static void greenlet_init_apps(void) {
ugl.gl = uwsgi_malloc( sizeof(PyGreenlet *) * uwsgi.async );
ugl.main = PyGreenlet_GetCurrent();
Py_INCREF(ugl.main);
ugl.callable = PyCFunction_New(uwsgi_greenlet_request_method, NULL);
Py_INCREF(ugl.callable);
uwsgi_log("enabled greenlet engine\n");
uwsgi.schedule_to_main = greenlet_schedule_to_main;
+1 -1
View File
@@ -139,7 +139,7 @@ void uwsgi_opt_https2(char *opt, char *value, void *cr) {
#ifdef UWSGI_SPDY
spdyerror:
uwsgi_log("unable to initialize SPDY settings buffers\n");
uwsgi_log("unable to inizialize SPDY settings buffers\n");
exit(1);
#endif
}
+4 -5
View File
@@ -127,7 +127,7 @@ JNIEXPORT jobject JNICALL uwsgi_jvm_api_rpc(JNIEnv *env, jclass c, jobject j_arg
char *argv[256];
uint16_t argvs[256];
jobject argvj[256];
uint64_t size = 0;
uint16_t size = 0;
size_t args = uwsgi_jvm_array_len(j_args);
if (args < 2) return NULL;
@@ -1277,7 +1277,7 @@ void uwsgi_jvm_release_bytearray(jobject o, char *str) {
(*ujvm_env)->ReleaseByteArrayElements(ujvm_env, o, (jbyte *)str, 0);
}
static uint64_t uwsgi_jvm_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
static uint16_t uwsgi_jvm_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
jvalue args[1];
jobject str_array = (*ujvm_env)->NewObjectArray(ujvm_env, argc, ujvm.str_class, NULL);
if (!str_array) return 0;
@@ -1294,10 +1294,9 @@ static uint64_t uwsgi_jvm_rpc(void *func, uint8_t argc, char **argv, uint16_t ar
return 0;
}
size_t rlen = uwsgi_jvm_strlen(ret);
if (rlen > 0) {
*buffer = uwsgi_malloc(rlen);
if (rlen <= 0xffff) {
char *b = uwsgi_jvm_str2c(ret);
memcpy(*buffer, b, rlen);
memcpy(buffer, b, rlen);
uwsgi_jvm_release_chars(ret, b);
uwsgi_jvm_local_unref(ret);
return rlen;
+1 -5
View File
@@ -7,11 +7,7 @@ JVM_INCPATH = None
JVM_LIBPATH = None
operating_system = os.uname()[0].lower()
try:
arch = os.environ['JVM_ARCH']
except:
arch = os.uname()[4].lower()
arch = os.uname()[4].lower()
if arch in ('i686', 'x86', 'x86_32'):
arch = 'i386'
-61
View File
@@ -1,61 +0,0 @@
#include <uwsgi.h>
#include <zmq.h>
extern struct uwsgi_server uwsgi;
static struct uwsgi_option uwsgi_zmq_logger_options[] = {
{"log-zeromq", required_argument, 0, "send logs to a zeromq server", uwsgi_opt_set_logger, "zeromq", UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{NULL, 0, 0, NULL, NULL, NULL, 0},
};
// the zeromq logger
static ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *ul, char *message, size_t len) {
if (!ul->configured) {
if (!ul->arg) {
uwsgi_log_safe("invalid zeromq syntax\n");
exit(1);
}
void *ctx = zmq_init(1);
if (!ctx) exit(1);
ul->data = zmq_socket(ctx, ZMQ_PUSH);
if (ul->data == NULL) {
uwsgi_error_safe("zmq_socket()");
exit(1);
}
if (zmq_connect(ul->data, ul->arg) < 0) {
uwsgi_error_safe("zmq_connect()");
exit(1);
}
ul->configured = 1;
}
zmq_msg_t msg;
if (zmq_msg_init_size(&msg, len) == 0) {
memcpy(zmq_msg_data(&msg), message, len);
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
zmq_sendmsg(ul->data, &msg, 0);
#else
zmq_send(ul->data, &msg, 0);
#endif
zmq_msg_close(&msg);
}
return 0;
}
static void uwsgi_zmq_logger_register() {
uwsgi_register_logger("zmq", uwsgi_zeromq_logger);
uwsgi_register_logger("zeromq", uwsgi_zeromq_logger);
}
struct uwsgi_plugin logzmq_plugin = {
.name = "logzmq",
.options = uwsgi_zmq_logger_options,
.on_load = uwsgi_zmq_logger_register,
};
-7
View File
@@ -1,7 +0,0 @@
NAME='logzmq'
CFLAGS = []
LDFLAGS = []
LIBS = ['-lzmq']
GCC_LIST = ['plugin']
+3 -4
View File
@@ -670,7 +670,7 @@ static int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
}
static uint64_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
static uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
uint8_t i;
const char *sv;
@@ -702,9 +702,8 @@ static uint64_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t a
#ifdef UWSGI_DEBUG
uwsgi_log("sv = %s sl = %lu\n", sv, (unsigned long) sl);
#endif
if (sl > 0) {
*buffer = uwsgi_malloc(sl);
memcpy(*buffer, sv, sl);
if (sl <= 0xffff) {
memcpy(buffer, sv, sl);
lua_pop(L, 1);
return sl;
}
-52
View File
@@ -1,52 +0,0 @@
#include <uwsgi.h>
#include <matheval.h>
static char *uwsgi_route_var_math(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
char *ret = NULL;
// avoid crash
if (!wsgi_req->var_cnt) return NULL;
// we make a bit of fun here, we do a copy of the vars buffer (+1 byte for final zero) and zeor-pad all of the strings
char *vars_buf = uwsgi_malloc(wsgi_req->uh->pktsize + keylen + 1);
char **names = uwsgi_malloc(sizeof(char *) * (wsgi_req->var_cnt/2));
double *values = uwsgi_calloc(sizeof(double) * (wsgi_req->var_cnt/2));
int i,j = 0;
char *ptr = vars_buf;
for (i = wsgi_req->var_cnt-1; i > 0; i -= 2) {
memcpy(ptr, wsgi_req->hvec[i-1].iov_base, wsgi_req->hvec[i-1].iov_len);
names[j] = ptr;
ptr += wsgi_req->hvec[i-1].iov_len;
*ptr++=0;
char *num = ptr;
memcpy(ptr, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
ptr += wsgi_req->hvec[i].iov_len;
*ptr++=0;
values[j] = strtod(num, NULL);
j++;
}
char *expr = ptr;
memcpy(ptr, key, keylen); ptr += keylen;
*ptr++=0;
void *e = evaluator_create(expr);
if (!e) goto end;
double n = evaluator_evaluate(e, j, names, values);
evaluator_destroy(e);
ret = uwsgi_num2str((int)n);
*vallen = strlen(ret);
end:
free(vars_buf);
free(names);
free(values);
return ret;
}
static void router_matheval_register() {
struct uwsgi_route_var *urv = uwsgi_register_route_var("math", uwsgi_route_var_math);
urv->need_free = 1;
}
struct uwsgi_plugin matheval_plugin = {
.name = "matheval",
.on_load = router_matheval_register,
};
-6
View File
@@ -1,6 +0,0 @@
NAME='matheval'
CFLAGS = []
LDFLAGS = []
LIBS = ['-lmatheval']
GCC_LIST = ['math']
-7
View File
@@ -1,7 +0,0 @@
NAME='mongrel2'
CFLAGS = []
LDFLAGS = []
LIBS = ['-lzmq']
GCC_LIST = ['mongrel2']
+1 -1
View File
@@ -374,7 +374,7 @@ PHP_FUNCTION(uwsgi_rpc) {
zval *z_current_obj;
char *argv[256];
uint16_t argvs[256];
uint64_t size = 0;
uint16_t size = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &varargs, &num_args) == FAILURE) {
RETURN_NULL();
-5
View File
@@ -58,11 +58,6 @@ struct uwsgi_perl {
time_t last_auto_reload;
struct uwsgi_string_list *auto_reload_ignore;
HV *auto_reload_hash;
int enable_psgix_io;
char *shell;
int shell_oneshot;
};
void init_perl_embedded_module(void);
+2 -3
View File
@@ -149,7 +149,7 @@ XS(XS_streaming_write) {
uwsgi_response_write_body_do(wsgi_req, body, blen);
uwsgi_pl_check_write_errors {
croak("error while streaming PSGI response");
// noop
}
XSRETURN(0);
@@ -349,7 +349,6 @@ 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 IO::Socket;", 0);
perl_eval_pv("use Scalar::Util;", 0);
if (!uperl.no_die_catch) {
perl_eval_pv("use Devel::StackTrace;", 0);
@@ -463,7 +462,7 @@ void uwsgi_psgi_app() {
init_psgi_app(NULL, uperl.psgi, strlen(uperl.psgi), uperl.main);
}
// create a perl environment (if needed)
else if (uperl.exec || uperl.shell) {
else if (uperl.exec) {
PERL_SET_CONTEXT(uperl.main[0]);
perl_parse(uperl.main[0], xs_init, 2, uperl.embedding, NULL);
}
+8 -101
View File
@@ -11,25 +11,9 @@ struct uwsgi_perl uperl;
struct uwsgi_plugin psgi_plugin;
static void uwsgi_opt_plshell(char *opt, char *value, void *foobar) {
uwsgi.honour_stdin = 1;
if (value) {
uperl.shell = value;
}
else {
uperl.shell = "";
}
if (!strcmp("plshell-oneshot", opt)) {
uperl.shell_oneshot = 1;
}
}
struct uwsgi_option uwsgi_perl_options[] = {
{"psgi", required_argument, 0, "load a psgi app", uwsgi_opt_set_str, &uperl.psgi, 0},
{"psgi-enable-psgix-io", no_argument, 0, "enable psgix.io support", uwsgi_opt_true, &uperl.enable_psgix_io, 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},
#ifdef PERL_VERSION_STRING
@@ -41,9 +25,6 @@ struct uwsgi_option uwsgi_perl_options[] = {
{"perl-exec-post-fork", required_argument, 0, "exec the specified perl file after fork()", uwsgi_opt_add_string_list, &uperl.exec_post_fork, 0},
{"perl-auto-reload", required_argument, 0, "enable perl auto-reloader with the specified frequency", uwsgi_opt_set_int, &uperl.auto_reload, UWSGI_OPT_MASTER},
{"perl-auto-reload-ignore", required_argument, 0, "ignore the specified files when auto-reload is enabled", uwsgi_opt_add_string_list, &uperl.auto_reload_ignore, UWSGI_OPT_MASTER},
{"plshell", optional_argument, 0, "run a perl interactive shell", uwsgi_opt_plshell, NULL, 0},
{"plshell-oneshot", no_argument, 0, "run a perl interactive shell (one shot)", uwsgi_opt_plshell, NULL, 0},
{0, 0, 0, 0, 0, 0, 0},
};
@@ -121,31 +102,6 @@ SV *uwsgi_perl_obj_new(char *class, size_t class_len) {
}
SV *uwsgi_perl_obj_new_from_fd(char *class, size_t class_len, int fd) {
SV *newobj;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv( class, class_len)));
XPUSHs(sv_2mortal(newSViv( fd )));
XPUSHs(sv_2mortal(newSVpv( "w", 1 )));
PUTBACK;
call_method( "new_from_fd", G_SCALAR);
SPAGAIN;
newobj = SvREFCNT_inc(POPs);
PUTBACK;
FREETMPS;
LEAVE;
return newobj;
}
SV *uwsgi_perl_call_stream(SV *func) {
SV *ret = NULL;
@@ -194,12 +150,9 @@ int uwsgi_perl_obj_can(SV *obj, char *method, size_t len) {
XPUSHs(sv_2mortal(newSVpv(method, len)));
PUTBACK;
call_method( "can", G_SCALAR|G_EVAL);
call_method( "can", G_SCALAR);
SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("%s", SvPV_nolen(ERRSV));
}
ret = SvROK(POPs);
PUTBACK;
@@ -256,7 +209,7 @@ SV *uwsgi_perl_obj_call(SV *obj, char *method) {
SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("%s", SvPV_nolen(ERRSV));
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
}
else {
ret = SvREFCNT_inc(POPs);
@@ -292,10 +245,7 @@ AV *psgi_call(struct wsgi_request *wsgi_req, SV *psgi_func, SV *env) {
uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV));
}
else {
SV *r = POPs;
if (SvROK(r)) {
ret = (AV *) SvREFCNT_inc(SvRV(r));
}
ret = (AV *) SvREFCNT_inc(SvRV(POPs));
}
PUTBACK;
@@ -410,12 +360,7 @@ SV *build_psgi_env(struct wsgi_request *wsgi_req) {
// cleanup handlers array
av = newAV();
if (!hv_store(env, "psgix.cleanup.handlers", 22, newRV_noinc((SV *)av ), 0)) goto clear;
// this call requires a bunch of syscalls, so it hurts performance
if (uperl.enable_psgix_io) {
SV *io = uwsgi_perl_obj_new_from_fd("IO::Socket", 10, wsgi_req->fd);
if (!hv_store(env, "psgix.io", 8, io, 0)) goto clear;
}
SV *pe = uwsgi_perl_obj_new("uwsgi::error", 12);
if (!hv_store(env, "psgi.errors", 11, pe, 0)) goto clear;
@@ -819,10 +764,10 @@ realstuff:
}
}
static uint64_t uwsgi_perl_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
static uint16_t uwsgi_perl_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
int i;
uint64_t ret = 0;
uint16_t ret = 0;
dSP;
ENTER;
@@ -843,11 +788,8 @@ static uint64_t uwsgi_perl_rpc(void *func, uint8_t argc, char **argv, uint16_t a
STRLEN rlen;
SV *response = POPs;
char *value = SvPV(response, rlen );
if (rlen > 0) {
*buffer = uwsgi_malloc(rlen);
memcpy(*buffer, value, rlen);
ret = rlen;
}
ret = UMIN(UMAX16-1, rlen);
memcpy(buffer, value, ret);
}
PUTBACK;
@@ -857,39 +799,6 @@ static uint64_t uwsgi_perl_rpc(void *func, uint8_t argc, char **argv, uint16_t a
return ret;
}
static void uwsgi_perl_hijack(void) {
if (uperl.shell_oneshot && uwsgi.workers[uwsgi.mywid].hijacked_count > 0) {
uwsgi.workers[uwsgi.mywid].hijacked = 0;
return;
}
if (uperl.shell && uwsgi.mywid == 1) {
uwsgi.workers[uwsgi.mywid].hijacked = 1;
uwsgi.workers[uwsgi.mywid].hijacked_count++;
// re-map stdin to stdout and stderr if we are logging to a file
if (uwsgi.logfile) {
if (dup2(0, 1) < 0) {
uwsgi_error("dup2()");
}
if (dup2(0, 2) < 0) {
uwsgi_error("dup2()");
}
}
if (uperl.shell[0] != 0) {
perl_eval_pv(uperl.shell, 0);
}
else {
perl_eval_pv("use Devel::REPL;my $repl = Devel::REPL->new;$repl->run;", 0);
}
if (uperl.shell_oneshot) {
exit(UWSGI_DE_HIJACKED_CODE);
}
exit(0);
}
}
struct uwsgi_plugin psgi_plugin = {
.name = "psgi",
@@ -906,8 +815,6 @@ struct uwsgi_plugin psgi_plugin = {
.mule = uwsgi_perl_mule,
.hijack_worker = uwsgi_perl_hijack,
.post_fork = uwsgi_perl_post_fork,
.request = uwsgi_perl_request,
.after_request = uwsgi_perl_after_request,
+38 -39
View File
@@ -22,13 +22,15 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
return UWSGI_OK;
}
if (wsgi_req->async_force_again) {
SvREFCNT_dec(chunk);
return UWSGI_AGAIN;
}
chitem = SvPV( chunk, hlen);
if (hlen <= 0) {
SvREFCNT_dec(chunk);
if (wsgi_req->async_force_again) {
return UWSGI_AGAIN;
}
SV *closed = uwsgi_perl_obj_call(wsgi_req->async_placeholder, "close");
if (closed) {
SvREFCNT_dec(closed);
@@ -74,16 +76,12 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
if (!headers) { uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;}
// generate headers
int headers_len = (int) av_len(headers);
for(i=0; i<=headers_len; i++) {
for(i=0; i<=av_len(headers); i++) {
hitem = av_fetch(headers,i,0);
if (!*hitem) {
uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;
}
chitem = SvPV(*hitem, hlen);
if (i+1 > headers_len) {
uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;
}
hitem = av_fetch(headers,i+1,0);
if (!*hitem) {
uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;
@@ -100,40 +98,41 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
}
if (!SvRV(*hitem)) { uwsgi_log("invalid PSGI response body\n") ; return UWSGI_OK; }
if (!SvROK(*hitem)) goto unsupported;
if (SvTYPE(SvRV(*hitem)) == SVt_PVGV || SvTYPE(SvRV(*hitem)) == SVt_PVHV || SvTYPE(SvRV(*hitem)) == SVt_PVMG) {
// check for fileno() method, IO class or GvIO
if (uwsgi_perl_obj_can(*hitem, "fileno", 6) || uwsgi_perl_obj_isa(*hitem, "IO") || (uwsgi_perl_obj_isa(*hitem, "GLOB") && GvIO(SvRV(*hitem))) ) {
SV *fn = uwsgi_perl_obj_call(*hitem, "fileno");
if (fn) {
if (SvTYPE(fn) == SVt_IV && SvIV(fn) >= 0) {
wsgi_req->sendfile_fd = SvIV(fn);
SvREFCNT_dec(fn);
uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0);
// no need to close here as perl GC will do the close()
uwsgi_pl_check_write_errors {
// noop
// respond to fileno ?
if (uwsgi.async < 2) {
// check for fileno() method, IO class or GvIO
if (uwsgi_perl_obj_can(*hitem, "fileno", 6) || uwsgi_perl_obj_isa(*hitem, "IO") || (uwsgi_perl_obj_isa(*hitem, "GLOB") && GvIO(SvRV(*hitem))) ) {
SV *fn = uwsgi_perl_obj_call(*hitem, "fileno");
if (fn) {
if (SvTYPE(fn) == SVt_IV && SvIV(fn) >= 0) {
wsgi_req->sendfile_fd = SvIV(fn);
SvREFCNT_dec(fn);
uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0);
// no need to close here as perl GC will do the close()
uwsgi_pl_check_write_errors {
// noop
}
return UWSGI_OK;
}
return UWSGI_OK;
SvREFCNT_dec(fn);
}
SvREFCNT_dec(fn);
}
}
// check for path method
if (uwsgi_perl_obj_can(*hitem, "path", 4)) {
SV *p = uwsgi_perl_obj_call(*hitem, "path");
int fd = open(SvPV_nolen(p), O_RDONLY);
SvREFCNT_dec(p);
// the following function will close fd
uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
uwsgi_pl_check_write_errors {
// noop
// check for path method
if (uwsgi_perl_obj_can(*hitem, "path", 4)) {
SV *p = uwsgi_perl_obj_call(*hitem, "path");
int fd = open(SvPV_nolen(p), O_RDONLY);
SvREFCNT_dec(p);
// the following function will close fd
uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
uwsgi_pl_check_write_errors {
// noop
}
return UWSGI_OK;
}
return UWSGI_OK;
}
for(;;) {
@@ -146,12 +145,13 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
}
chitem = SvPV( chunk, hlen);
if (uwsgi.async > 1 && wsgi_req->async_force_again) {
SvREFCNT_dec(chunk);
wsgi_req->async_placeholder = (SV *) *hitem;
return UWSGI_AGAIN;
}
if (hlen <= 0) {
SvREFCNT_dec(chunk);
if (uwsgi.async > 1 && wsgi_req->async_force_again) {
wsgi_req->async_placeholder = (SV *) *hitem;
return UWSGI_AGAIN;
}
break;
}
@@ -190,7 +190,6 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
}
else {
unsupported:
uwsgi_log("unsupported response body type: %d\n", SvTYPE(SvRV(*hitem)));
}
+3 -370
View File
@@ -324,7 +324,7 @@ XS(XS_call) {
dXSARGS;
char *func;
uint64_t size = 0;
uint16_t size = 0;
int i;
char *argv[256];
uint16_t argvs[256];
@@ -351,41 +351,6 @@ XS(XS_call) {
XSRETURN_UNDEF;
}
XS(XS_rpc) {
dXSARGS;
char *node;
char *func;
uint64_t size = 0;
int i;
char *argv[256];
uint16_t argvs[256];
STRLEN arg_len;
psgi_check_args(2);
node = SvPV_nolen(ST(0));
func = SvPV_nolen(ST(1));
for(i=0;i<(items-2);i++) {
argv[i] = SvPV(ST(i+2), arg_len);
argvs[i] = arg_len;
}
// response must be always freed
char *response = uwsgi_do_rpc(node, func, items-2, argv, argvs, &size);
if (response) {
ST(0) = newSVpv(response, size);
sv_2mortal(ST(0));
free(response);
XSRETURN(1);
}
XSRETURN_UNDEF;
}
XS(XS_suspend) {
@@ -439,20 +404,9 @@ XS(XS_i_am_the_lord) {
}
XSRETURN_NO;
}
#endif
XS(XS_connection_fd) {
dXSARGS;
psgi_check_args(0);
struct wsgi_request *wsgi_req = current_wsgi_req();
ST(0) = newSViv(wsgi_req->fd);
sv_2mortal(ST(0));
XSRETURN(1);
}
XS(XS_websocket_handshake) {
dXSARGS;
@@ -498,70 +452,6 @@ XS(XS_websocket_send) {
XSRETURN_UNDEF;
}
XS(XS_websocket_send_from_sharedarea) {
dXSARGS;
psgi_check_args(2);
int id = SvIV(ST(0));
uint64_t pos = SvIV(ST(1));
uint64_t len = 0;
if (items > 2) {
len = SvIV(ST(2));
}
struct wsgi_request *wsgi_req = current_wsgi_req();
if (uwsgi_websocket_send_from_sharedarea(wsgi_req, id, pos, len)) {
croak("unable to send websocket message from sharedarea");
}
XSRETURN_UNDEF;
}
XS(XS_websocket_send_binary) {
dXSARGS;
char *message = NULL;
STRLEN message_len = 0;
psgi_check_args(1);
message = SvPV(ST(0), message_len);
struct wsgi_request *wsgi_req = current_wsgi_req();
if (uwsgi_websocket_send_binary(wsgi_req, message, message_len)) {
croak("unable to send websocket binary message");
}
XSRETURN_UNDEF;
}
XS(XS_websocket_send_binary_from_sharedarea) {
dXSARGS;
psgi_check_args(2);
int id = SvIV(ST(0));
uint64_t pos = SvIV(ST(1));
uint64_t len = 0;
if (items > 2) {
len = SvIV(ST(2));
}
struct wsgi_request *wsgi_req = current_wsgi_req();
if (uwsgi_websocket_send_binary_from_sharedarea(wsgi_req, id, pos, len)) {
croak("unable to send websocket binary message from sharedarea");
}
XSRETURN_UNDEF;
}
XS(XS_websocket_recv) {
dXSARGS;
@@ -634,243 +524,7 @@ XS(XS_add_rb_timer) {
XSRETURN(1);
}
XS(XS_metric_inc) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_inc(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_dec) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_dec(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_mul) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_mul(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_div) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_div(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_set) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 0;
psgi_check_args(2);
metric = SvPV(ST(0), metric_len);
value = (int64_t) SvIV(ST(1));
if (uwsgi_metric_set(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_get) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
ST(0) = newSViv(uwsgi_metric_get(metric, NULL));
sv_2mortal(ST(0));
XSRETURN(1);
}
XS(XS_sharedarea_wait) {
dXSARGS;
int id;
int freq = 0;
int timeout = 0;
psgi_check_args(1);
id = SvIV(ST(0));
if (items > 1) {
freq = SvIV(ST(1));
}
if (uwsgi_sharedarea_wait(id, freq, timeout)) {
croak("unable to wait for sharedarea %d", id);
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_sharedarea_read) {
dXSARGS;
int id;
uint64_t pos;
uint64_t len = 0;
psgi_check_args(2);
id = SvIV(ST(0));
pos = SvIV(ST(1));
if (items > 2) {
len = SvIV(ST(2));
}
else {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) {
croak("unable to read from sharedarea %d", id);
XSRETURN_UNDEF;
}
len = (sa->max_pos+1)-pos;
}
char *buf = uwsgi_malloc(len);
int64_t rlen = uwsgi_sharedarea_read(id, pos, buf, len);
if (rlen < 0) {
free(buf);
croak("unable to read from sharedarea %d", id);
XSRETURN_UNDEF;
}
ST(0) = sv_newmortal();
sv_usepvn(ST(0), buf, rlen);
XSRETURN(1);
}
XS(XS_sharedarea_readfast) {
dXSARGS;
int id;
uint64_t pos;
uint64_t len = 0;
psgi_check_args(3);
id = SvIV(ST(0));
pos = SvIV(ST(1));
char *buf = SvPV_nolen(ST(2));
if (items > 3) {
len = SvIV(ST(3));
}
if (uwsgi_sharedarea_read(id, pos, buf, len)) {
croak("unable to (fast) read from sharedarea %d", id);
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_sharedarea_write) {
dXSARGS;
int id;
uint64_t pos;
STRLEN vallen;
psgi_check_args(3);
id = SvIV(ST(0));
pos = SvIV(ST(1));
char *value = SvPV(ST(2), vallen);
if (uwsgi_sharedarea_write(id, pos, value, vallen)) {
croak("unable to write to sharedarea %d", id);
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_chunked_read) {
dXSARGS;
int timeout = 0;
size_t len = 0;
psgi_check_args(0);
if (items > 0) {
timeout = SvIV(ST(0));
}
struct wsgi_request *wsgi_req = current_wsgi_req();
char *chunk = uwsgi_chunked_read(wsgi_req, &len, timeout, 0);
if (!chunk) {
croak("unable to receive chunked part");
XSRETURN_UNDEF;
}
ST(0) = newSVpv(chunk, len);
sv_2mortal(ST(0));
XSRETURN(1);
}
XS(XS_chunked_read_nb) {
dXSARGS;
size_t len = 0;
psgi_check_args(0);
struct wsgi_request *wsgi_req = current_wsgi_req();
char *chunk = uwsgi_chunked_read(wsgi_req, &len, 0, 1);
if (!chunk) {
if (uwsgi_is_again()) XSRETURN_UNDEF;
croak("unable to receive chunked part");
XSRETURN_UNDEF;
}
ST(0) = newSVpv(chunk, len);
sv_2mortal(ST(0));
XSRETURN(1);
}
void init_perl_embedded_module() {
psgi_xs(reload);
@@ -882,7 +536,6 @@ void init_perl_embedded_module() {
psgi_xs(cache_clear);
psgi_xs(call);
psgi_xs(rpc);
psgi_xs(wait_fd_read);
psgi_xs(wait_fd_write);
psgi_xs(async_sleep);
@@ -896,17 +549,11 @@ void init_perl_embedded_module() {
#ifdef UWSGI_SSL
psgi_xs(i_am_the_lord);
#endif
psgi_xs(connection_fd);
psgi_xs(alarm);
psgi_xs(websocket_handshake);
psgi_xs(websocket_recv);
psgi_xs(websocket_recv_nb);
psgi_xs(websocket_send);
psgi_xs(websocket_send_from_sharedarea);
psgi_xs(websocket_send_binary);
psgi_xs(websocket_send_binary_from_sharedarea);
psgi_xs(postfork);
psgi_xs(atexit);
@@ -914,19 +561,5 @@ void init_perl_embedded_module() {
psgi_xs(add_rb_timer);
psgi_xs(set_user_harakiri);
psgi_xs(metric_inc);
psgi_xs(metric_dec);
psgi_xs(metric_mul);
psgi_xs(metric_div);
psgi_xs(metric_get);
psgi_xs(metric_set);
psgi_xs(chunked_read);
psgi_xs(chunked_read_nb);
psgi_xs(sharedarea_read);
psgi_xs(sharedarea_readfast);
psgi_xs(sharedarea_write);
psgi_xs(sharedarea_wait);
}
-1
View File
@@ -149,7 +149,6 @@ static void *uwsgi_pty_loop(void *arg) {
if (rlen == 0) exit(1);
if (rlen < 0) {
uwsgi_error("uwsgi_pty_loop()/read()");
continue;
}
if (upty.log && upty.original_log >= 0) {
if (write(upty.original_log, buf, rlen) != rlen) {
+2 -3
View File
@@ -274,10 +274,10 @@ static int uwsgi_pypy_signal_handler(uint8_t sig, void *handler) {
return 0;
}
static uint64_t uwsgi_pypy_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
static uint16_t uwsgi_pypy_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
int iargvs[UMAX8];
int i;
int (*pypy_func)(int, char **, int*, char **) = (int (*)(int, char **, int*, char **)) func;
int (*pypy_func)(int, char **, int*, char *) = (int (*)(int, char **, int*, char *)) func;
// we convert 16bit to int
for(i=0;i<argc;i++) {
iargvs[i] = (int) argvs[i];
@@ -313,7 +313,6 @@ static void uwsgi_pypy_onload() {
#ifdef UWSGI_PYPY_HOME
upypy.home = UWSGI_PYPY_HOME;
#endif
uwsgi.has_threads = 1;
}
static int uwsgi_pypy_mule(char *opt) {
+5 -21
View File
@@ -172,8 +172,6 @@ const char *uwsgi_pypy_version;
char *uwsgi_binary_path();
void *uwsgi_malloc(size_t);
int uwsgi_response_prepare_headers(struct wsgi_request *, char *, size_t);
int uwsgi_response_add_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
int uwsgi_response_write_body_do(struct wsgi_request *, char *, size_t);
@@ -188,7 +186,7 @@ int uwsgi_is_again();
int uwsgi_register_rpc(char *, struct uwsgi_plugin *, uint8_t, void *);
int uwsgi_register_signal(uint8_t, char *, void *, uint8_t);
char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint64_t *);
char *uwsgi_do_rpc(char *, char *, uint8_t, char **, uint16_t *, uint16_t *);
void uwsgi_set_processname(char *);
int uwsgi_signal_send(int, uint8_t);
@@ -237,13 +235,6 @@ int uwsgi_ready_fd(struct wsgi_request *);
void set_user_harakiri(int);
int uwsgi_metric_set(char *, char *, int64_t);
int uwsgi_metric_inc(char *, char *, int64_t);
int uwsgi_metric_dec(char *, char *, int64_t);
int uwsgi_metric_mul(char *, char *, int64_t);
int uwsgi_metric_div(char *, char *, int64_t);
int64_t uwsgi_metric_get(char *, char *);
%s
''' % ('\n'.join(uwsgi_cdef), hooks)
@@ -492,16 +483,15 @@ class uwsgi_pypy_RPC(object):
for i in range(0, argc):
pargs.append(ffi.string(argv[i], argvs[i]))
response = self.func(*pargs)
if len(response) > 0:
buf[0] = lib.uwsgi_malloc(len(response))
dst = ffi.buffer(buf[0], len(response))
if len(response) > 0 and len(response) <= 65535:
dst = ffi.buffer(buf, 65536)
dst[:len(response)] = response
return len(response)
def uwsgi_pypy_uwsgi_register_rpc(name, func, argc=0):
rpc_func = uwsgi_pypy_RPC(func)
cb = ffi.callback("int(int, char*[], int[], char**)", rpc_func)
cb = ffi.callback("int(int, char*[], int[], char*)", rpc_func)
uwsgi_gc.append(cb)
if lib.uwsgi_register_rpc(ffi.new("char[]", name), ffi.addressof(lib.pypy_plugin), argc, cb) < 0:
raise Exception("unable to register rpc func %s" % name)
@@ -511,7 +501,7 @@ def uwsgi_pypy_rpc(node, func, *args):
argc = 0
argv = ffi.new('char*[256]')
argvs = ffi.new('uint16_t[256]')
rsize = ffi.new('uint64_t*')
rsize = ffi.new('uint16_t*')
for arg in args:
if argc >= 255:
@@ -544,12 +534,6 @@ uwsgi.call = uwsgi_pypy_call
uwsgi.signal = lambda x: lib.uwsgi_signal_send(lib.uwsgi.signal_socket, x)
uwsgi.metric_get = lambda x: lib.uwsgi_metric_get(x, ffi.NULL)
uwsgi.metric_set = lambda x, y: lib.uwsgi_metric_set(x, ffi.NULL, y)
uwsgi.metric_inc = lambda x, y=1: lib.uwsgi_metric_inc(x, ffi.NULL, y)
uwsgi.metric_dec = lambda x, y=1: lib.uwsgi_metric_dec(x, ffi.NULL, y)
uwsgi.metric_mul = lambda x, y=1: lib.uwsgi_metric_mul(x, ffi.NULL, y)
uwsgi.metric_div = lambda x, y=1: lib.uwsgi_metric_div(x, ffi.NULL, y)
def uwsgi_pypy_uwsgi_cache_get(key, cache=ffi.NULL):
vallen = ffi.new('uint64_t*')
+5 -12
View File
@@ -167,7 +167,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
PyThreadState_Swap(wi->interpreter);
init_pyargv();
// we need to initialize an embedded module for every interpreter
// we need to inizialize an embedded module for every interpreter
init_uwsgi_embedded_module();
init_uwsgi_vars();
@@ -205,7 +205,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
app_list = PyDict_Keys(applications);
multiapp = PyList_Size(app_list);
if (multiapp < 1) {
uwsgi_log("you have to define at least one app in the applications dictionary\n");
uwsgi_log("you have to define at least one app in the apllications dictionary\n");
goto doh;
}
@@ -227,10 +227,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
PyObject *callables_dict = get_uwsgi_pydict((char *)arg1);
if (callables_dict) {
wi->callable = PyDict_GetItem(callables_dict, (PyObject *)wi->callable);
if (!wi->callable) {
uwsgi_log("skipping broken app %s\n", wsgi_req->appid);
goto multiapp;
}
}
}
}
@@ -340,11 +336,9 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
const char *default_app = "";
if (!uwsgi.no_default_app) {
if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
default_app = " (default app)" ;
uwsgi.default_app = id;
}
if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
default_app = " (default app)" ;
uwsgi.default_app = id;
}
wi->started_at = now;
@@ -363,7 +357,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
uwsgi_apps_cnt++;
multiapp:
if (multiapp > 1) {
for(i=1;i<multiapp;i++) {
PyObject *app_mnt = PyList_GetItem(app_list, i);
+4 -20
View File
@@ -164,10 +164,6 @@ struct uwsgi_option uwsgi_python_options[] = {
{"python-raw", required_argument, 0, "load a python file for managing raw requests", uwsgi_opt_set_str, &up.raw, 0},
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
{"py-sharedarea", required_argument, 0, "create a sharedarea from a python bytearray object of the specified size", uwsgi_opt_add_string_list, &up.sharedarea, 0},
#endif
{0, 0, 0, 0, 0, 0, 0},
};
@@ -267,17 +263,6 @@ pep405:
up.swap_ts = simple_swap_ts;
up.reset_ts = simple_reset_ts;
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, up.sharedarea) {
uint64_t len = uwsgi_n64(usl->value);
PyObject *obj = PyByteArray_FromStringAndSize(NULL, len);
char *storage = PyByteArray_AsString(obj);
Py_INCREF(obj);
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_init_ptr(storage, len);
sa->obj = obj;
}
#endif
uwsgi_log_initial("Python main interpreter initialized at %p\n", up.main_thread);
@@ -848,7 +833,7 @@ void init_uwsgi_embedded_module() {
init_uwsgi_module_spooler(new_uwsgi_module);
}
if (uwsgi.sharedareas) {
if (uwsgi.sharedareasize > 0 && uwsgi.sharedarea) {
init_uwsgi_module_sharedarea(new_uwsgi_module);
}
@@ -1537,7 +1522,7 @@ clear:
return -1;
}
uint64_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
UWSGI_GET_GIL;
@@ -1561,9 +1546,8 @@ uint64_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[
if (PyString_Check(ret)) {
rv = PyString_AsString(ret);
rl = PyString_Size(ret);
if (rl > 0) {
*buffer = uwsgi_malloc(rl);
memcpy(*buffer, rv, rl);
if (rl <= 65536) {
memcpy(buffer, rv, rl);
Py_DECREF(ret);
UWSGI_RELEASE_GIL;
return rl;
+155 -340
View File
@@ -265,7 +265,7 @@ PyObject *py_uwsgi_add_file_monitor(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_call(PyObject * self, PyObject * args) {
char *func;
uint64_t size = 0;
uint16_t size = 0;
PyObject *py_func;
int argc = PyTuple_Size(args);
int i;
@@ -331,7 +331,7 @@ PyObject *py_uwsgi_rpc_list(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
char *node = NULL, *func;
uint64_t size = 0;
uint16_t size = 0;
PyObject *py_node, *py_func;
int argc = PyTuple_Size(args);
@@ -1066,27 +1066,6 @@ PyObject *py_uwsgi_websocket_send(PyObject * self, PyObject * args) {
return Py_None;
}
PyObject *py_uwsgi_websocket_send_binary(PyObject * self, PyObject * args) {
char *message = NULL;
Py_ssize_t message_len = 0;
if (!PyArg_ParseTuple(args, "s#:websocket_send_binary", &message, &message_len)) {
return NULL;
}
struct wsgi_request *wsgi_req = py_current_wsgi_req();
UWSGI_RELEASE_GIL
int ret = uwsgi_websocket_send_binary(wsgi_req, message, message_len);
UWSGI_GET_GIL
if (ret < 0) {
return PyErr_Format(PyExc_IOError, "unable to send websocket binary message");
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_chunked_read(PyObject * self, PyObject * args) {
int timeout = 0;
if (!PyArg_ParseTuple(args, "|i:chunked_read", &timeout)) {
@@ -1447,228 +1426,222 @@ PyObject *py_uwsgi_extract(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_sharedarea_inc64(PyObject * self, PyObject * args) {
int id;
PyObject *py_uwsgi_sharedarea_inclong(PyObject * self, PyObject * args) {
uint64_t pos = 0;
int64_t value = 1;
uint64_t value = 1;
uint64_t current_value = 0;
if (!PyArg_ParseTuple(args, "il|l:sharedarea_inc64", &id, &pos, &value)) {
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "l|l:sharedarea_inclong", &pos, &value)) {
return NULL;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_inc64(id, pos, value);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_inc64()");
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_RELEASE_GIL
Py_INCREF(Py_None);
return Py_None;
uwsgi_wlock(uwsgi.sa_lock);
memcpy(&current_value, uwsgi.sharedarea + pos, 8);
value = current_value + value;
memcpy(uwsgi.sharedarea + pos, &value, 8);
uwsgi_rwunlock(uwsgi.sa_lock);
UWSGI_GET_GIL
return PyInt_FromLong(value);
}
PyObject *py_uwsgi_sharedarea_write64(PyObject * self, PyObject * args) {
int id;
PyObject *py_uwsgi_sharedarea_writelong(PyObject * self, PyObject * args) {
uint64_t pos = 0;
int64_t value = 0;
uint64_t value = 0;
if (!PyArg_ParseTuple(args, "ill:sharedarea_write64", &id, &pos, &value)) {
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "ll:sharedarea_writelong", &pos, &value)) {
return NULL;
}
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_write64(id, pos, &value);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write64()");
}
uwsgi_wlock(uwsgi.sa_lock);
memcpy(uwsgi.sharedarea + pos, &value, 8);
uwsgi_rwunlock(uwsgi.sa_lock);
UWSGI_GET_GIL
return PyInt_FromLong(value);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_sharedarea_write(PyObject * self, PyObject * args) {
int id;
uint64_t pos = 0;
char *value;
Py_ssize_t value_len = 0;
if (!PyArg_ParseTuple(args, "ils#:sharedarea_write", &id, &pos, &value, &value_len)) {
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "ls#:sharedarea_write", &pos, &value, &value_len)) {
return NULL;
}
if (pos + value_len >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_write(id, pos, value, value_len);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write()");
}
uwsgi_wlock(uwsgi.sa_lock);
Py_INCREF(Py_None);
return Py_None;
}
memcpy(uwsgi.sharedarea + pos, value, value_len);
PyObject *py_uwsgi_sharedarea_update(PyObject * self, PyObject * args) {
int id;
if (!PyArg_ParseTuple(args, "i:sharedarea_update", &id)) {
return NULL;
}
uwsgi_rwunlock(uwsgi.sa_lock);
if (uwsgi_sharedarea_update(id)) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_update()");
}
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
return PyInt_FromLong(value_len);
}
PyObject *py_uwsgi_sharedarea_rlock(PyObject * self, PyObject * args) {
int id;
if (!PyArg_ParseTuple(args, "i:sharedarea_rlock", &id)) {
return NULL;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_rlock(id);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_rlock()");
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_sharedarea_wlock(PyObject * self, PyObject * args) {
int id;
if (!PyArg_ParseTuple(args, "i:sharedarea_wlock", &id)) {
return NULL;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_wlock(id);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_wlock()");
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_sharedarea_unlock(PyObject * self, PyObject * args) {
int id;
if (!PyArg_ParseTuple(args, "i:sharedarea_unlock", &id)) {
return NULL;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_unlock(id);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_unlock()");
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_sharedarea_write8(PyObject * self, PyObject * args) {
int id;
PyObject *py_uwsgi_sharedarea_writebyte(PyObject * self, PyObject * args) {
uint64_t pos = 0;
int8_t value;
char value;
if (!PyArg_ParseTuple(args, "ilb:sharedarea_write8", &id, &pos, &value)) {
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "lb:sharedarea_writebyte", &pos, &value)) {
return NULL;
}
if (pos >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_write8(id, pos, &value);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write8()");
}
uwsgi_wlock(uwsgi.sa_lock);
Py_INCREF(Py_None);
return Py_None;
uwsgi.sharedarea[pos] = value;
uwsgi_rwunlock(uwsgi.sa_lock);
UWSGI_GET_GIL
return PyInt_FromLong(value);
}
PyObject *py_uwsgi_sharedarea_read64(PyObject * self, PyObject * args) {
int id;
PyObject *py_uwsgi_sharedarea_readlong(PyObject * self, PyObject * args) {
uint64_t pos = 0;
int64_t value;
uint64_t value;
if (!PyArg_ParseTuple(args, "il:sharedarea_read64", &id, &pos)) {
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "l:sharedarea_readlong", &pos)) {
return NULL;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_read64(id, pos, &value);
UWSGI_GET_GIL
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read64()");
}
UWSGI_RELEASE_GIL
uwsgi_wlock(uwsgi.sa_lock);
memcpy(&value, uwsgi.sharedarea + pos, 8);
uwsgi_rwunlock(uwsgi.sa_lock);
UWSGI_GET_GIL
return PyLong_FromLong(value);
}
PyObject *py_uwsgi_sharedarea_read8(PyObject * self, PyObject * args) {
int id;
uint64_t pos = 0;
int8_t byte;
if (!PyArg_ParseTuple(args, "il:sharedarea_read8", &id, &pos)) {
PyObject *py_uwsgi_sharedarea_readbyte(PyObject * self, PyObject * args) {
uint64_t pos = 0;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "l:sharedarea_readbyte", &pos)) {
return NULL;
}
if (pos >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_RELEASE_GIL
int ret = uwsgi_sharedarea_read8(id, pos, &byte);
UWSGI_GET_GIL
if (ret) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read8()");
}
uwsgi_wlock(uwsgi.sa_lock);
char value = uwsgi.sharedarea[pos];
uwsgi_rwunlock(uwsgi.sa_lock);
UWSGI_GET_GIL
return PyInt_FromLong(value);
return PyInt_FromLong(byte);
}
PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) {
int id;
uint64_t pos = 0;
uint64_t len = 0;
uint64_t len = 1;
if (!PyArg_ParseTuple(args, "il|l:sharedarea_read", &id, &pos, &len)) {
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "l|l:sharedarea_read", &pos, &len)) {
return NULL;
}
if (!len) {
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
if (!sa) {
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read()");
}
len = (sa->max_pos+1)-pos;
if (pos + len >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
PyObject *ret = PyString_FromStringAndSize(NULL, len);
@@ -1679,51 +1652,18 @@ PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) {
#endif
UWSGI_RELEASE_GIL
int64_t rlen = uwsgi_sharedarea_read(id, pos, storage, len);
UWSGI_GET_GIL
if (rlen < 0) {
Py_DECREF(ret);
return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read()");
}
uwsgi_wlock(uwsgi.sa_lock);
// HACK: we are safe as rlen can only be lower or equal to len
Py_SIZE(ret) = rlen;
memcpy(storage, uwsgi.sharedarea + pos, len);
uwsgi_rwunlock(uwsgi.sa_lock);
UWSGI_GET_GIL
return ret;
}
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
#ifndef HAS_NOT_PyMemoryView_FromBuffer
PyObject *py_uwsgi_sharedarea_memoryview(PyObject * self, PyObject * args) {
int id;
if (!PyArg_ParseTuple(args, "i:sharedarea_memoryview", &id)) {
return NULL;
}
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) {
return PyErr_Format(PyExc_ValueError, "cannot get a memoryview object from sharedarea %d", id);
}
Py_buffer info;
if (PyBuffer_FillInfo(&info, NULL, sa->area, sa->max_pos+1, 0, PyBUF_CONTIG) < 0)
return PyErr_Format(PyExc_ValueError, "cannot get a memoryview object from sharedarea %d", id);
return PyMemoryView_FromBuffer(&info);
}
#endif
PyObject *py_uwsgi_sharedarea_object(PyObject * self, PyObject * args) {
int id;
if (!PyArg_ParseTuple(args, "i:sharedarea_object", &id)) {
return NULL;
}
struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
if (!sa) {
return PyErr_Format(PyExc_ValueError, "cannot get an object from sharedarea %d", id);
}
return (PyObject *) sa->obj;
}
#endif
PyObject *py_uwsgi_spooler_freq(PyObject * self, PyObject * args) {
if (!PyArg_ParseTuple(args, "i", &uwsgi.shared->spooler_frequency)) {
@@ -2579,11 +2519,11 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"ready", py_uwsgi_ready, METH_VARARGS, ""},
{"set_user_harakiri", py_uwsgi_set_user_harakiri, METH_VARARGS, ""},
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
{"websocket_recv", py_uwsgi_websocket_recv, METH_VARARGS, ""},
{"websocket_recv_nb", py_uwsgi_websocket_recv_nb, METH_VARARGS, ""},
{"websocket_send", py_uwsgi_websocket_send, METH_VARARGS, ""},
{"websocket_send_binary", py_uwsgi_websocket_send_binary, METH_VARARGS, ""},
{"websocket_handshake", py_uwsgi_websocket_handshake, METH_VARARGS, ""},
{"chunked_read", py_uwsgi_chunked_read, METH_VARARGS, ""},
@@ -2598,25 +2538,11 @@ static PyMethodDef uwsgi_advanced_methods[] = {
static PyMethodDef uwsgi_sa_methods[] = {
{"sharedarea_read", py_uwsgi_sharedarea_read, METH_VARARGS, ""},
{"sharedarea_write", py_uwsgi_sharedarea_write, METH_VARARGS, ""},
{"sharedarea_readbyte", py_uwsgi_sharedarea_read8, METH_VARARGS, ""},
{"sharedarea_writebyte", py_uwsgi_sharedarea_write8, METH_VARARGS, ""},
{"sharedarea_read8", py_uwsgi_sharedarea_read8, METH_VARARGS, ""},
{"sharedarea_write8", py_uwsgi_sharedarea_write8, METH_VARARGS, ""},
{"sharedarea_readlong", py_uwsgi_sharedarea_read64, METH_VARARGS, ""},
{"sharedarea_writelong", py_uwsgi_sharedarea_write64, METH_VARARGS, ""},
{"sharedarea_read64", py_uwsgi_sharedarea_read64, METH_VARARGS, ""},
{"sharedarea_write64", py_uwsgi_sharedarea_write64, METH_VARARGS, ""},
{"sharedarea_inclong", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""},
{"sharedarea_inc64", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""},
{"sharedarea_rlock", py_uwsgi_sharedarea_rlock, METH_VARARGS, ""},
{"sharedarea_wlock", py_uwsgi_sharedarea_wlock, METH_VARARGS, ""},
{"sharedarea_unlock", py_uwsgi_sharedarea_unlock, METH_VARARGS, ""},
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
#ifndef HAS_NOT_PyMemoryView_FromBuffer
{"sharedarea_memoryview", py_uwsgi_sharedarea_memoryview, METH_VARARGS, ""},
#endif
{"sharedarea_object", py_uwsgi_sharedarea_object, METH_VARARGS, ""},
#endif
{"sharedarea_readbyte", py_uwsgi_sharedarea_readbyte, METH_VARARGS, ""},
{"sharedarea_writebyte", py_uwsgi_sharedarea_writebyte, METH_VARARGS, ""},
{"sharedarea_readlong", py_uwsgi_sharedarea_readlong, METH_VARARGS, ""},
{"sharedarea_writelong", py_uwsgi_sharedarea_writelong, METH_VARARGS, ""},
{"sharedarea_inclong", py_uwsgi_sharedarea_inclong, METH_VARARGS, ""},
{NULL, NULL},
};
@@ -3243,111 +3169,6 @@ static PyMethodDef uwsgi_queue_methods[] = {
{NULL, NULL},
};
PyObject *py_uwsgi_metric_inc(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_inc", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_inc(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_dec(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_dec", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_dec(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_mul(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_mul", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_mul(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_div(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_div", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_div(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_set(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_set", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_set(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_get(PyObject * self, PyObject * args) {
char *key;
if (!PyArg_ParseTuple(args, "s:metric_get", &key)) return NULL;
UWSGI_RELEASE_GIL
int64_t value = uwsgi_metric_get(key, NULL);
UWSGI_GET_GIL
return PyLong_FromLongLong(value);
}
static PyMethodDef uwsgi_metrics_methods[] = {
{"metric_inc", py_uwsgi_metric_inc, METH_VARARGS, ""},
{"metric_dec", py_uwsgi_metric_dec, METH_VARARGS, ""},
{"metric_mul", py_uwsgi_metric_mul, METH_VARARGS, ""},
{"metric_div", py_uwsgi_metric_div, METH_VARARGS, ""},
{"metric_get", py_uwsgi_metric_get, METH_VARARGS, ""},
{"metric_set", py_uwsgi_metric_set, METH_VARARGS, ""},
{NULL, NULL},
};
void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) {
@@ -3383,12 +3204,6 @@ void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) {
Py_DECREF(func);
}
for (uwsgi_function = uwsgi_metrics_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
Py_DECREF(func);
}
}
void init_uwsgi_module_cache(PyObject * current_uwsgi_module) {
-12
View File
@@ -14,10 +14,6 @@
#define UWSGI_PYTHON_OLD
#endif
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
#define HAS_NOT_PyMemoryView_FromBuffer
#endif
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
#define HAS_NOT_PyFrame_GetLineNumber
#endif
@@ -34,12 +30,6 @@
#define PYTHREE
#endif
#if (PY_VERSION_HEX < 0x02060000)
#ifndef Py_SIZE
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
#endif
#endif
#define UWSGI_GET_GIL up.gil_get();
#define UWSGI_RELEASE_GIL up.gil_release();
@@ -195,8 +185,6 @@ struct uwsgi_python {
char *raw;
PyObject *raw_callable;
struct uwsgi_string_list *sharedarea;
};
+2 -12
View File
@@ -18,15 +18,13 @@ extern PyTypeObject uwsgi_InputType;
*/
int uwsgi_python_send_body(struct wsgi_request *wsgi_req, PyObject *chunk) {
char *content = NULL;
size_t content_len = 0;
if (!up.wsgi_accept_buffer && !wsgi_req->is_raw) goto strict;
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
Py_buffer pbuf;
int has_buffer = 0;
#endif
char *content = NULL;
size_t content_len = 0;
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
if (PyObject_CheckBuffer(chunk)) {
if (!PyObject_GetBuffer(chunk, &pbuf, PyBUF_SIMPLE)) {
@@ -38,18 +36,10 @@ int uwsgi_python_send_body(struct wsgi_request *wsgi_req, PyObject *chunk) {
}
#else
if (PyObject_CheckReadBuffer(chunk)) {
#ifdef UWSGI_PYTHON_OLD
int buffer_len = 0;
if (!PyObject_AsCharBuffer(chunk, (const char **) &content, &buffer_len)) {
#else
if (!PyObject_AsCharBuffer(chunk, (const char **) &content, (Py_ssize_t *) &content_len)) {
#endif
PyErr_Clear();
goto found;
}
#ifdef UWSGI_PYTHON_OLD
content_len = buffer_len;
#endif
}
#endif
+1 -97
View File
@@ -7,88 +7,6 @@ extern struct uwsgi_plugin rack_plugin;
#define uwsgi_rack_api(x, y, z) rb_define_module_function(rb_uwsgi_embedded, x, y, z)
static VALUE rack_uwsgi_metric_get(VALUE *class, VALUE key) {
Check_Type(key, T_STRING);
int64_t value = uwsgi_metric_get(RSTRING_PTR(key), NULL);
return LONG2NUM(value);
}
static VALUE rack_uwsgi_metric_set(VALUE *class, VALUE key, VALUE val) {
Check_Type(key, T_STRING);
Check_Type(val, T_FIXNUM); // should be T_BIGNUM...
if (uwsgi_metric_set(RSTRING_PTR(key), NULL, NUM2LONG(val) )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_inc(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_inc(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_dec(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_dec(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_mul(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_mul(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_div(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_div(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_warning(VALUE *class, VALUE rbmessage) {
Check_Type(rbmessage, T_STRING);
@@ -141,11 +59,6 @@ static VALUE rack_uwsgi_i_am_the_lord(VALUE *class, VALUE legion_name) {
}
#endif
static VALUE rack_uwsgi_connection_fd(VALUE *class) {
struct wsgi_request *wsgi_req = current_wsgi_req();
return INT2NUM(wsgi_req->fd);
}
static VALUE rack_uwsgi_setprocname(VALUE *class, VALUE rbname) {
@@ -805,7 +718,7 @@ static VALUE uwsgi_ruby_signal_registered(VALUE *class, VALUE signum) {
static VALUE uwsgi_ruby_do_rpc(int argc, VALUE *rpc_argv, VALUE *class) {
char *node = NULL, *func;
uint64_t size = 0;
uint16_t size = 0;
char *argv[256];
uint16_t argvs[256];
@@ -1171,8 +1084,6 @@ void uwsgi_rack_init_api() {
#ifdef UWSGI_SSL
uwsgi_rack_api("i_am_the_lord", rack_uwsgi_i_am_the_lord, 1);
#endif
uwsgi_rack_api("connection_fd", rack_uwsgi_connection_fd, 0);
uwsgi_rack_api("cache_get", rack_uwsgi_cache_get, -1);
@@ -1188,13 +1099,6 @@ void uwsgi_rack_init_api() {
uwsgi_rack_api("cache_clear", rack_uwsgi_cache_clear, -1);
uwsgi_rack_api("cache_clear!", rack_uwsgi_cache_clear_exc, -1);
uwsgi_rack_api("metric_get", rack_uwsgi_metric_get, 1);
uwsgi_rack_api("metric_set", rack_uwsgi_metric_set, 2);
uwsgi_rack_api("metric_inc", rack_uwsgi_metric_inc, -1);
uwsgi_rack_api("metric_dec", rack_uwsgi_metric_dec, -1);
uwsgi_rack_api("metric_mul", rack_uwsgi_metric_mul, -1);
uwsgi_rack_api("metric_div", rack_uwsgi_metric_div, -1);
VALUE uwsgi_rb_opt_hash = rb_hash_new();
int i;
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
+7 -4
View File
@@ -315,7 +315,7 @@ VALUE rack_call_rpc_handler(VALUE args) {
}
uint64_t uwsgi_ruby_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
uint16_t uwsgi_ruby_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
uint8_t i;
VALUE rb_args = rb_ary_new2(2);
@@ -343,9 +343,8 @@ uint64_t uwsgi_ruby_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[],
if (TYPE(ret) == T_STRING) {
rv = RSTRING_PTR(ret);
rl = RSTRING_LEN(ret);
if (rl > 0) {
*buffer = uwsgi_malloc(rl);
memcpy(*buffer, rv, rl);
if (rl <= 0xffff) {
memcpy(buffer, rv, rl);
return rl;
}
}
@@ -1107,6 +1106,7 @@ static void uwsgi_rack_hijack(void) {
uwsgi_error("dup2()");
}
}
int ret = -1;
int error = 0;
if (ur.rbshell[0] != 0) {
rb_eval_string(ur.rbshell);
@@ -1122,6 +1122,9 @@ static void uwsgi_rack_hijack(void) {
exit(UWSGI_DE_HIJACKED_CODE);
}
if (ret == 0) {
exit(UWSGI_QUIET_CODE);
}
exit(0);
}
-17
View File
@@ -37,7 +37,6 @@ struct uwsgi_rbthreads {
int rbthreads;
int (*orig_wait_write_hook) (int, int);
int (*orig_wait_read_hook) (int, int);
int (*orig_wait_milliseconds_hook) (int);
} urbts;
static struct uwsgi_option rbthreads_options[] = {
@@ -143,20 +142,6 @@ static int rbthreads_wait_fd_read(int fd, int timeout) {
return urbt.ret;
}
static void *rbthreads_wait_milliseconds_do(void *arg) {
struct uwsgi_rbthread *urbt = (struct uwsgi_rbthread *) arg;
urbt->ret = urbts.orig_wait_milliseconds_hook(urbt->timeout);
return NULL;
}
static int rbthreads_wait_milliseconds(int timeout) {
struct uwsgi_rbthread urbt;
urbt.timeout = timeout;
rb_thread_call_without_gvl(rbthreads_wait_milliseconds_do, &urbt, NULL, NULL);
return urbt.ret;
}
static void rbthreads_loop() {
struct uwsgi_plugin *rup = uwsgi_plugin_get("rack");
// disable init_thread warning
@@ -167,10 +152,8 @@ static void rbthreads_loop() {
// override read/write nb hooks
urbts.orig_wait_write_hook = uwsgi.wait_write_hook;
urbts.orig_wait_read_hook = uwsgi.wait_read_hook;
urbts.orig_wait_milliseconds_hook = uwsgi.wait_milliseconds_hook;
uwsgi.wait_write_hook = rbthreads_wait_fd_write;
uwsgi.wait_read_hook = rbthreads_wait_fd_read;
uwsgi.wait_milliseconds_hook = rbthreads_wait_milliseconds;
int i;
for(i=1;i<uwsgi.threads;i++) {
+1 -8
View File
@@ -57,8 +57,6 @@ struct uwsgi_router_cache_conf {
char *status_str;
int status;
char *no_offload;
char *no_cl;
};
// this is allocated for each transformation
@@ -191,9 +189,7 @@ static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_
if (expires) {
if (uwsgi_response_add_expires(wsgi_req, expires)) goto error;
}
if (!urcc->no_cl) {
if (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
}
if (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
if (wsgi_req->socket->can_offload && !ur->custom && !urcc->no_offload) {
if (!uwsgi_offload_request_memory_do(wsgi_req, value, valsize)) {
wsgi_req->via = UWSGI_VIA_OFFLOAD;
@@ -382,9 +378,6 @@ static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
"mime", &urcc->mime,
"name", &urcc->name,
"no_offload", &urcc->no_offload,
"no_content_length", &urcc->no_cl,
"no_cl", &urcc->no_cl,
"nocl", &urcc->no_cl,
NULL)) {
uwsgi_log("invalid route syntax: %s\n", args);
exit(1);
+1 -3
View File
@@ -56,8 +56,6 @@ static int uwsgi_routing_func_hash(struct wsgi_request *wsgi_req, struct uwsgi_r
// skip last semicolon
if (urhc->items[ilen-1] == ';') items--;
if (items < 1) return UWSGI_ROUTE_BREAK;
uint32_t hashed_result = h % items;
uint32_t found = 0;
char *value = urhc->items;
@@ -83,7 +81,7 @@ static int uwsgi_routing_func_hash(struct wsgi_request *wsgi_req, struct uwsgi_r
vallen = urhc->items_len;
}
// last item
else if (value != NULL) {
else {
vallen = (urhc->items + urhc->items_len) - value;
}
}

Some files were not shown because too many files have changed in this diff Show More