mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41bc23bb40 |
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[uwsgi]
|
||||
main_plugin = gccgo
|
||||
inherit = base
|
||||
@@ -1,3 +1,4 @@
|
||||
[uwsgi]
|
||||
main_plugin = glusterfs
|
||||
inherit = base
|
||||
matheval = false
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
[uwsgi]
|
||||
main_plugin = go
|
||||
inherit = base
|
||||
bin_name = libuwsgi.so
|
||||
as_shared_library = true
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
xml = true
|
||||
yaml = true
|
||||
json = true
|
||||
zeromq = true
|
||||
ssl = true
|
||||
pcre = true
|
||||
routing = true
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
xml = true
|
||||
yaml = true
|
||||
json = false
|
||||
zeromq = false
|
||||
ssl = true
|
||||
pcre = true
|
||||
routing = true
|
||||
|
||||
+37
-86
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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]);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,6 @@ void uwsgi_mule(int id) {
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_hooks_run(uwsgi.hook_as_mule, "as-mule", 1);
|
||||
uwsgi_mule_run();
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#include <uwsgi.h>
|
||||
#include "uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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() {
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
NAME='logzmq'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lzmq']
|
||||
|
||||
GCC_LIST = ['plugin']
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
NAME='matheval'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lmatheval']
|
||||
GCC_LIST = ['math']
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
NAME='mongrel2'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lzmq']
|
||||
|
||||
GCC_LIST = ['mongrel2']
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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*')
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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(¤t_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) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user