mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd3291b11f | ||
|
|
e5ac5d6352 | ||
|
|
403bd604e2 | ||
|
|
045d8947ae | ||
|
|
a9f2c71863 | ||
|
|
b504a1ebe8 | ||
|
|
f05ce0d2fc | ||
|
|
a2f3c716b1 | ||
|
|
2d7ca36f60 | ||
|
|
5370e535dd | ||
|
|
092767c29f | ||
|
|
4e119e6838 | ||
|
|
87ef444ea6 | ||
|
|
714be76f9b | ||
|
|
af0f0da8c2 | ||
|
|
8407372801 | ||
|
|
d19c4e84fc | ||
|
|
3342852a9a | ||
|
|
586a02d849 | ||
|
|
188dad744a | ||
|
|
6cf3bbea69 | ||
|
|
04736d371e | ||
|
|
cc9151f89e | ||
|
|
e13734ae6c | ||
|
|
cf62b03e33 | ||
|
|
b2f292c2da | ||
|
|
b96b6a24a6 | ||
|
|
b2a1237781 | ||
|
|
a48af2e226 | ||
|
|
33446c3179 | ||
|
|
242e01e37a | ||
|
|
41eba2b486 | ||
|
|
24763fdbd2 | ||
|
|
951cbf3eba | ||
|
|
8759b66206 | ||
|
|
93aacace5f | ||
|
|
8406fb12be | ||
|
|
6af3ea267e | ||
|
|
9ff37ce019 | ||
|
|
f4187680bd | ||
|
|
57b72ac17d | ||
|
|
5c64839734 | ||
|
|
e4de9a8bc7 | ||
|
|
689b4afb44 | ||
|
|
ceebaa7d9d | ||
|
|
0fa2c543ec | ||
|
|
519df88126 | ||
|
|
75b275591d | ||
|
|
2f901f08cb | ||
|
|
b041fe4473 | ||
|
|
f5d6cb65f9 | ||
|
|
9c94aedb29 |
@@ -1,5 +1,33 @@
|
||||
*** current ***
|
||||
|
||||
* 1.4.1
|
||||
|
||||
- fixed typos in corerouter plugins
|
||||
- fixed offloading when the number of threads is higher than 1
|
||||
- fixed static_maps for non-existent paths
|
||||
- fixed uwsgi_connect() on modern Linux systems to reset the socket to blocking mode
|
||||
|
||||
*** november 2012 ***
|
||||
|
||||
* 1.4
|
||||
|
||||
- gevent improvements
|
||||
- improved http/https router and fastrouter
|
||||
- Go official support
|
||||
- a new set of infos are exported to the stats system
|
||||
- improved systemd support
|
||||
- log filtering and routing
|
||||
- improved tracebacker
|
||||
- offload transfer for static files, and network transfers
|
||||
- matheval support
|
||||
- plugins can be written in Obj-C
|
||||
- smart attach daemon
|
||||
- added support for PEP 405 virtualenvs
|
||||
- rawrouter with xclient support
|
||||
- internal routing plugin for cache
|
||||
|
||||
*** semptember 2012 ***
|
||||
|
||||
* 1.3
|
||||
|
||||
- python tracebacker
|
||||
|
||||
+1
-1
@@ -29,7 +29,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
|
||||
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
|
||||
as_shared_library = false
|
||||
|
||||
locking = auto
|
||||
|
||||
+51
-48
@@ -20,9 +20,9 @@ void uwsgi_alarm_func_cmd(struct uwsgi_alarm_instance *uai, char *msg, size_t le
|
||||
int pipe[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe)) {
|
||||
return;
|
||||
}
|
||||
uwsgi_socket_nb(pipe[0]);
|
||||
uwsgi_socket_nb(pipe[1]);
|
||||
}
|
||||
uwsgi_socket_nb(pipe[0]);
|
||||
uwsgi_socket_nb(pipe[1]);
|
||||
if (write(pipe[1], msg, len) != (ssize_t) len) {
|
||||
close(pipe[0]);
|
||||
close(pipe[1]);
|
||||
@@ -36,7 +36,7 @@ void uwsgi_alarm_func_cmd(struct uwsgi_alarm_instance *uai, char *msg, size_t le
|
||||
// pass the log line to a mule
|
||||
|
||||
void uwsgi_alarm_init_mule(struct uwsgi_alarm_instance *uai) {
|
||||
uai->data32 = atoi(uai->arg);
|
||||
uai->data32 = atoi(uai->arg);
|
||||
if (uai->data32 > (uint32_t) uwsgi.mules_cnt) {
|
||||
uwsgi_log_alarm("] invalid mule_id (%d mules available), fallback to 0\n", uwsgi.mules_cnt);
|
||||
uai->data32 = 0;
|
||||
@@ -45,24 +45,25 @@ void uwsgi_alarm_init_mule(struct uwsgi_alarm_instance *uai) {
|
||||
|
||||
void uwsgi_alarm_func_mule(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
// skip if mules are not available
|
||||
if (uwsgi.mules_cnt == 0) return;
|
||||
if (uwsgi.mules_cnt == 0)
|
||||
return;
|
||||
int fd = uwsgi.shared->mule_queue_pipe[0];
|
||||
if (uai->data32 > 0) {
|
||||
int mule_id = uai->data32-1;
|
||||
fd = uwsgi.mules[mule_id].queue_pipe[0];
|
||||
int mule_id = uai->data32 - 1;
|
||||
fd = uwsgi.mules[mule_id].queue_pipe[0];
|
||||
}
|
||||
mule_send_msg(fd, msg, len);
|
||||
}
|
||||
|
||||
|
||||
// register a new alarm
|
||||
void uwsgi_register_alarm(char *name, void (*init)(struct uwsgi_alarm_instance *), void (*func)(struct uwsgi_alarm_instance *, char *, size_t)) {
|
||||
struct uwsgi_alarm *old_ua=NULL,*ua = uwsgi.alarms;
|
||||
while(ua) {
|
||||
void uwsgi_register_alarm(char *name, void (*init) (struct uwsgi_alarm_instance *), void (*func) (struct uwsgi_alarm_instance *, char *, size_t)) {
|
||||
struct uwsgi_alarm *old_ua = NULL, *ua = uwsgi.alarms;
|
||||
while (ua) {
|
||||
// skip already initialized alarms
|
||||
if (!strcmp(ua->name, name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
old_ua = ua;
|
||||
ua = ua->next;
|
||||
}
|
||||
@@ -89,17 +90,18 @@ void uwsgi_register_embedded_alarms() {
|
||||
|
||||
static int uwsgi_alarm_add(char *name, char *plugin, char *arg) {
|
||||
struct uwsgi_alarm *ua = uwsgi.alarms;
|
||||
while(ua) {
|
||||
while (ua) {
|
||||
if (!strcmp(ua->name, plugin)) {
|
||||
break;
|
||||
}
|
||||
ua = ua->next;
|
||||
}
|
||||
|
||||
if (!ua) return -1;
|
||||
if (!ua)
|
||||
return -1;
|
||||
|
||||
struct uwsgi_alarm_instance *old_uai = NULL, *uai = uwsgi.alarm_instances;
|
||||
while(uai) {
|
||||
while (uai) {
|
||||
old_uai = uai;
|
||||
uai = uai->next;
|
||||
}
|
||||
@@ -116,7 +118,7 @@ static int uwsgi_alarm_add(char *name, char *plugin, char *arg) {
|
||||
else {
|
||||
uwsgi.alarm_instances = uai;
|
||||
}
|
||||
|
||||
|
||||
ua->init(uai);
|
||||
return 0;
|
||||
}
|
||||
@@ -124,7 +126,7 @@ static int uwsgi_alarm_add(char *name, char *plugin, char *arg) {
|
||||
// get an alarm instance by its name
|
||||
static struct uwsgi_alarm_instance *uwsgi_alarm_get_instance(char *name) {
|
||||
struct uwsgi_alarm_instance *uai = uwsgi.alarm_instances;
|
||||
while(uai) {
|
||||
while (uai) {
|
||||
if (!strcmp(name, uai->name)) {
|
||||
return uai;
|
||||
}
|
||||
@@ -137,7 +139,7 @@ static struct uwsgi_alarm_instance *uwsgi_alarm_get_instance(char *name) {
|
||||
static int uwsgi_alarm_log_add(char *alarms, char *regexp) {
|
||||
|
||||
struct uwsgi_alarm_log *old_ual = NULL, *ual = uwsgi.alarm_logs;
|
||||
while(ual) {
|
||||
while (ual) {
|
||||
old_ual = ual;
|
||||
ual = ual->next;
|
||||
}
|
||||
@@ -145,7 +147,7 @@ static int uwsgi_alarm_log_add(char *alarms, char *regexp) {
|
||||
ual = uwsgi_calloc(sizeof(struct uwsgi_alarm_log));
|
||||
if (uwsgi_regexp_build(regexp, &ual->pattern, &ual->pattern_extra)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (old_ual) {
|
||||
old_ual->next = ual;
|
||||
@@ -157,11 +159,12 @@ static int uwsgi_alarm_log_add(char *alarms, char *regexp) {
|
||||
// map instances to the log
|
||||
char *list = uwsgi_str(alarms);
|
||||
char *p = strtok(list, ",");
|
||||
while(p) {
|
||||
while (p) {
|
||||
struct uwsgi_alarm_instance *uai = uwsgi_alarm_get_instance(p);
|
||||
if (!uai) return -1;
|
||||
struct uwsgi_alarm_ll *old_uall=NULL,*uall = ual->alarms;
|
||||
while(uall) {
|
||||
if (!uai)
|
||||
return -1;
|
||||
struct uwsgi_alarm_ll *old_uall = NULL, *uall = ual->alarms;
|
||||
while (uall) {
|
||||
old_uall = uall;
|
||||
uall = uall->next;
|
||||
}
|
||||
@@ -184,7 +187,7 @@ void uwsgi_alarms_init() {
|
||||
|
||||
// first of all, create instance of alarms
|
||||
struct uwsgi_string_list *usl = uwsgi.alarm_list;
|
||||
while(usl) {
|
||||
while (usl) {
|
||||
char *line = uwsgi_str(usl->value);
|
||||
char *space = strchr(line, ' ');
|
||||
if (!space) {
|
||||
@@ -192,14 +195,14 @@ void uwsgi_alarms_init() {
|
||||
exit(1);
|
||||
}
|
||||
*space = 0;
|
||||
char *plugin = space+1;
|
||||
char *plugin = space + 1;
|
||||
char *colon = strchr(plugin, ':');
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid alarm syntax: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
*colon = 0;
|
||||
char *arg = colon+1;
|
||||
char *arg = colon + 1;
|
||||
// here the alarm is mapped to a name and initialized
|
||||
if (uwsgi_alarm_add(line, plugin, arg)) {
|
||||
uwsgi_log("invalid alarm: %s\n", usl->value);
|
||||
@@ -210,20 +213,20 @@ void uwsgi_alarms_init() {
|
||||
|
||||
// then map log-alarm
|
||||
usl = uwsgi.alarm_logs_list;
|
||||
while(usl) {
|
||||
while (usl) {
|
||||
char *line = uwsgi_str(usl->value);
|
||||
char *space = strchr(line, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid log-alarm syntax: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
*space = 0;
|
||||
char *regexp = space+1;
|
||||
// here the log-alarm is created
|
||||
if (uwsgi_alarm_log_add(line, regexp)) {
|
||||
uwsgi_log("invalid log-alarm: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
if (!space) {
|
||||
uwsgi_log("invalid log-alarm syntax: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
*space = 0;
|
||||
char *regexp = space + 1;
|
||||
// here the log-alarm is created
|
||||
if (uwsgi_alarm_log_add(line, regexp)) {
|
||||
uwsgi_log("invalid log-alarm: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
usl = usl->next;
|
||||
}
|
||||
@@ -231,13 +234,14 @@ void uwsgi_alarms_init() {
|
||||
|
||||
// check if a log should raise an alarm
|
||||
void uwsgi_alarm_log_check(char *msg, size_t len) {
|
||||
if (!uwsgi_strncmp(msg, len, "[uwsgi-alarm", 12)) return;
|
||||
if (!uwsgi_strncmp(msg, len, "[uwsgi-alarm", 12))
|
||||
return;
|
||||
struct uwsgi_alarm_log *ual = uwsgi.alarm_logs;
|
||||
while(ual) {
|
||||
if (uwsgi_regexp_match(ual->pattern, ual->pattern_extra, msg, len) >= 0) {
|
||||
uwsgi_alarm_log_run(ual, msg, len);
|
||||
}
|
||||
ual = ual->next;
|
||||
while (ual) {
|
||||
if (uwsgi_regexp_match(ual->pattern, ual->pattern_extra, msg, len) >= 0) {
|
||||
uwsgi_alarm_log_run(ual, msg, len);
|
||||
}
|
||||
ual = ual->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,8 +249,9 @@ void uwsgi_alarm_log_check(char *msg, size_t len) {
|
||||
void uwsgi_alarm_run(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
time_t now = uwsgi_now();
|
||||
// avoid alarm storming/loop if last message is the same
|
||||
if (!uwsgi_strncmp(msg, len, uai->last_msg, uai->last_msg_size)) {
|
||||
if (now - uai->last_run < uwsgi.alarm_freq) return;
|
||||
if (!uwsgi_strncmp(msg, len, uai->last_msg, uai->last_msg_size)) {
|
||||
if (now - uai->last_run < uwsgi.alarm_freq)
|
||||
return;
|
||||
}
|
||||
uai->alarm->func(uai, msg, len);
|
||||
uai->last_run = uwsgi_now();
|
||||
@@ -257,10 +262,8 @@ void uwsgi_alarm_run(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
// call the alarms mapped to a log line
|
||||
void uwsgi_alarm_log_run(struct uwsgi_alarm_log *ual, char *msg, size_t len) {
|
||||
struct uwsgi_alarm_ll *uall = ual->alarms;
|
||||
while(uall) {
|
||||
while (uall) {
|
||||
uwsgi_alarm_run(uall->alarm, msg, len);
|
||||
uall = uall->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+28
-24
@@ -10,19 +10,20 @@ struct uwsgi_buffer *uwsgi_buffer_new(size_t len) {
|
||||
ub->len = len;
|
||||
}
|
||||
return ub;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_buffer_fix(struct uwsgi_buffer *ub, size_t len) {
|
||||
if (ub->limit >0 && len > ub->limit) return -1;
|
||||
if (ub->limit > 0 && len > ub->limit)
|
||||
return -1;
|
||||
if (ub->len < len) {
|
||||
char *new_buf = realloc(ub->buf, len);
|
||||
if (!new_buf) {
|
||||
uwsgi_error("uwsgi_buffer_fix()");
|
||||
return -1;
|
||||
}
|
||||
ub->buf = new_buf;
|
||||
ub->len = len;
|
||||
if (!new_buf) {
|
||||
uwsgi_error("uwsgi_buffer_fix()");
|
||||
return -1;
|
||||
}
|
||||
ub->buf = new_buf;
|
||||
ub->len = len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -31,19 +32,20 @@ int uwsgi_buffer_ensure(struct uwsgi_buffer *ub, size_t len) {
|
||||
size_t remains = ub->len - ub->pos;
|
||||
if (remains < len) {
|
||||
size_t new_len = ub->len + (len - remains);
|
||||
if (ub->limit >0 && new_len > ub->limit) {
|
||||
if (ub->limit > 0 && new_len > ub->limit) {
|
||||
new_len = ub->limit;
|
||||
if (new_len == ub->len) return -1;
|
||||
if (new_len == ub->len)
|
||||
return -1;
|
||||
}
|
||||
char *new_buf = realloc(ub->buf, new_len);
|
||||
if (!new_buf) {
|
||||
uwsgi_error("uwsgi_buffer_ensure()");
|
||||
return -1;
|
||||
}
|
||||
ub->buf = new_buf;
|
||||
ub->len = new_len;
|
||||
}
|
||||
return 0;
|
||||
char *new_buf = realloc(ub->buf, new_len);
|
||||
if (!new_buf) {
|
||||
uwsgi_error("uwsgi_buffer_ensure()");
|
||||
return -1;
|
||||
}
|
||||
ub->buf = new_buf;
|
||||
ub->len = new_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,12 +55,13 @@ int uwsgi_buffer_append(struct uwsgi_buffer *ub, char *buf, size_t len) {
|
||||
|
||||
if (len > remains) {
|
||||
size_t chunk_size = UMAX(len, (size_t) uwsgi.page_size);
|
||||
if (ub->limit >0 && ub->len + chunk_size > ub->limit) {
|
||||
if (ub->limit > 0 && ub->len + chunk_size > ub->limit) {
|
||||
// retry with another minimal size
|
||||
if (len < (size_t) uwsgi.page_size) {
|
||||
chunk_size = len;
|
||||
}
|
||||
if (ub->len + chunk_size > ub->limit) return -1;
|
||||
if (ub->len + chunk_size > ub->limit)
|
||||
return -1;
|
||||
}
|
||||
char *new_buf = realloc(ub->buf, ub->len + chunk_size);
|
||||
if (!new_buf) {
|
||||
@@ -75,7 +78,8 @@ int uwsgi_buffer_append(struct uwsgi_buffer *ub, char *buf, size_t len) {
|
||||
}
|
||||
|
||||
void uwsgi_buffer_destroy(struct uwsgi_buffer *ub) {
|
||||
if (ub->buf) free(ub->buf);
|
||||
if (ub->buf)
|
||||
free(ub->buf);
|
||||
free(ub);
|
||||
}
|
||||
|
||||
@@ -83,14 +87,14 @@ int uwsgi_buffer_send(struct uwsgi_buffer *ub, int fd) {
|
||||
size_t remains = ub->pos;
|
||||
char *ptr = ub->buf;
|
||||
|
||||
while(remains > 0) {
|
||||
while (remains > 0) {
|
||||
int ret = uwsgi_waitfd_write(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (ret > 0) {
|
||||
ssize_t len = write(fd, ptr, remains);
|
||||
if (len > 0) {
|
||||
ptr += len;
|
||||
remains -= len;
|
||||
}
|
||||
}
|
||||
else if (len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+148
-137
@@ -5,91 +5,87 @@ extern struct uwsgi_server uwsgi;
|
||||
void uwsgi_init_cache() {
|
||||
|
||||
if (!uwsgi.cache_blocksize)
|
||||
uwsgi.cache_blocksize = UMAX16;
|
||||
uwsgi.cache_blocksize = UMAX16;
|
||||
|
||||
uwsgi.cache_hashtable = (uint64_t *) mmap(NULL, sizeof(uint64_t) * UMAX16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache_hashtable) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.cache_hashtable = (uint64_t *) mmap(NULL, sizeof(uint64_t) * UMAX16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache_hashtable) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(uwsgi.cache_hashtable, 0, sizeof(uint64_t) * UMAX16);
|
||||
memset(uwsgi.cache_hashtable, 0, sizeof(uint64_t) * UMAX16);
|
||||
|
||||
uwsgi.cache_unused_stack = (uint64_t *) mmap(NULL, sizeof(uint64_t) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache_unused_stack) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.cache_unused_stack = (uint64_t *) mmap(NULL, sizeof(uint64_t) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache_unused_stack) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(uwsgi.cache_unused_stack, 0, sizeof(uint64_t) * uwsgi.cache_max_items);
|
||||
memset(uwsgi.cache_unused_stack, 0, sizeof(uint64_t) * uwsgi.cache_max_items);
|
||||
|
||||
// the first cache item is always zero
|
||||
uwsgi.shared->cache_first_available_item = 1;
|
||||
uwsgi.shared->cache_unused_stack_ptr = 0;
|
||||
// the first cache item is always zero
|
||||
uwsgi.shared->cache_first_available_item = 1;
|
||||
uwsgi.shared->cache_unused_stack_ptr = 0;
|
||||
|
||||
//uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (uwsgi.cache_store) {
|
||||
uwsgi.cache_filesize = (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items);
|
||||
int cache_fd;
|
||||
struct stat cst;
|
||||
//uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (uwsgi.cache_store) {
|
||||
uwsgi.cache_filesize = (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items);
|
||||
int cache_fd;
|
||||
struct stat cst;
|
||||
|
||||
if (stat(uwsgi.cache_store, &cst)) {
|
||||
uwsgi_log("creating a new cache store file: %s\n", uwsgi.cache_store);
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (cache_fd >= 0) {
|
||||
// fill the caching store
|
||||
if (ftruncate(cache_fd, uwsgi.cache_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((size_t) cst.st_size != uwsgi.cache_filesize || !S_ISREG(cst.st_mode)) {
|
||||
uwsgi_log("invalid cache store file. Please remove it or fix cache blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
uwsgi_log("recovered cache from backing store file: %s\n", uwsgi.cache_store);
|
||||
}
|
||||
if (stat(uwsgi.cache_store, &cst)) {
|
||||
uwsgi_log("creating a new cache store file: %s\n", uwsgi.cache_store);
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (cache_fd >= 0) {
|
||||
// fill the caching store
|
||||
if (ftruncate(cache_fd, uwsgi.cache_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((size_t) cst.st_size != uwsgi.cache_filesize || !S_ISREG(cst.st_mode)) {
|
||||
uwsgi_log("invalid cache store file. Please remove it or fix cache blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
uwsgi_log("recovered cache from backing store file: %s\n", uwsgi.cache_store);
|
||||
}
|
||||
|
||||
if (cache_fd < 0) {
|
||||
uwsgi_error_open(uwsgi.cache_store);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, uwsgi.cache_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, cache_fd, 0);
|
||||
uwsgi_cache_fix();
|
||||
if (cache_fd < 0) {
|
||||
uwsgi_error_open(uwsgi.cache_store);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, uwsgi.cache_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, cache_fd, 0);
|
||||
uwsgi_cache_fix();
|
||||
|
||||
}
|
||||
else {
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
int i;
|
||||
for (i = 0; i < (int) uwsgi.cache_max_items; i++) {
|
||||
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
|
||||
}
|
||||
}
|
||||
if (!uwsgi.cache_items) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
int i;
|
||||
for (i = 0; i < (int) uwsgi.cache_max_items; i++) {
|
||||
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
|
||||
}
|
||||
}
|
||||
if (!uwsgi.cache_items) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
uwsgi.cache = mmap(NULL, uwsgi.cache_blocksize * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
uwsgi.cache = mmap(NULL, uwsgi.cache_blocksize * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
|
||||
uwsgi.cache = ((void *) uwsgi.cache_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items);
|
||||
uwsgi.cache = ((void *) uwsgi.cache_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items);
|
||||
|
||||
uwsgi.cache_lock = uwsgi_rwlock_init("cache");
|
||||
uwsgi.cache_lock = uwsgi_rwlock_init("cache");
|
||||
|
||||
uwsgi_log("*** Cache subsystem initialized: %lluMB (key: %llu bytes, keys: %llu bytes, data: %llu bytes) preallocated ***\n",
|
||||
(unsigned long long) ((uwsgi.cache_blocksize * uwsgi.cache_max_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items)) / (1024 * 1024),
|
||||
(unsigned long long) sizeof(struct uwsgi_cache_item),
|
||||
(unsigned long long) (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items),
|
||||
(unsigned long long) (uwsgi.cache_blocksize * uwsgi.cache_max_items));
|
||||
uwsgi_log("*** Cache subsystem initialized: %lluMB (key: %llu bytes, keys: %llu bytes, data: %llu bytes) preallocated ***\n", (unsigned long long) ((uwsgi.cache_blocksize * uwsgi.cache_max_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items)) / (1024 * 1024), (unsigned long long) sizeof(struct uwsgi_cache_item), (unsigned long long) (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items), (unsigned long long) (uwsgi.cache_blocksize * uwsgi.cache_max_items));
|
||||
}
|
||||
|
||||
uint32_t djb33x_hash(char *key, int keylen) {
|
||||
@@ -97,7 +93,7 @@ uint32_t djb33x_hash(char *key, int keylen) {
|
||||
register uint32_t hash = 5381;
|
||||
int i;
|
||||
|
||||
for(i=0;i<keylen;i++) {
|
||||
for (i = 0; i < keylen; i++) {
|
||||
hash = ((hash << 5) + hash) ^ key[i];
|
||||
}
|
||||
|
||||
@@ -108,7 +104,7 @@ uint32_t djb33x_hash(char *key, int keylen) {
|
||||
static inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
|
||||
|
||||
uint32_t hash = djb33x_hash(key, keylen);
|
||||
|
||||
|
||||
int hash_key = hash % 0xffff;
|
||||
|
||||
uint64_t slot = uwsgi.cache_hashtable[hash_key];
|
||||
@@ -121,19 +117,22 @@ static inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
|
||||
uci = &uwsgi.cache_items[slot];
|
||||
|
||||
// first round
|
||||
if (uci->djbhash != hash) return 0;
|
||||
if (uci->keysize != keylen) goto cycle;
|
||||
if (memcmp(uci->key, key, keylen)) goto cycle;
|
||||
if (uci->djbhash != hash)
|
||||
return 0;
|
||||
if (uci->keysize != keylen)
|
||||
goto cycle;
|
||||
if (memcmp(uci->key, key, keylen))
|
||||
goto cycle;
|
||||
|
||||
return slot;
|
||||
|
||||
cycle:
|
||||
while(uci->next) {
|
||||
while (uci->next) {
|
||||
slot = uci->next;
|
||||
uci = &uwsgi.cache_items[slot];
|
||||
rounds++;
|
||||
if (rounds > uwsgi.cache_max_items) {
|
||||
uwsgi_log("ALARM !!! cache-loop (and potential deadlock) detected slot = %llu prev = %llu next = %llu\n", uci->next, slot, uci->prev, uci->next);
|
||||
uwsgi_log("ALARM !!! cache-loop (and potential deadlock) detected slot = %llu prev = %llu next = %llu\n", uci->next, slot, uci->prev, uci->next);
|
||||
// terrible case: the whole uWSGI stack can deadlock, leaving only the master alive
|
||||
// if the master is avalable, trigger a brutal reload
|
||||
if (uwsgi.master_process) {
|
||||
@@ -144,9 +143,12 @@ cycle:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (uci->djbhash != hash) return 0;
|
||||
if (uci->keysize != keylen) continue;
|
||||
if (!memcmp(uci->key, key, keylen)) return slot;
|
||||
if (uci->djbhash != hash)
|
||||
return 0;
|
||||
if (uci->keysize != keylen)
|
||||
continue;
|
||||
if (!memcmp(uci->key, key, keylen))
|
||||
return slot;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -157,15 +159,16 @@ uint32_t uwsgi_cache_exists(char *key, uint16_t keylen) {
|
||||
return uwsgi_cache_get_index(key, keylen);
|
||||
}
|
||||
|
||||
char *uwsgi_cache_get(char *key, uint16_t keylen, uint64_t *valsize) {
|
||||
char *uwsgi_cache_get(char *key, uint16_t keylen, uint64_t * valsize) {
|
||||
|
||||
uint64_t index = uwsgi_cache_get_index(key, keylen);
|
||||
|
||||
if (index) {
|
||||
if (uwsgi.cache_items[index].flags & UWSGI_CACHE_FLAG_UNGETTABLE) return NULL;
|
||||
if (uwsgi.cache_items[index].flags & UWSGI_CACHE_FLAG_UNGETTABLE)
|
||||
return NULL;
|
||||
*valsize = uwsgi.cache_items[index].valsize;
|
||||
uwsgi.cache_items[index].hits++;
|
||||
return uwsgi.cache+(index*uwsgi.cache_blocksize);
|
||||
return uwsgi.cache + (index * uwsgi.cache_blocksize);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -180,20 +183,20 @@ int uwsgi_cache_del(char *key, uint16_t keylen, uint64_t index) {
|
||||
index = uwsgi_cache_get_index(key, keylen);
|
||||
|
||||
if (index) {
|
||||
uci = &uwsgi.cache_items[index] ;
|
||||
uci = &uwsgi.cache_items[index];
|
||||
uci->keysize = 0;
|
||||
uci->valsize = 0;
|
||||
uwsgi.shared->cache_unused_stack_ptr++;
|
||||
uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr] = index;
|
||||
// try to return to initial condition...
|
||||
if (index == uwsgi.shared->cache_first_available_item-1) {
|
||||
if (index == uwsgi.shared->cache_first_available_item - 1) {
|
||||
uwsgi.shared->cache_first_available_item--;
|
||||
//uwsgi_log("FACI: %llu STACK PTR: %llu\n", (unsigned long long) uwsgi.shared->cache_first_available_item, (unsigned long long) uwsgi.shared->cache_unused_stack_ptr);
|
||||
}
|
||||
ret = 0;
|
||||
// relink collisioned entry
|
||||
if (uci->prev) {
|
||||
uwsgi.cache_items[uci->prev].next = uci->next;
|
||||
uwsgi.cache_items[uci->prev].next = uci->next;
|
||||
}
|
||||
else {
|
||||
// set next as the new entry point (could be 0)
|
||||
@@ -201,7 +204,7 @@ int uwsgi_cache_del(char *key, uint16_t keylen, uint64_t index) {
|
||||
}
|
||||
|
||||
if (uci->next) {
|
||||
uwsgi.cache_items[uci->next].prev = uci->prev;
|
||||
uwsgi.cache_items[uci->next].prev = uci->prev;
|
||||
}
|
||||
|
||||
if (!uci->prev && !uci->next) {
|
||||
@@ -222,12 +225,12 @@ void uwsgi_cache_fix() {
|
||||
|
||||
uint64_t i;
|
||||
|
||||
for(i=0;i< uwsgi.cache_max_items;i++) {
|
||||
for (i = 0; i < uwsgi.cache_max_items; i++) {
|
||||
// valid record ?
|
||||
if (uwsgi.cache_items[i].keysize) {
|
||||
if (!uwsgi.cache_items[i].prev) {
|
||||
// put value in hash_table
|
||||
uwsgi.cache_hashtable[ uwsgi.cache_items[i].djbhash % 0xffff] = i;
|
||||
uwsgi.cache_hashtable[uwsgi.cache_items[i].djbhash % 0xffff] = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -241,15 +244,17 @@ void uwsgi_cache_fix() {
|
||||
|
||||
int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint64_t expires, uint16_t flags) {
|
||||
|
||||
uint64_t index = 0, last_index = 0 ;
|
||||
uint64_t index = 0, last_index = 0;
|
||||
|
||||
struct uwsgi_cache_item *uci, *ucii;
|
||||
|
||||
int ret = -1;
|
||||
|
||||
if (!keylen || !vallen) return -1;
|
||||
if (!keylen || !vallen)
|
||||
return -1;
|
||||
|
||||
if (keylen > UWSGI_CACHE_MAX_KEY_SIZE) return -1;
|
||||
if (keylen > UWSGI_CACHE_MAX_KEY_SIZE)
|
||||
return -1;
|
||||
|
||||
if (uwsgi.shared->cache_first_available_item >= uwsgi.cache_max_items && !uwsgi.shared->cache_unused_stack_ptr) {
|
||||
uwsgi_log("*** DANGER cache is FULL !!! ***\n");
|
||||
@@ -265,24 +270,25 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
|
||||
uwsgi.shared->cache_unused_stack_ptr--;
|
||||
}
|
||||
else {
|
||||
index = uwsgi.shared->cache_first_available_item;
|
||||
index = uwsgi.shared->cache_first_available_item;
|
||||
if (uwsgi.shared->cache_first_available_item < uwsgi.cache_max_items) {
|
||||
uwsgi.shared->cache_first_available_item++;
|
||||
}
|
||||
}
|
||||
uci = &uwsgi.cache_items[index] ;
|
||||
if (expires) expires += uwsgi_now();
|
||||
uci = &uwsgi.cache_items[index];
|
||||
if (expires)
|
||||
expires += uwsgi_now();
|
||||
uci->expires = expires;
|
||||
uci->djbhash = djb33x_hash(key, keylen);
|
||||
uci->hits = 0;
|
||||
uci->flags = flags;
|
||||
memcpy(uci->key, key, keylen);
|
||||
memcpy(uwsgi.cache+(index*uwsgi.cache_blocksize), val, vallen);
|
||||
memcpy(uwsgi.cache + (index * uwsgi.cache_blocksize), val, vallen);
|
||||
|
||||
// set this as late as possibile (to reduce races risk)
|
||||
|
||||
uci->valsize = vallen;
|
||||
uci->keysize = keylen;
|
||||
uci->keysize = keylen;
|
||||
ret = 0;
|
||||
// now put the value in the 16bit hashtable
|
||||
int slot = uci->djbhash % 0xffff;
|
||||
@@ -297,29 +303,29 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
|
||||
//uwsgi_log("HASH COLLISION !!!!\n");
|
||||
// append to first available next
|
||||
last_index = uwsgi.cache_hashtable[slot];
|
||||
ucii = &uwsgi.cache_items[ last_index ];
|
||||
while(ucii->next) {
|
||||
ucii = &uwsgi.cache_items[last_index];
|
||||
while (ucii->next) {
|
||||
last_index = ucii->next;
|
||||
ucii = &uwsgi.cache_items[ last_index ];
|
||||
ucii = &uwsgi.cache_items[last_index];
|
||||
}
|
||||
ucii->next = index;
|
||||
uci->prev = last_index;
|
||||
}
|
||||
}
|
||||
else if (flags & UWSGI_CACHE_FLAG_UPDATE) {
|
||||
uci = &uwsgi.cache_items[index] ;
|
||||
uci = &uwsgi.cache_items[index];
|
||||
if (expires) {
|
||||
expires += uwsgi_now();
|
||||
uci->expires = expires;
|
||||
}
|
||||
memcpy(uwsgi.cache+(index*uwsgi.cache_blocksize), val, vallen);
|
||||
memcpy(uwsgi.cache + (index * uwsgi.cache_blocksize), val, vallen);
|
||||
uci->valsize = vallen;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* THIS PART IS HEAVILY OPTIMIZED: PERFORMANCE NOT ELEGANCE !!! */
|
||||
@@ -330,7 +336,7 @@ void *cache_thread_loop(void *fd_ptr) {
|
||||
int fd = *fd_tmp;
|
||||
int i;
|
||||
ssize_t len;
|
||||
char uwsgi_packet[UMAX16+4];
|
||||
char uwsgi_packet[UMAX16 + 4];
|
||||
struct uwsgi_header *uh = (struct uwsgi_header *) uwsgi_packet;
|
||||
char *val;
|
||||
uint64_t vallen;
|
||||
@@ -343,7 +349,7 @@ void *cache_thread_loop(void *fd_ptr) {
|
||||
|
||||
ctl_poll.events = POLLIN;
|
||||
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
ctl_sun_len = sizeof(struct sockaddr_un);
|
||||
pthread_mutex_lock(&uwsgi.cache_server_lock);
|
||||
|
||||
@@ -356,55 +362,58 @@ void *cache_thread_loop(void *fd_ptr) {
|
||||
continue;
|
||||
}
|
||||
i = 0;
|
||||
while(i < 4) {
|
||||
while (i < 4) {
|
||||
len = poll(&ctl_poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("cache poll()");
|
||||
goto clear;
|
||||
}
|
||||
len = read(ctl_poll.fd, uwsgi_packet+i, 4-i);
|
||||
len = read(ctl_poll.fd, uwsgi_packet + i, 4 - i);
|
||||
if (len < 0) {
|
||||
uwsgi_error("cache read()");
|
||||
goto clear;
|
||||
}
|
||||
i+=len;
|
||||
i += len;
|
||||
}
|
||||
|
||||
if (uh->pktsize == 0) goto clear;
|
||||
if (uh->pktsize == 0)
|
||||
goto clear;
|
||||
|
||||
while(i < 4+uh->pktsize) {
|
||||
while (i < 4 + uh->pktsize) {
|
||||
len = poll(&ctl_poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("cache poll()");
|
||||
goto clear;
|
||||
}
|
||||
len = read(ctl_poll.fd, uwsgi_packet+i, (4+uh->pktsize)-i);
|
||||
len = read(ctl_poll.fd, uwsgi_packet + i, (4 + uh->pktsize) - i);
|
||||
if (len < 0) {
|
||||
uwsgi_error("cache read()");
|
||||
goto clear;
|
||||
}
|
||||
i+=len;
|
||||
i += len;
|
||||
}
|
||||
|
||||
watermark = uwsgi_packet+4+uh->pktsize;
|
||||
watermark = uwsgi_packet + 4 + uh->pktsize;
|
||||
|
||||
// get first parameter
|
||||
memcpy(&keylen, uwsgi_packet+4, 2);
|
||||
memcpy(&keylen, uwsgi_packet + 4, 2);
|
||||
#ifdef __BIG_ENDIAN__
|
||||
keylen = uwsgi_swap16(keylen);
|
||||
keylen = uwsgi_swap16(keylen);
|
||||
#endif
|
||||
if (uwsgi_packet+6+keylen > watermark) goto clear;
|
||||
key = uwsgi_packet+6+keylen+2;
|
||||
memcpy(&keylen, key-2, 2);
|
||||
if (uwsgi_packet + 6 + keylen > watermark)
|
||||
goto clear;
|
||||
key = uwsgi_packet + 6 + keylen + 2;
|
||||
memcpy(&keylen, key - 2, 2);
|
||||
#ifdef __BIG_ENDIAN__
|
||||
keylen = uwsgi_swap16(keylen);
|
||||
keylen = uwsgi_swap16(keylen);
|
||||
#endif
|
||||
|
||||
if (key+keylen > watermark) goto clear;
|
||||
if (key + keylen > watermark)
|
||||
goto clear;
|
||||
|
||||
val = uwsgi_cache_get(key, keylen, &vallen);
|
||||
if (val && vallen > 0) {
|
||||
if (write(ctl_poll.fd, val, vallen) < 0) {
|
||||
if (val && vallen > 0) {
|
||||
if (write(ctl_poll.fd, val, vallen) < 0) {
|
||||
uwsgi_error("cache write()");
|
||||
}
|
||||
}
|
||||
@@ -419,32 +428,34 @@ clear:
|
||||
int uwsgi_cache_server(char *socket, int threads) {
|
||||
|
||||
int *fd = uwsgi_malloc(sizeof(int));
|
||||
|
||||
|
||||
int i;
|
||||
pthread_t thread_id;
|
||||
char *tcp_port = strchr(socket, ':');
|
||||
if (tcp_port) {
|
||||
*fd = bind_to_tcp(socket, uwsgi.listen_queue, tcp_port);
|
||||
}
|
||||
else {
|
||||
*fd = bind_to_unix(socket, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
char *tcp_port = strchr(socket, ':');
|
||||
if (tcp_port) {
|
||||
*fd = bind_to_tcp(socket, uwsgi.listen_queue, tcp_port);
|
||||
}
|
||||
else {
|
||||
*fd = bind_to_unix(socket, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
|
||||
pthread_mutex_init(&uwsgi.cache_server_lock, NULL);
|
||||
pthread_mutex_init(&uwsgi.cache_server_lock, NULL);
|
||||
|
||||
if (threads < 1) threads = 1;
|
||||
if (threads < 1)
|
||||
threads = 1;
|
||||
|
||||
uwsgi_log("*** cache-optimized server enabled on fd %d (%d threads) ***\n", *fd, threads);
|
||||
|
||||
for(i=0;i<threads;i++) {
|
||||
for (i = 0; i < threads; i++) {
|
||||
pthread_create(&thread_id, NULL, cache_thread_loop, (void *) fd);
|
||||
}
|
||||
|
||||
return *fd;
|
||||
return *fd;
|
||||
}
|
||||
|
||||
int uwsgi_cache_enabled() {
|
||||
if (uwsgi.cache_max_items > 0) return 1;
|
||||
if (uwsgi.cache_max_items > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -4,11 +4,11 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
// in the future we will need to use the best clock source for each os/system
|
||||
time_t uwsgi_now() {
|
||||
return uwsgi.clock->seconds();
|
||||
return uwsgi.clock->seconds();
|
||||
}
|
||||
|
||||
uint64_t uwsgi_micros() {
|
||||
return uwsgi.clock->microseconds();
|
||||
return uwsgi.clock->microseconds();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ void uwsgi_register_clock(struct uwsgi_clock *clock) {
|
||||
return;
|
||||
}
|
||||
|
||||
while(clocks) {
|
||||
while (clocks) {
|
||||
if (!clocks->next) {
|
||||
clocks->next = clock;
|
||||
return;
|
||||
@@ -33,7 +33,7 @@ void uwsgi_register_clock(struct uwsgi_clock *clock) {
|
||||
|
||||
void uwsgi_set_clock(char *name) {
|
||||
struct uwsgi_clock *clocks = uwsgi.clocks;
|
||||
while(clocks) {
|
||||
while (clocks) {
|
||||
if (!strcmp(name, clocks->name)) {
|
||||
uwsgi.clock = clocks;
|
||||
return;
|
||||
|
||||
+317
-317
@@ -7,7 +7,7 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
static void cluster_manage_opt(char *key, uint16_t keylen, char *value, uint16_t vallen, void *foobar) {
|
||||
|
||||
add_exported_option( uwsgi_concat2n(key, keylen, "", 0), uwsgi_concat2n(value, vallen, "", 0), 0);
|
||||
add_exported_option(uwsgi_concat2n(key, keylen, "", 0), uwsgi_concat2n(value, vallen, "", 0), 0);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,45 +15,45 @@ void cluster_setup() {
|
||||
|
||||
int rlen;
|
||||
// get cluster configuration
|
||||
if (uwsgi.cluster != NULL) {
|
||||
// get multicast socket
|
||||
if (uwsgi.cluster != NULL) {
|
||||
// get multicast socket
|
||||
|
||||
uwsgi.cluster_fd = uwsgi_cluster_join(uwsgi.cluster);
|
||||
uwsgi.cluster_fd = uwsgi_cluster_join(uwsgi.cluster);
|
||||
|
||||
uwsgi_log("JOINED CLUSTER: %s\n", uwsgi.cluster);
|
||||
uwsgi_log("JOINED CLUSTER: %s\n", uwsgi.cluster);
|
||||
|
||||
// ask for cluster options only if bot pre-existent options are set
|
||||
if (uwsgi.exported_opts_cnt == 1 && !uwsgi.cluster_nodes) {
|
||||
// now wait max 60 seconds and resend multicast request every 10 seconds
|
||||
for (;;) {
|
||||
uwsgi_log("asking \"%s\" uWSGI cluster for configuration data:\n", uwsgi.cluster);
|
||||
if (uwsgi_send_empty_pkt(uwsgi.cluster_fd, uwsgi.cluster, 99, 0) < 0) {
|
||||
uwsgi_log("unable to send multicast message to %s\n", uwsgi.cluster);
|
||||
continue;
|
||||
}
|
||||
waitfd:
|
||||
rlen = uwsgi_waitfd(uwsgi.cluster_fd, 10);
|
||||
if (rlen < 0) {
|
||||
break;
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
// receive the packet
|
||||
char clusterbuf[4096];
|
||||
if (!uwsgi_hooked_parse_dict_dgram(uwsgi.cluster_fd, clusterbuf, 4096, 99, 1, cluster_manage_opt, NULL)) {
|
||||
uwsgi_configure();
|
||||
goto options_parsed;
|
||||
}
|
||||
else {
|
||||
goto waitfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options_parsed:
|
||||
// ask for cluster options only if bot pre-existent options are set
|
||||
if (uwsgi.exported_opts_cnt == 1 && !uwsgi.cluster_nodes) {
|
||||
// now wait max 60 seconds and resend multicast request every 10 seconds
|
||||
for (;;) {
|
||||
uwsgi_log("asking \"%s\" uWSGI cluster for configuration data:\n", uwsgi.cluster);
|
||||
if (uwsgi_send_empty_pkt(uwsgi.cluster_fd, uwsgi.cluster, 99, 0) < 0) {
|
||||
uwsgi_log("unable to send multicast message to %s\n", uwsgi.cluster);
|
||||
continue;
|
||||
}
|
||||
waitfd:
|
||||
rlen = uwsgi_waitfd(uwsgi.cluster_fd, 10);
|
||||
if (rlen < 0) {
|
||||
break;
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
// receive the packet
|
||||
char clusterbuf[4096];
|
||||
if (!uwsgi_hooked_parse_dict_dgram(uwsgi.cluster_fd, clusterbuf, 4096, 99, 1, cluster_manage_opt, NULL)) {
|
||||
uwsgi_configure();
|
||||
goto options_parsed;
|
||||
}
|
||||
else {
|
||||
goto waitfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options_parsed:
|
||||
|
||||
if (!uwsgi.cluster_nodes)
|
||||
uwsgi_cluster_add_me();
|
||||
}
|
||||
if (!uwsgi.cluster_nodes)
|
||||
uwsgi_cluster_add_me();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,404 +61,404 @@ void cluster_setup() {
|
||||
|
||||
void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_cluster_node *ucn;
|
||||
char *tcp_port;
|
||||
int i;
|
||||
struct uwsgi_cluster_node *ucn;
|
||||
char *tcp_port;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding node\n");
|
||||
uwsgi_log("adding node\n");
|
||||
#endif
|
||||
|
||||
tcp_port = strchr(nucn->name, ':');
|
||||
tcp_port = strchr(nucn->name, ':');
|
||||
#ifndef UWSGI_ZEROMQ
|
||||
if (tcp_port == NULL) {
|
||||
if (tcp_port == NULL) {
|
||||
#else
|
||||
char *zmq_dash = strchr(nucn->name, '-');
|
||||
if (tcp_port == NULL && zmq_dash == NULL) {
|
||||
char *zmq_dash = strchr(nucn->name, '-');
|
||||
if (tcp_port == NULL && zmq_dash == NULL) {
|
||||
#endif
|
||||
|
||||
fprintf(stdout, "invalid cluster node name %s\n", nucn->name);
|
||||
return;
|
||||
}
|
||||
fprintf(stdout, "invalid cluster node name %s\n", nucn->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// first check for already present node
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
if (ucn->name[0] != 0) {
|
||||
if (!strcmp(ucn->name, nucn->name)) {
|
||||
ucn->status = UWSGI_NODE_OK;
|
||||
ucn->last_seen = uwsgi_now();
|
||||
// update requests
|
||||
ucn->requests = nucn->requests;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// first check for already present node
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
if (ucn->name[0] != 0) {
|
||||
if (!strcmp(ucn->name, nucn->name)) {
|
||||
ucn->status = UWSGI_NODE_OK;
|
||||
ucn->last_seen = uwsgi_now();
|
||||
// update requests
|
||||
ucn->requests = nucn->requests;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
|
||||
if (ucn->name[0] == 0) {
|
||||
memcpy(ucn->name, nucn->name, strlen(nucn->name) + 1);
|
||||
memcpy(ucn->nodename, nucn->nodename, strlen(nucn->nodename) + 1);
|
||||
ucn->workers = nucn->workers;
|
||||
ucn->ucn_addr.sin_family = AF_INET;
|
||||
if (tcp_port) {
|
||||
ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1));
|
||||
tcp_port[0] = 0;
|
||||
}
|
||||
if (nucn->name[0] == 0) {
|
||||
ucn->ucn_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
if (ucn->name[0] == 0) {
|
||||
memcpy(ucn->name, nucn->name, strlen(nucn->name) + 1);
|
||||
memcpy(ucn->nodename, nucn->nodename, strlen(nucn->nodename) + 1);
|
||||
ucn->workers = nucn->workers;
|
||||
ucn->ucn_addr.sin_family = AF_INET;
|
||||
if (tcp_port) {
|
||||
ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1));
|
||||
tcp_port[0] = 0;
|
||||
}
|
||||
if (nucn->name[0] == 0) {
|
||||
ucn->ucn_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s\n", nucn->name);
|
||||
uwsgi_log("%s\n", nucn->name);
|
||||
#endif
|
||||
ucn->ucn_addr.sin_addr.s_addr = inet_addr(nucn->name);
|
||||
}
|
||||
ucn->ucn_addr.sin_addr.s_addr = inet_addr(nucn->name);
|
||||
}
|
||||
|
||||
ucn->type = type;
|
||||
// here memory can be freed, as it is allocated by uwsgi_concat2n
|
||||
if (type != CLUSTER_NODE_DYNAMIC && tcp_port) {
|
||||
tcp_port[0] = ':';
|
||||
}
|
||||
ucn->last_seen = uwsgi_now();
|
||||
ucn->requests = nucn->requests;
|
||||
uwsgi_log("[uWSGI cluster] added node %s\n", ucn->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ucn->type = type;
|
||||
// here memory can be freed, as it is allocated by uwsgi_concat2n
|
||||
if (type != CLUSTER_NODE_DYNAMIC && tcp_port) {
|
||||
tcp_port[0] = ':';
|
||||
}
|
||||
ucn->last_seen = uwsgi_now();
|
||||
ucn->requests = nucn->requests;
|
||||
uwsgi_log("[uWSGI cluster] added node %s\n", ucn->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_log("unable to add node %s\n", nucn->name);
|
||||
uwsgi_log("unable to add node %s\n", nucn->name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uwsgi_cluster_add_me() {
|
||||
|
||||
const char *key1 = "hostname";
|
||||
const char *key2 = "address";
|
||||
const char *key3 = "workers";
|
||||
const char *key4 = "requests";
|
||||
const char *key1 = "hostname";
|
||||
const char *key2 = "address";
|
||||
const char *key3 = "workers";
|
||||
const char *key4 = "requests";
|
||||
|
||||
char *ptrbuf;
|
||||
uint16_t ustrlen;
|
||||
char numproc[6];
|
||||
char *ptrbuf;
|
||||
uint16_t ustrlen;
|
||||
char numproc[6];
|
||||
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
char uuid_zmq_str[37];
|
||||
uuid_t uuid_zmq;
|
||||
if (!uwsgi.sockets && !uwsgi.zeromq) {
|
||||
char uuid_zmq_str[37];
|
||||
uuid_t uuid_zmq;
|
||||
if (!uwsgi.sockets && !uwsgi.zeromq) {
|
||||
#else
|
||||
if (!uwsgi.sockets) {
|
||||
if (!uwsgi.sockets) {
|
||||
#endif
|
||||
uwsgi_log("you need to specify at least a socket to start a uWSGI cluster\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("you need to specify at least a socket to start a uWSGI cluster\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(numproc, 6, "%d", uwsgi.numproc);
|
||||
snprintf(numproc, 6, "%d", uwsgi.numproc);
|
||||
|
||||
size_t len;
|
||||
size_t len;
|
||||
|
||||
if (uwsgi.sockets) {
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uwsgi.sockets->name) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
if (uwsgi.sockets) {
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uwsgi.sockets->name) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
else if (uwsgi.zeromq) {
|
||||
uuid_generate(uuid_zmq);
|
||||
uuid_unparse(uuid_zmq, uuid_zmq_str);
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uuid_zmq_str) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
else if (uwsgi.zeromq) {
|
||||
uuid_generate(uuid_zmq);
|
||||
uuid_unparse(uuid_zmq, uuid_zmq_str);
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uuid_zmq_str) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
char *buf = uwsgi_malloc(len);
|
||||
else {
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
char *buf = uwsgi_malloc(len);
|
||||
|
||||
ptrbuf = buf;
|
||||
ptrbuf = buf;
|
||||
|
||||
ustrlen = strlen(key1);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key1, strlen(key1));
|
||||
ptrbuf += strlen(key1);
|
||||
ustrlen = strlen(key1);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key1, strlen(key1));
|
||||
ptrbuf += strlen(key1);
|
||||
|
||||
ustrlen = strlen(uwsgi.hostname);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uwsgi.hostname, strlen(uwsgi.hostname));
|
||||
ptrbuf += strlen(uwsgi.hostname);
|
||||
ustrlen = strlen(uwsgi.hostname);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uwsgi.hostname, strlen(uwsgi.hostname));
|
||||
ptrbuf += strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
if (uwsgi.sockets && uwsgi.sockets->name) {
|
||||
ustrlen = strlen(key2);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key2, strlen(key2));
|
||||
ptrbuf += strlen(key2);
|
||||
if (uwsgi.sockets && uwsgi.sockets->name) {
|
||||
ustrlen = strlen(key2);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key2, strlen(key2));
|
||||
ptrbuf += strlen(key2);
|
||||
|
||||
ustrlen = strlen(uwsgi.sockets->name);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uwsgi.sockets->name, strlen(uwsgi.sockets->name));
|
||||
ptrbuf += strlen(uwsgi.sockets->name);
|
||||
}
|
||||
ustrlen = strlen(uwsgi.sockets->name);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uwsgi.sockets->name, strlen(uwsgi.sockets->name));
|
||||
ptrbuf += strlen(uwsgi.sockets->name);
|
||||
}
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
else if (uwsgi.zeromq) {
|
||||
ustrlen = strlen(key2);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key2, strlen(key2));
|
||||
ptrbuf += strlen(key2);
|
||||
else if (uwsgi.zeromq) {
|
||||
ustrlen = strlen(key2);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key2, strlen(key2));
|
||||
ptrbuf += strlen(key2);
|
||||
|
||||
ustrlen = strlen(uuid_zmq_str);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uuid_zmq_str, strlen(uuid_zmq_str));
|
||||
ptrbuf += strlen(uuid_zmq_str);
|
||||
}
|
||||
ustrlen = strlen(uuid_zmq_str);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uuid_zmq_str, strlen(uuid_zmq_str));
|
||||
ptrbuf += strlen(uuid_zmq_str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ustrlen = strlen(key3);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key3, strlen(key3));
|
||||
ptrbuf += strlen(key3);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key3, strlen(key3));
|
||||
ptrbuf += strlen(key3);
|
||||
|
||||
ustrlen = strlen(numproc);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, numproc, strlen(numproc));
|
||||
ptrbuf += strlen(numproc);
|
||||
ustrlen = strlen(numproc);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, numproc, strlen(numproc));
|
||||
ptrbuf += strlen(numproc);
|
||||
|
||||
ustrlen = strlen(key4);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key4, strlen(key4));
|
||||
ptrbuf += strlen(key4);
|
||||
ustrlen = strlen(key4);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key4, strlen(key4));
|
||||
ptrbuf += strlen(key4);
|
||||
|
||||
ustrlen = 1;
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, "0", 1);
|
||||
ptrbuf += 1;
|
||||
ustrlen = 1;
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, "0", 1);
|
||||
ptrbuf += 1;
|
||||
|
||||
|
||||
uwsgi_string_sendto(uwsgi.cluster_fd, 95, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), buf, len);
|
||||
uwsgi_string_sendto(uwsgi.cluster_fd, 95, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), buf, len);
|
||||
|
||||
free(buf);
|
||||
free(buf);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("add_me() successfull\n");
|
||||
uwsgi_log("add_me() successfull\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_cluster_join(char *name) {
|
||||
|
||||
int fd;
|
||||
char *cp;
|
||||
int broadcast = 0;
|
||||
int fd;
|
||||
char *cp;
|
||||
int broadcast = 0;
|
||||
|
||||
|
||||
|
||||
if (name[0] == ':') {
|
||||
fd = bind_to_udp(name, 0, 1);
|
||||
broadcast = 1;
|
||||
}
|
||||
else {
|
||||
fd = bind_to_udp(name, 1, 0);
|
||||
}
|
||||
if (name[0] == ':') {
|
||||
fd = bind_to_udp(name, 0, 1);
|
||||
broadcast = 1;
|
||||
}
|
||||
else {
|
||||
fd = bind_to_udp(name, 1, 0);
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
cp = strchr(name, ':');
|
||||
cp[0] = 0;
|
||||
uwsgi.mc_cluster_addr.sin_family = AF_INET;
|
||||
if (broadcast) {
|
||||
uwsgi.mc_cluster_addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
}
|
||||
else {
|
||||
uwsgi.mc_cluster_addr.sin_addr.s_addr = inet_addr(name);
|
||||
}
|
||||
uwsgi.mc_cluster_addr.sin_port = htons(atoi(cp + 1));
|
||||
cp[0] = ':';
|
||||
if (fd >= 0) {
|
||||
cp = strchr(name, ':');
|
||||
cp[0] = 0;
|
||||
uwsgi.mc_cluster_addr.sin_family = AF_INET;
|
||||
if (broadcast) {
|
||||
uwsgi.mc_cluster_addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
}
|
||||
else {
|
||||
uwsgi.mc_cluster_addr.sin_addr.s_addr = inet_addr(name);
|
||||
}
|
||||
uwsgi.mc_cluster_addr.sin_port = htons(atoi(cp + 1));
|
||||
cp[0] = ':';
|
||||
|
||||
|
||||
// announce my presence to all the nodes
|
||||
uwsgi_string_sendto(fd, 73, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), uwsgi.hostname, strlen(uwsgi.hostname));
|
||||
}
|
||||
else {
|
||||
exit(1);
|
||||
}
|
||||
// announce my presence to all the nodes
|
||||
uwsgi_string_sendto(fd, 73, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), uwsgi.hostname, strlen(uwsgi.hostname));
|
||||
}
|
||||
else {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
return fd;
|
||||
return fd;
|
||||
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_cluster_best_node() {
|
||||
|
||||
int i;
|
||||
int best_node = -1;
|
||||
struct uwsgi_cluster_node *ucn;
|
||||
int i;
|
||||
int best_node = -1;
|
||||
struct uwsgi_cluster_node *ucn;
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
if (ucn->name[0] != 0 && ucn->status == UWSGI_NODE_OK) {
|
||||
if (best_node == -1) {
|
||||
best_node = i;
|
||||
}
|
||||
else {
|
||||
if (ucn->last_choosen < uwsgi.shared->nodes[best_node].last_choosen) {
|
||||
best_node = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
if (ucn->name[0] != 0 && ucn->status == UWSGI_NODE_OK) {
|
||||
if (best_node == -1) {
|
||||
best_node = i;
|
||||
}
|
||||
else {
|
||||
if (ucn->last_choosen < uwsgi.shared->nodes[best_node].last_choosen) {
|
||||
best_node = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_node == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (best_node == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uwsgi.shared->nodes[best_node].last_choosen = uwsgi_now();
|
||||
return uwsgi.shared->nodes[best_node].name;
|
||||
uwsgi.shared->nodes[best_node].last_choosen = uwsgi_now();
|
||||
return uwsgi.shared->nodes[best_node].name;
|
||||
}
|
||||
|
||||
|
||||
void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) {
|
||||
|
||||
char *tmpstr;
|
||||
struct uwsgi_cluster_node *ucn = (struct uwsgi_cluster_node *) data;
|
||||
char *tmpstr;
|
||||
struct uwsgi_cluster_node *ucn = (struct uwsgi_cluster_node *) data;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%.*s = %.*s\n", keylen, key, vallen, val);
|
||||
uwsgi_log("%.*s = %.*s\n", keylen, key, vallen, val);
|
||||
#endif
|
||||
|
||||
if (!uwsgi_strncmp("hostname", 8, key, keylen)) {
|
||||
strncpy(ucn->nodename, val, UMIN(vallen, 255));
|
||||
}
|
||||
if (!uwsgi_strncmp("hostname", 8, key, keylen)) {
|
||||
strncpy(ucn->nodename, val, UMIN(vallen, 255));
|
||||
}
|
||||
|
||||
if (!uwsgi_strncmp("address", 7, key, keylen)) {
|
||||
strncpy(ucn->name, val, UMIN(vallen, 100));
|
||||
}
|
||||
if (!uwsgi_strncmp("address", 7, key, keylen)) {
|
||||
strncpy(ucn->name, val, UMIN(vallen, 100));
|
||||
}
|
||||
|
||||
if (!uwsgi_strncmp("workers", 7, key, keylen)) {
|
||||
tmpstr = uwsgi_concat2n(val, vallen, "", 0);
|
||||
ucn->workers = atoi(tmpstr);
|
||||
free(tmpstr);
|
||||
}
|
||||
if (!uwsgi_strncmp("workers", 7, key, keylen)) {
|
||||
tmpstr = uwsgi_concat2n(val, vallen, "", 0);
|
||||
ucn->workers = atoi(tmpstr);
|
||||
free(tmpstr);
|
||||
}
|
||||
|
||||
if (!uwsgi_strncmp("requests", 8, key, keylen)) {
|
||||
tmpstr = uwsgi_concat2n(val, vallen, "", 0);
|
||||
ucn->requests = strtoul(tmpstr, NULL, 0);
|
||||
free(tmpstr);
|
||||
}
|
||||
if (!uwsgi_strncmp("requests", 8, key, keylen)) {
|
||||
tmpstr = uwsgi_concat2n(val, vallen, "", 0);
|
||||
ucn->requests = strtoul(tmpstr, NULL, 0);
|
||||
free(tmpstr);
|
||||
}
|
||||
}
|
||||
|
||||
void manage_cluster_message(char *cluster_opt_buf, int cluster_opt_size) {
|
||||
|
||||
struct uwsgi_cluster_node nucn;
|
||||
struct uwsgi_cluster_node nucn;
|
||||
|
||||
switch (uwsgi.workers[0].cores[0].req.uh.modifier1) {
|
||||
case 95:
|
||||
memset(&nucn, 0, sizeof(struct uwsgi_cluster_node));
|
||||
switch (uwsgi.workers[0].cores[0].req.uh.modifier1) {
|
||||
case 95:
|
||||
memset(&nucn, 0, sizeof(struct uwsgi_cluster_node));
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize);
|
||||
uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize);
|
||||
#endif
|
||||
uwsgi_hooked_parse(uwsgi.workers[0].cores[0].req.buffer, uwsgi.workers[0].cores[0].req.uh.pktsize, manage_cluster_announce, &nucn);
|
||||
if (nucn.name[0] != 0) {
|
||||
uwsgi_cluster_add_node(&nucn, CLUSTER_NODE_DYNAMIC);
|
||||
}
|
||||
break;
|
||||
case 96:
|
||||
uwsgi_hooked_parse(uwsgi.workers[0].cores[0].req.buffer, uwsgi.workers[0].cores[0].req.uh.pktsize, manage_cluster_announce, &nucn);
|
||||
if (nucn.name[0] != 0) {
|
||||
uwsgi_cluster_add_node(&nucn, CLUSTER_NODE_DYNAMIC);
|
||||
}
|
||||
break;
|
||||
case 96:
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize);
|
||||
uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize);
|
||||
#endif
|
||||
uwsgi_log_verbose("%.*s\n", uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer);
|
||||
break;
|
||||
case 98:
|
||||
if (kill(getpid(), SIGHUP)) {
|
||||
uwsgi_error("kill()");
|
||||
}
|
||||
break;
|
||||
case 99:
|
||||
if (uwsgi.cluster_nodes)
|
||||
break;
|
||||
if (uwsgi.workers[0].cores[0].req.uh.modifier2 == 0) {
|
||||
uwsgi_log("requested configuration data, sending %d bytes\n", cluster_opt_size);
|
||||
sendto(uwsgi.cluster_fd, cluster_opt_buf, cluster_opt_size, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr));
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
uwsgi_log_verbose("%.*s\n", uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer);
|
||||
break;
|
||||
case 98:
|
||||
if (kill(getpid(), SIGHUP)) {
|
||||
uwsgi_error("kill()");
|
||||
}
|
||||
break;
|
||||
case 99:
|
||||
if (uwsgi.cluster_nodes)
|
||||
break;
|
||||
if (uwsgi.workers[0].cores[0].req.uh.modifier2 == 0) {
|
||||
uwsgi_log("requested configuration data, sending %d bytes\n", cluster_opt_size);
|
||||
sendto(uwsgi.cluster_fd, cluster_opt_buf, cluster_opt_size, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr));
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize);
|
||||
uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize);
|
||||
#endif
|
||||
uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer);
|
||||
break;
|
||||
}
|
||||
uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
char *uwsgi_setup_clusterbuf(size_t *size) {
|
||||
char *uwsgi_setup_clusterbuf(size_t * size) {
|
||||
|
||||
size_t cluster_opt_size = 4;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
//uwsgi_log("%s\n", uwsgi.exported_opts[i]->key);
|
||||
cluster_opt_size += 2 + strlen(uwsgi.exported_opts[i]->key);
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
cluster_opt_size += 2 + strlen(uwsgi.exported_opts[i]->value);
|
||||
}
|
||||
else {
|
||||
cluster_opt_size += 2 + 1;
|
||||
}
|
||||
}
|
||||
//uwsgi_log("%s\n", uwsgi.exported_opts[i]->key);
|
||||
cluster_opt_size += 2 + strlen(uwsgi.exported_opts[i]->key);
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
cluster_opt_size += 2 + strlen(uwsgi.exported_opts[i]->value);
|
||||
}
|
||||
else {
|
||||
cluster_opt_size += 2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//uwsgi_log("cluster opts size: %d\n", cluster_opt_size);
|
||||
char *cluster_opt_buf = uwsgi_malloc(cluster_opt_size);
|
||||
//uwsgi_log("cluster opts size: %d\n", cluster_opt_size);
|
||||
char *cluster_opt_buf = uwsgi_malloc(cluster_opt_size);
|
||||
|
||||
struct uwsgi_header *uh = (struct uwsgi_header *) cluster_opt_buf;
|
||||
struct uwsgi_header *uh = (struct uwsgi_header *) cluster_opt_buf;
|
||||
|
||||
uh->modifier1 = 99;
|
||||
uh->pktsize = cluster_opt_size - 4;
|
||||
uh->modifier2 = 1;
|
||||
uh->modifier1 = 99;
|
||||
uh->pktsize = cluster_opt_size - 4;
|
||||
uh->modifier2 = 1;
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh->pktsize = uwsgi_swap16(uh->pktsize);
|
||||
uh->pktsize = uwsgi_swap16(uh->pktsize);
|
||||
#endif
|
||||
|
||||
char *cptrbuf = cluster_opt_buf + 4;
|
||||
char *cptrbuf = cluster_opt_buf + 4;
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
//uwsgi_log("%s\n", uwsgi.exported_opts[i]->key);
|
||||
uint16_t ustrlen = strlen(uwsgi.exported_opts[i]->key);
|
||||
*cptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(cptrbuf, uwsgi.exported_opts[i]->key, ustrlen);
|
||||
cptrbuf += ustrlen;
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
//uwsgi_log("%s\n", uwsgi.exported_opts[i]->key);
|
||||
uint16_t ustrlen = strlen(uwsgi.exported_opts[i]->key);
|
||||
*cptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(cptrbuf, uwsgi.exported_opts[i]->key, ustrlen);
|
||||
cptrbuf += ustrlen;
|
||||
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
ustrlen = strlen(uwsgi.exported_opts[i]->value);
|
||||
*cptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(cptrbuf, uwsgi.exported_opts[i]->value, ustrlen);
|
||||
}
|
||||
else {
|
||||
ustrlen = 1;
|
||||
*cptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
*cptrbuf = '1';
|
||||
}
|
||||
cptrbuf += ustrlen;
|
||||
}
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
ustrlen = strlen(uwsgi.exported_opts[i]->value);
|
||||
*cptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(cptrbuf, uwsgi.exported_opts[i]->value, ustrlen);
|
||||
}
|
||||
else {
|
||||
ustrlen = 1;
|
||||
*cptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*cptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
*cptrbuf = '1';
|
||||
}
|
||||
cptrbuf += ustrlen;
|
||||
}
|
||||
|
||||
return cluster_opt_buf;
|
||||
return cluster_opt_buf;
|
||||
}
|
||||
|
||||
+127
-116
@@ -30,8 +30,18 @@ extern struct uwsgi_server uwsgi;
|
||||
*/
|
||||
|
||||
void uwsgi_daemons_smart_check() {
|
||||
static time_t last_run = 0;
|
||||
|
||||
time_t now = uwsgi_now();
|
||||
|
||||
if (now - last_run <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_run = now;
|
||||
|
||||
struct uwsgi_daemon *ud = uwsgi.daemons;
|
||||
while (ud) {
|
||||
while (ud) {
|
||||
if (ud->pidfile) {
|
||||
int checked_pid = uwsgi_check_pidfile(ud->pidfile);
|
||||
if (checked_pid <= 0) {
|
||||
@@ -41,14 +51,14 @@ void uwsgi_daemons_smart_check() {
|
||||
}
|
||||
else {
|
||||
ud->pidfile_checks++;
|
||||
if (ud->pidfile_checks >= (uint64_t) ud->freq) {
|
||||
if (ud->pidfile_checks >= (unsigned int) ud->freq) {
|
||||
uwsgi_log("[uwsgi-daemons] found changed pidfile for \"%s\" (old_pid: %d new_pid: %d)\n", ud->command, (int) ud->pid, (int) checked_pid);
|
||||
uwsgi_spawn_daemon(ud);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (checked_pid != ud->pid) {
|
||||
uwsgi_log("[uwsgi-daemons] found changed pidfile for \"%s\" (old_pid: %d new_pid: %d)\n", ud->command, (int) ud->pid, (int) checked_pid);
|
||||
uwsgi_log("[uwsgi-daemons] found changed pid for \"%s\" (old_pid: %d new_pid: %d)\n", ud->command, (int) ud->pid, (int) checked_pid);
|
||||
ud->pid = checked_pid;
|
||||
}
|
||||
// all ok, pidfile and process found
|
||||
@@ -63,12 +73,12 @@ void uwsgi_daemons_smart_check() {
|
||||
// this function is called when a dumb daemon dies and we do not wat to respawn it
|
||||
int uwsgi_daemon_check_pid_death(pid_t diedpid) {
|
||||
struct uwsgi_daemon *ud = uwsgi.daemons;
|
||||
while (ud) {
|
||||
if (ud->pid == diedpid && !ud->pidfile) {
|
||||
uwsgi_log("daemon \"%s\" (pid: %d) annihilated\n", ud->command, (int) diedpid);
|
||||
while (ud) {
|
||||
if (ud->pid == diedpid && !ud->pidfile) {
|
||||
uwsgi_log("daemon \"%s\" (pid: %d) annihilated\n", ud->command, (int) diedpid);
|
||||
return -1;
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -76,13 +86,13 @@ int uwsgi_daemon_check_pid_death(pid_t diedpid) {
|
||||
// this function is called when a dumb daemon dies and we want to respawn it
|
||||
int uwsgi_daemon_check_pid_reload(pid_t diedpid) {
|
||||
struct uwsgi_daemon *ud = uwsgi.daemons;
|
||||
while (ud) {
|
||||
if (ud->pid == diedpid && !ud->pidfile) {
|
||||
uwsgi_spawn_daemon(ud);
|
||||
while (ud) {
|
||||
if (ud->pid == diedpid && !ud->pidfile) {
|
||||
uwsgi_spawn_daemon(ud);
|
||||
return 1;
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -97,16 +107,17 @@ int uwsgi_check_pidfile(char *filename) {
|
||||
goto end;
|
||||
}
|
||||
if (fstat(fd, &st)) {
|
||||
uwsgi_error("fstat()");
|
||||
goto end2;
|
||||
}
|
||||
char *pidstr = uwsgi_calloc(st.st_size+1);
|
||||
uwsgi_error("fstat()");
|
||||
goto end2;
|
||||
}
|
||||
char *pidstr = uwsgi_calloc(st.st_size + 1);
|
||||
if (read(fd, pidstr, st.st_size) != st.st_size) {
|
||||
uwsgi_error("read()");
|
||||
goto end3;
|
||||
}
|
||||
pid_t pid = atoi(pidstr);
|
||||
if (pid <= 0) goto end3;
|
||||
if (pid <= 0)
|
||||
goto end3;
|
||||
if (!kill(pid, 0)) {
|
||||
ret = pid;
|
||||
}
|
||||
@@ -120,8 +131,8 @@ end:
|
||||
|
||||
void uwsgi_daemons_spawn_all() {
|
||||
struct uwsgi_daemon *ud = uwsgi.daemons;
|
||||
while (ud) {
|
||||
if (!ud->registered) {
|
||||
while (ud) {
|
||||
if (!ud->registered) {
|
||||
if (ud->pidfile) {
|
||||
int checked_pid = uwsgi_check_pidfile(ud->pidfile);
|
||||
if (checked_pid <= 0) {
|
||||
@@ -133,117 +144,118 @@ void uwsgi_daemons_spawn_all() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_spawn_daemon(ud);
|
||||
uwsgi_spawn_daemon(ud);
|
||||
}
|
||||
ud->registered = 1;
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
ud->registered = 1;
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_detach_daemons() {
|
||||
struct uwsgi_daemon *ud = uwsgi.daemons;
|
||||
while (ud) {
|
||||
if (ud->pid > 0 && !ud->pidfile)
|
||||
kill(-ud->pid, SIGKILL);
|
||||
ud = ud->next;
|
||||
}
|
||||
while (ud) {
|
||||
if (ud->pid > 0 && !ud->pidfile)
|
||||
kill(-ud->pid, SIGKILL);
|
||||
ud = ud->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {
|
||||
|
||||
int devnull = -1;
|
||||
int throttle = 0;
|
||||
int devnull = -1;
|
||||
int throttle = 0;
|
||||
|
||||
if (uwsgi.current_time - ud->last_spawn <= 3) {
|
||||
throttle = ud->respawns - (uwsgi.current_time - ud->last_spawn);
|
||||
}
|
||||
if (uwsgi.current_time - ud->last_spawn <= 3) {
|
||||
throttle = ud->respawns - (uwsgi.current_time - ud->last_spawn);
|
||||
}
|
||||
|
||||
pid_t pid = uwsgi_fork("uWSGI external daemon");
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
return;
|
||||
}
|
||||
pid_t pid = uwsgi_fork("uWSGI external daemon");
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
ud->pid = pid;
|
||||
ud->status = 1;
|
||||
if (pid > 0) {
|
||||
ud->pid = pid;
|
||||
ud->status = 1;
|
||||
ud->pidfile_checks = 0;
|
||||
if (ud->respawns == 0) {
|
||||
ud->born = uwsgi_now();
|
||||
}
|
||||
if (ud->respawns == 0) {
|
||||
ud->born = uwsgi_now();
|
||||
}
|
||||
|
||||
ud->respawns++;
|
||||
ud->last_spawn = uwsgi_now();
|
||||
ud->respawns++;
|
||||
ud->last_spawn = uwsgi_now();
|
||||
|
||||
}
|
||||
else {
|
||||
// close uwsgi sockets
|
||||
uwsgi_close_all_sockets();
|
||||
}
|
||||
else {
|
||||
// close uwsgi sockets
|
||||
uwsgi_close_all_sockets();
|
||||
uwsgi_close_all_fds();
|
||||
|
||||
if (ud->daemonize) {
|
||||
/* refork... */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
exit(1);
|
||||
}
|
||||
if (pid != 0) {
|
||||
_exit(0);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
exit(1);
|
||||
}
|
||||
if (pid != 0) {
|
||||
_exit(0);
|
||||
}
|
||||
uwsgi_write_pidfile(ud->pidfile);
|
||||
}
|
||||
|
||||
// /dev/null will became stdin
|
||||
devnull = open("/dev/null", O_RDONLY);
|
||||
if (devnull < 0) {
|
||||
uwsgi_error("/dev/null open()");
|
||||
exit(1);
|
||||
}
|
||||
if (devnull != 0) {
|
||||
if (dup2(devnull, 0)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(devnull);
|
||||
}
|
||||
// /dev/null will became stdin
|
||||
devnull = open("/dev/null", O_RDONLY);
|
||||
if (devnull < 0) {
|
||||
uwsgi_error("/dev/null open()");
|
||||
exit(1);
|
||||
}
|
||||
if (devnull != 0) {
|
||||
if (dup2(devnull, 0)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(devnull);
|
||||
}
|
||||
|
||||
if (setsid() < 0) {
|
||||
uwsgi_error("setsid()");
|
||||
exit(1);
|
||||
}
|
||||
if (setsid() < 0) {
|
||||
uwsgi_error("setsid()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!ud->pidfile) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (throttle) {
|
||||
uwsgi_log("[uwsgi-daemons] throttling \"%s\" for %d seconds\n", ud->command, throttle);
|
||||
sleep(throttle);
|
||||
}
|
||||
if (throttle) {
|
||||
uwsgi_log("[uwsgi-daemons] throttling \"%s\" for %d seconds\n", ud->command, throttle);
|
||||
sleep(throttle);
|
||||
}
|
||||
|
||||
uwsgi_log("[uwsgi-daemons] %sspawning \"%s\"\n", ud->respawns > 0 ? "re":"", ud->command);
|
||||
uwsgi_log("[uwsgi-daemons] %sspawning \"%s\"\n", ud->respawns > 0 ? "re" : "", ud->command);
|
||||
uwsgi_exec_command_with_args(ud->command);
|
||||
uwsgi_log("[uwsgi-daemons] unable to spawn \"%s\"\n", ud->command);
|
||||
uwsgi_log("[uwsgi-daemons] unable to spawn \"%s\"\n", ud->command);
|
||||
|
||||
// never here;
|
||||
exit(1);
|
||||
}
|
||||
// never here;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_opt_add_daemon(char *opt, char *value, void *none) {
|
||||
|
||||
struct uwsgi_daemon *uwsgi_ud = uwsgi.daemons, *old_ud;
|
||||
struct uwsgi_daemon *uwsgi_ud = uwsgi.daemons, *old_ud;
|
||||
char *pidfile = NULL;
|
||||
int daemonize = 0;
|
||||
int freq = 10;
|
||||
@@ -253,7 +265,7 @@ void uwsgi_opt_add_daemon(char *opt, char *value, void *none) {
|
||||
if (!strcmp(opt, "smart-attach-daemon") || !strcmp(opt, "smart-attach-daemon2")) {
|
||||
char *space = strchr(command, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid smart-attach-daemon syntax: %s\n", command);
|
||||
uwsgi_log("invalid smart-attach-daemon syntax: %s\n", command);
|
||||
exit(1);
|
||||
}
|
||||
*space = 0;
|
||||
@@ -262,7 +274,7 @@ void uwsgi_opt_add_daemon(char *opt, char *value, void *none) {
|
||||
char *comma = strchr(pidfile, ',');
|
||||
if (comma) {
|
||||
*comma = 0;
|
||||
freq = atoi(comma+1);
|
||||
freq = atoi(comma + 1);
|
||||
}
|
||||
command = space + 1;
|
||||
if (!strcmp(opt, "smart-attach-daemon2")) {
|
||||
@@ -270,32 +282,31 @@ void uwsgi_opt_add_daemon(char *opt, char *value, void *none) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!uwsgi_ud) {
|
||||
uwsgi.daemons = uwsgi_malloc(sizeof(struct uwsgi_daemon));
|
||||
uwsgi_ud = uwsgi.daemons;
|
||||
}
|
||||
else {
|
||||
while (uwsgi_ud) {
|
||||
old_ud = uwsgi_ud;
|
||||
uwsgi_ud = uwsgi_ud->next;
|
||||
}
|
||||
if (!uwsgi_ud) {
|
||||
uwsgi.daemons = uwsgi_malloc(sizeof(struct uwsgi_daemon));
|
||||
uwsgi_ud = uwsgi.daemons;
|
||||
}
|
||||
else {
|
||||
while (uwsgi_ud) {
|
||||
old_ud = uwsgi_ud;
|
||||
uwsgi_ud = uwsgi_ud->next;
|
||||
}
|
||||
|
||||
uwsgi_ud = uwsgi_malloc(sizeof(struct uwsgi_daemon));
|
||||
old_ud->next = uwsgi_ud;
|
||||
}
|
||||
uwsgi_ud = uwsgi_malloc(sizeof(struct uwsgi_daemon));
|
||||
old_ud->next = uwsgi_ud;
|
||||
}
|
||||
|
||||
uwsgi_ud->command = command;
|
||||
uwsgi_ud->pid = 0;
|
||||
uwsgi_ud->status = 0;
|
||||
uwsgi_ud->freq = freq;
|
||||
uwsgi_ud->registered = 0;
|
||||
uwsgi_ud->next = NULL;
|
||||
uwsgi_ud->respawns = 0;
|
||||
uwsgi_ud->last_spawn = 0;
|
||||
uwsgi_ud->command = command;
|
||||
uwsgi_ud->pid = 0;
|
||||
uwsgi_ud->status = 0;
|
||||
uwsgi_ud->freq = freq;
|
||||
uwsgi_ud->registered = 0;
|
||||
uwsgi_ud->next = NULL;
|
||||
uwsgi_ud->respawns = 0;
|
||||
uwsgi_ud->last_spawn = 0;
|
||||
uwsgi_ud->daemonize = daemonize;
|
||||
uwsgi_ud->pidfile = pidfile;
|
||||
|
||||
uwsgi.daemons_cnt++;
|
||||
uwsgi.daemons_cnt++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+155
-158
@@ -125,17 +125,12 @@ struct uwsgi_emperor_scanner *emperor_scanners;
|
||||
|
||||
int uwsgi_emperor_is_valid(char *name) {
|
||||
|
||||
if (uwsgi_endswith(name, ".xml") ||
|
||||
uwsgi_endswith(name, ".ini") ||
|
||||
uwsgi_endswith(name, ".yml") ||
|
||||
uwsgi_endswith(name, ".yaml") ||
|
||||
uwsgi_endswith(name, ".js") ||
|
||||
uwsgi_endswith(name, ".json")) {
|
||||
if (uwsgi_endswith(name, ".xml") || uwsgi_endswith(name, ".ini") || uwsgi_endswith(name, ".yml") || uwsgi_endswith(name, ".yaml") || uwsgi_endswith(name, ".js") || uwsgi_endswith(name, ".json")) {
|
||||
|
||||
|
||||
if (strlen(name) < 0xff) {
|
||||
return 1;
|
||||
}
|
||||
if (strlen(name) < 0xff) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -155,48 +150,48 @@ void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *ues) {
|
||||
DIR *dir = opendir(".");
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
|
||||
if (!uwsgi_emperor_is_valid(de->d_name))
|
||||
continue;
|
||||
if (!uwsgi_emperor_is_valid(de->d_name))
|
||||
continue;
|
||||
|
||||
if (stat(de->d_name, &st))
|
||||
continue;
|
||||
if (stat(de->d_name, &st))
|
||||
continue;
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
|
||||
ui_current = emperor_get(de->d_name);
|
||||
ui_current = emperor_get(de->d_name);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, stop the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", de->d_name);
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, stop the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", de->d_name);
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
// now check for removed instances
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
|
||||
while (c_ui) {
|
||||
while (c_ui) {
|
||||
if (c_ui->scanner == ues) {
|
||||
if (stat(c_ui->name, &st)) {
|
||||
emperor_stop(c_ui);
|
||||
}
|
||||
}
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
}
|
||||
|
||||
// this is the monitor for glob patterns
|
||||
@@ -213,50 +208,50 @@ void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *ues) {
|
||||
}
|
||||
|
||||
for (i = 0; i < (int) g.gl_pathc; i++) {
|
||||
|
||||
if (!uwsgi_emperor_is_valid(g.gl_pathv[i]))
|
||||
continue;
|
||||
|
||||
if (stat(g.gl_pathv[i], &st))
|
||||
continue;
|
||||
if (!uwsgi_emperor_is_valid(g.gl_pathv[i]))
|
||||
continue;
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
if (stat(g.gl_pathv[i], &st))
|
||||
continue;
|
||||
|
||||
ui_current = emperor_get(g.gl_pathv[i]);
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, stop the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]);
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
ui_current = emperor_get(g.gl_pathv[i]);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, stop the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]);
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
}
|
||||
|
||||
}
|
||||
globfree(&g);
|
||||
|
||||
// now check for removed instances
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
|
||||
while (c_ui) {
|
||||
if (c_ui->scanner == ues) {
|
||||
if (stat(c_ui->name, &st)) {
|
||||
emperor_stop(c_ui);
|
||||
}
|
||||
}
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
while (c_ui) {
|
||||
if (c_ui->scanner == ues) {
|
||||
if (stat(c_ui->name, &st)) {
|
||||
emperor_stop(c_ui);
|
||||
}
|
||||
}
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -308,7 +303,7 @@ static void royal_death(int signum) {
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_log("[emperor] *** RAGNAROK EVOKED ***\n");
|
||||
uwsgi_log("[emperor] *** RAGNAROK EVOKED ***\n");
|
||||
uwsgi_notify("The Emperor is buried.");
|
||||
exit(0);
|
||||
}
|
||||
@@ -768,14 +763,14 @@ void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *ues) {
|
||||
uwsgi.emperor_absolute_dir = uwsgi.cwd;
|
||||
|
||||
if (!uwsgi_startswith(ues->arg, "glob://", 7)) {
|
||||
ues->arg+=7;
|
||||
ues->arg += 7;
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *ues) {
|
||||
|
||||
if (!uwsgi_startswith(ues->arg, "dir://", 6)) {
|
||||
ues->arg+=6;
|
||||
ues->arg += 6;
|
||||
}
|
||||
|
||||
if (chdir(ues->arg)) {
|
||||
@@ -789,6 +784,8 @@ void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *ues) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ues->arg = uwsgi.emperor_absolute_dir;
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_imperial_monitor *imperial_monitor_get_by_id(char *scheme) {
|
||||
@@ -881,13 +878,13 @@ next:
|
||||
int uwsgi_emperor_scanner_event(int fd) {
|
||||
|
||||
struct uwsgi_emperor_scanner *ues = emperor_scanners;
|
||||
while (ues) {
|
||||
while (ues) {
|
||||
if (ues->fd > -1 && ues->fd == fd) {
|
||||
ues->event_func(ues);
|
||||
return 1;
|
||||
}
|
||||
ues = ues->next;
|
||||
}
|
||||
ues = ues->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -993,9 +990,10 @@ void emperor_loop() {
|
||||
}
|
||||
|
||||
// check if a monitor is mapped to that file descriptor
|
||||
if (uwsgi_emperor_scanner_event(interesting_fd)) continue;
|
||||
if (uwsgi_emperor_scanner_event(interesting_fd))
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
ui_current = emperor_get_by_fd(interesting_fd);
|
||||
if (ui_current) {
|
||||
char byte;
|
||||
@@ -1041,9 +1039,9 @@ void emperor_loop() {
|
||||
|
||||
// check for heartbeat (if required)
|
||||
ui_current = ui->ui_next;
|
||||
while(ui_current) {
|
||||
while (ui_current) {
|
||||
if (ui_current->last_heartbeat > 0) {
|
||||
if ( (ui_current->last_heartbeat + uwsgi.emperor_heartbeat) < uwsgi_now()) {
|
||||
if ((ui_current->last_heartbeat + uwsgi.emperor_heartbeat) < uwsgi_now()) {
|
||||
uwsgi_log("[emperor] vassal %s sent no heartbeat in last %d seconds, respawning it...\n", ui_current->name, uwsgi.emperor_heartbeat);
|
||||
// set last_heartbeat to 0 avoiding races
|
||||
ui_current->last_heartbeat = 0;
|
||||
@@ -1085,7 +1083,7 @@ void emperor_loop() {
|
||||
struct uwsgi_instance *rebel_vassal = ui_current;
|
||||
ui_current = ui_current->ui_next;
|
||||
emperor_del(rebel_vassal);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_error("waitpid()");
|
||||
@@ -1143,11 +1141,11 @@ void emperor_send_stats(int fd) {
|
||||
}
|
||||
|
||||
if (uwsgi.stats_http) {
|
||||
if (uwsgi_send_http_stats(client_fd)) {
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (uwsgi_send_http_stats(client_fd)) {
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_stats *us = uwsgi_stats_new(8192);
|
||||
|
||||
@@ -1250,49 +1248,49 @@ void emperor_send_stats(int fd) {
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end0;
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_key(us, "blacklist"))
|
||||
goto end0;
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end0;
|
||||
goto end0;
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end0;
|
||||
|
||||
struct uwsgi_emperor_blacklist_item *uebi = emperor_blacklist;
|
||||
while (uebi) {
|
||||
while (uebi) {
|
||||
|
||||
if (uwsgi_stats_object_open(us))
|
||||
goto end0;
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keyval_comma(us, "id", uebi->id))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keyval_comma(us, "id", uebi->id))
|
||||
goto end0;
|
||||
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "throttle_level", uebi->throttle_level/1000))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keylong_comma(us, "throttle_level", uebi->throttle_level / 1000))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "attempt", (unsigned long long) uebi->attempt))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keylong_comma(us, "attempt", (unsigned long long) uebi->attempt))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "first_attempt", (unsigned long long) uebi->first_attempt.tv_sec))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keylong_comma(us, "first_attempt", (unsigned long long) uebi->first_attempt.tv_sec))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "last_attempt", (unsigned long long) uebi->last_attempt.tv_sec))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keylong(us, "last_attempt", (unsigned long long) uebi->last_attempt.tv_sec))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_object_close(us))
|
||||
goto end0;
|
||||
goto end0;
|
||||
|
||||
|
||||
uebi = uebi->next;
|
||||
uebi = uebi->next;
|
||||
if (uebi) {
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi_stats_list_close(us))
|
||||
goto end0;
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_object_close(us))
|
||||
goto end0;
|
||||
@@ -1301,9 +1299,9 @@ void emperor_send_stats(int fd) {
|
||||
off_t pos = 0;
|
||||
while (remains > 0) {
|
||||
int ret = uwsgi_waitfd_write(client_fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (ret <= 0) {
|
||||
goto end0;
|
||||
}
|
||||
if (ret <= 0) {
|
||||
goto end0;
|
||||
}
|
||||
ssize_t res = write(client_fd, us->base + pos, remains);
|
||||
if (res <= 0) {
|
||||
if (res < 0) {
|
||||
@@ -1326,75 +1324,74 @@ end:
|
||||
void uwsgi_emperor_start() {
|
||||
|
||||
if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.master_process) {
|
||||
uwsgi_notify_ready();
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_notify_ready();
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
|
||||
if (uwsgi.emperor_pid < 0) {
|
||||
uwsgi_error("pid()");
|
||||
exit(1);
|
||||
}
|
||||
else if (uwsgi.emperor_pid == 0) {
|
||||
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
|
||||
if (uwsgi.emperor_pid < 0) {
|
||||
uwsgi_error("pid()");
|
||||
exit(1);
|
||||
}
|
||||
else if (uwsgi.emperor_pid == 0) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_check_emperor() {
|
||||
char *emperor_env = getenv("UWSGI_EMPEROR_FD");
|
||||
if (emperor_env) {
|
||||
uwsgi.has_emperor = 1;
|
||||
uwsgi.emperor_fd = atoi(emperor_env);
|
||||
uwsgi.master_process = 1;
|
||||
uwsgi.no_orphans = 1;
|
||||
uwsgi_log("*** has_emperor mode detected (fd: %d) ***\n", uwsgi.emperor_fd);
|
||||
if (emperor_env) {
|
||||
uwsgi.has_emperor = 1;
|
||||
uwsgi.emperor_fd = atoi(emperor_env);
|
||||
uwsgi.master_process = 1;
|
||||
uwsgi.no_orphans = 1;
|
||||
uwsgi_log("*** has_emperor mode detected (fd: %d) ***\n", uwsgi.emperor_fd);
|
||||
|
||||
if (getenv("UWSGI_EMPEROR_FD_CONFIG")) {
|
||||
uwsgi.emperor_fd_config = atoi(getenv("UWSGI_EMPEROR_FD_CONFIG"));
|
||||
}
|
||||
}
|
||||
if (getenv("UWSGI_EMPEROR_FD_CONFIG")) {
|
||||
uwsgi.emperor_fd_config = atoi(getenv("UWSGI_EMPEROR_FD_CONFIG"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char *config, time_t ts, uid_t uid, gid_t gid) {
|
||||
|
||||
if (!uwsgi_emperor_is_valid(name))
|
||||
return;
|
||||
if (!uwsgi_emperor_is_valid(name))
|
||||
return;
|
||||
|
||||
struct uwsgi_instance *ui_current = emperor_get(name);
|
||||
struct uwsgi_instance *ui_current = emperor_get(name);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, stop the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (uid != ui_current->uid || gid != ui_current->gid) {
|
||||
uwsgi_log("[emperor-tyrant] !!! permissions of vassal %s changed. stopping the instance... !!!\n", name);
|
||||
emperor_stop(ui_current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (ts > ui_current->last_mod) {
|
||||
// make a new config (free the old one)
|
||||
free(ui_current->config);
|
||||
ui_current->config = config;
|
||||
ui_current->config_len = strlen(config);
|
||||
// always respawn (no need for amqp-style rules)
|
||||
emperor_respawn(ui_current, ts);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// make a copy of the config as it will be freed
|
||||
emperor_add(ues, name, ts, uwsgi_str(config), strlen((const char *)config), uid, gid);
|
||||
}
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, stop the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (uid != ui_current->uid || gid != ui_current->gid) {
|
||||
uwsgi_log("[emperor-tyrant] !!! permissions of vassal %s changed. stopping the instance... !!!\n", name);
|
||||
emperor_stop(ui_current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (ts > ui_current->last_mod) {
|
||||
// make a new config (free the old one)
|
||||
free(ui_current->config);
|
||||
ui_current->config = config;
|
||||
ui_current->config_len = strlen(config);
|
||||
// always respawn (no need for amqp-style rules)
|
||||
emperor_respawn(ui_current, ts);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// make a copy of the config as it will be freed
|
||||
emperor_add(ues, name, ts, uwsgi_str(config), strlen((const char *) config), uid, gid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+414
-410
File diff suppressed because it is too large
Load Diff
+80
-80
@@ -2,29 +2,29 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_gateway *register_gateway(char *name, void (*loop)(int, void *), void *data) {
|
||||
struct uwsgi_gateway *register_gateway(char *name, void (*loop) (int, void *), void *data) {
|
||||
|
||||
struct uwsgi_gateway *ug;
|
||||
int num=1,i;
|
||||
struct uwsgi_gateway *ug;
|
||||
int num = 1, i;
|
||||
|
||||
if (ushared->gateways_cnt >= MAX_GATEWAYS) {
|
||||
uwsgi_log("you can register max %d gateways\n", MAX_GATEWAYS);
|
||||
return NULL;
|
||||
}
|
||||
if (ushared->gateways_cnt >= MAX_GATEWAYS) {
|
||||
uwsgi_log("you can register max %d gateways\n", MAX_GATEWAYS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i=0;i<ushared->gateways_cnt;i++) {
|
||||
if (!strcmp(name, ushared->gateways[i].name)) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ushared->gateways_cnt; i++) {
|
||||
if (!strcmp(name, ushared->gateways[i].name)) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
char *fullname = uwsgi_concat3(name, " ", uwsgi_num2str(num));
|
||||
|
||||
ug = &ushared->gateways[ushared->gateways_cnt];
|
||||
ug->pid = 0;
|
||||
ug->name = name;
|
||||
ug->loop = loop;
|
||||
ug->num = num;
|
||||
ug = &ushared->gateways[ushared->gateways_cnt];
|
||||
ug->pid = 0;
|
||||
ug->name = name;
|
||||
ug->loop = loop;
|
||||
ug->num = num;
|
||||
ug->fullname = fullname;
|
||||
ug->data = data;
|
||||
|
||||
@@ -35,10 +35,10 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(int, void *), vo
|
||||
if (!uwsgi.master_process)
|
||||
gateway_respawn(ushared->gateways_cnt);
|
||||
|
||||
ushared->gateways_cnt++;
|
||||
ushared->gateways_cnt++;
|
||||
|
||||
|
||||
return ug;
|
||||
return ug;
|
||||
}
|
||||
|
||||
void gateway_respawn(int id) {
|
||||
@@ -48,114 +48,114 @@ void gateway_respawn(int id) {
|
||||
|
||||
if (uwsgi.master_process)
|
||||
uwsgi.shared->gateways_harakiri[id] = 0;
|
||||
|
||||
|
||||
gw_pid = uwsgi_fork(ug->fullname);
|
||||
if (gw_pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
uwsgi_error("fork()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (gw_pid == 0) {
|
||||
uwsgi_fixup_fds(0, 0, ug);
|
||||
if (uwsgi.master_as_root) uwsgi_as_root();
|
||||
if (uwsgi.master_as_root)
|
||||
uwsgi_as_root();
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
uwsgi.mypid = getpid();
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, end_me);
|
||||
signal(SIGTERM, end_me);
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
signal(SIGUSR2, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGSTOP, SIG_IGN);
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, end_me);
|
||||
signal(SIGTERM, end_me);
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
signal(SIGUSR2, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGSTOP, SIG_IGN);
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
|
||||
ug->loop(id, ug->data);
|
||||
// never here !!! (i hope)
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ug->pid = gw_pid;
|
||||
ug->respawns++;
|
||||
if (ug->respawns == 1) {
|
||||
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
|
||||
uwsgi_log("spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "respawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
|
||||
uwsgi_log("respawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_gateway_socket *uwsgi_new_gateway_socket(char *name, char *owner) {
|
||||
|
||||
struct uwsgi_gateway_socket *uwsgi_sock = uwsgi.gateway_sockets, *old_uwsgi_sock;
|
||||
struct uwsgi_gateway_socket *uwsgi_sock = uwsgi.gateway_sockets, *old_uwsgi_sock;
|
||||
|
||||
if (!uwsgi_sock) {
|
||||
uwsgi.gateway_sockets = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
uwsgi_sock = uwsgi.gateway_sockets;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_sock) {
|
||||
old_uwsgi_sock = uwsgi_sock;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
if (!uwsgi_sock) {
|
||||
uwsgi.gateway_sockets = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
uwsgi_sock = uwsgi.gateway_sockets;
|
||||
}
|
||||
else {
|
||||
while (uwsgi_sock) {
|
||||
old_uwsgi_sock = uwsgi_sock;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
old_uwsgi_sock->next = uwsgi_sock;
|
||||
}
|
||||
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
old_uwsgi_sock->next = uwsgi_sock;
|
||||
}
|
||||
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_gateway_socket));
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_gateway_socket));
|
||||
uwsgi_sock->fd = -1;
|
||||
uwsgi_sock->shared = 0;
|
||||
uwsgi_sock->name = name;
|
||||
uwsgi_sock->name = name;
|
||||
uwsgi_sock->name_len = strlen(name);
|
||||
uwsgi_sock->owner = owner;
|
||||
|
||||
return uwsgi_sock;
|
||||
return uwsgi_sock;
|
||||
}
|
||||
|
||||
struct uwsgi_gateway_socket *uwsgi_new_gateway_socket_from_fd(int fd, char *owner) {
|
||||
|
||||
struct uwsgi_gateway_socket *uwsgi_sock = uwsgi.gateway_sockets, *old_uwsgi_sock;
|
||||
struct uwsgi_gateway_socket *uwsgi_sock = uwsgi.gateway_sockets, *old_uwsgi_sock;
|
||||
|
||||
if (!uwsgi_sock) {
|
||||
uwsgi.gateway_sockets = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
uwsgi_sock = uwsgi.gateway_sockets;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_sock) {
|
||||
old_uwsgi_sock = uwsgi_sock;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
if (!uwsgi_sock) {
|
||||
uwsgi.gateway_sockets = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
uwsgi_sock = uwsgi.gateway_sockets;
|
||||
}
|
||||
else {
|
||||
while (uwsgi_sock) {
|
||||
old_uwsgi_sock = uwsgi_sock;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
old_uwsgi_sock->next = uwsgi_sock;
|
||||
}
|
||||
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
|
||||
old_uwsgi_sock->next = uwsgi_sock;
|
||||
}
|
||||
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_gateway_socket));
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_gateway_socket));
|
||||
uwsgi_sock->fd = fd;
|
||||
uwsgi_sock->name = uwsgi_getsockname(fd);
|
||||
uwsgi_sock->name = uwsgi_getsockname(fd);
|
||||
uwsgi_sock->name_len = strlen(uwsgi_sock->name);
|
||||
uwsgi_sock->owner = owner;
|
||||
uwsgi_sock->owner = owner;
|
||||
|
||||
return uwsgi_sock;
|
||||
return uwsgi_sock;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_gateway_go_cheap(char *gw_id, int queue, int *i_am_cheap) {
|
||||
|
||||
uwsgi_log("[%s pid %d] no more nodes available. Going cheap...\n", gw_id, (int) uwsgi.mypid);
|
||||
struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
|
||||
while (ugs) {
|
||||
if (!strcmp(ugs->owner, gw_id) && !ugs->subscription) {
|
||||
event_queue_del_fd(queue, ugs->fd, event_queue_read());
|
||||
}
|
||||
ugs = ugs->next;
|
||||
}
|
||||
*i_am_cheap = 1;
|
||||
uwsgi_log("[%s pid %d] no more nodes available. Going cheap...\n", gw_id, (int) uwsgi.mypid);
|
||||
struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
|
||||
while (ugs) {
|
||||
if (!strcmp(ugs->owner, gw_id) && !ugs->subscription) {
|
||||
event_queue_del_fd(queue, ugs->fd, event_queue_read());
|
||||
}
|
||||
ugs = ugs->next;
|
||||
}
|
||||
*i_am_cheap = 1;
|
||||
}
|
||||
|
||||
|
||||
+16
-15
@@ -13,7 +13,7 @@ void ini_rstrip(char *line) {
|
||||
|
||||
off_t i;
|
||||
|
||||
for(i = strlen(line)-1;i>=0; i--) {
|
||||
for (i = strlen(line) - 1; i >= 0; i--) {
|
||||
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
|
||||
line[i] = 0;
|
||||
continue;
|
||||
@@ -27,7 +27,7 @@ char *ini_lstrip(char *line) {
|
||||
off_t i;
|
||||
char *ptr = line;
|
||||
|
||||
for(i=0;i< (int) strlen(line);i++) {
|
||||
for (i = 0; i < (int) strlen(line); i++) {
|
||||
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
|
||||
ptr++;
|
||||
continue;
|
||||
@@ -43,7 +43,7 @@ char *ini_get_key(char *key) {
|
||||
off_t i;
|
||||
char *ptr = key;
|
||||
|
||||
for(i=0;i< (int) strlen(key);i++) {
|
||||
for (i = 0; i < (int) strlen(key); i++) {
|
||||
ptr++;
|
||||
if (key[i] == '=') {
|
||||
key[i] = 0;
|
||||
@@ -59,7 +59,7 @@ char *ini_get_line(char *ini, off_t size) {
|
||||
off_t i;
|
||||
char *ptr = ini;
|
||||
|
||||
for(i=0;i<size;i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
ptr++;
|
||||
if (ini[i] == '\n') {
|
||||
ini[i] = 0;
|
||||
@@ -92,18 +92,19 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
|
||||
if (uwsgi_check_scheme(file)) {
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(file, ':');
|
||||
}
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(file, ':');
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
if (colon[1] != 0) {
|
||||
section_asked = colon+1;
|
||||
section_asked = colon + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
|
||||
ini = uwsgi_open_and_read(file, &len, 1, magic_table);
|
||||
|
||||
while(len) {
|
||||
while (len) {
|
||||
ini_line = ini_get_line(ini, len);
|
||||
if (ini_line == NULL) {
|
||||
break;
|
||||
@@ -125,8 +126,8 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
ini_rstrip(key);
|
||||
if (key[0] != 0) {
|
||||
if (key[0] == '[') {
|
||||
section = key+1;
|
||||
section[strlen(section)-1] = 0;
|
||||
section = key + 1;
|
||||
section[strlen(section) - 1] = 0;
|
||||
}
|
||||
else if (key[0] == ';' || key[0] == '#') {
|
||||
// this is a comment
|
||||
@@ -139,7 +140,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
ini_rstrip(key);
|
||||
val = ini_lstrip(val);
|
||||
ini_rstrip(val);
|
||||
add_exported_option((char *)key, val, 0);
|
||||
add_exported_option((char *) key, val, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+189
-187
@@ -7,73 +7,75 @@ void uwsgi_init_default() {
|
||||
uwsgi.cpus = 1;
|
||||
|
||||
uwsgi.backtrace_depth = 64;
|
||||
uwsgi.max_apps = 64;
|
||||
uwsgi.max_apps = 64;
|
||||
|
||||
uwsgi.master_queue = -1;
|
||||
uwsgi.master_queue = -1;
|
||||
|
||||
uwsgi.signal_socket = -1;
|
||||
uwsgi.my_signal_socket = -1;
|
||||
uwsgi.cache_server_fd = -1;
|
||||
uwsgi.stats_fd = -1;
|
||||
uwsgi.signal_socket = -1;
|
||||
uwsgi.my_signal_socket = -1;
|
||||
uwsgi.cache_server_fd = -1;
|
||||
uwsgi.stats_fd = -1;
|
||||
|
||||
uwsgi.stats_pusher_default_freq = 3;
|
||||
|
||||
uwsgi.original_log_fd = -1;
|
||||
uwsgi.original_log_fd = -1;
|
||||
|
||||
uwsgi.emperor_fd_config = -1;
|
||||
// default emperor scan frequency
|
||||
uwsgi.emperor_freq = 3;
|
||||
uwsgi.emperor_throttle = 1000;
|
||||
uwsgi.emperor_heartbeat = 30;
|
||||
// max 3 minutes throttling
|
||||
uwsgi.emperor_max_throttle = 1000 * 180;
|
||||
uwsgi.emperor_pid = -1;
|
||||
uwsgi.emperor_fd_config = -1;
|
||||
// default emperor scan frequency
|
||||
uwsgi.emperor_freq = 3;
|
||||
uwsgi.emperor_throttle = 1000;
|
||||
uwsgi.emperor_heartbeat = 30;
|
||||
// max 3 minutes throttling
|
||||
uwsgi.emperor_max_throttle = 1000 * 180;
|
||||
uwsgi.emperor_pid = -1;
|
||||
|
||||
uwsgi.subscribe_freq = 10;
|
||||
uwsgi.subscription_tolerance = 17;
|
||||
uwsgi.subscribe_freq = 10;
|
||||
uwsgi.subscription_tolerance = 17;
|
||||
|
||||
uwsgi.cluster_fd = -1;
|
||||
uwsgi.cores = 1;
|
||||
uwsgi.threads = 1;
|
||||
uwsgi.cluster_fd = -1;
|
||||
uwsgi.cores = 1;
|
||||
uwsgi.threads = 1;
|
||||
|
||||
uwsgi.default_app = -1;
|
||||
uwsgi.offload_threads_events = 64;
|
||||
|
||||
uwsgi.buffer_size = 4096;
|
||||
uwsgi.numproc = 1;
|
||||
uwsgi.default_app = -1;
|
||||
|
||||
uwsgi.forkbomb_delay = 2;
|
||||
uwsgi.buffer_size = 4096;
|
||||
uwsgi.numproc = 1;
|
||||
|
||||
uwsgi.async = 1;
|
||||
uwsgi.listen_queue = 100;
|
||||
uwsgi.forkbomb_delay = 2;
|
||||
|
||||
uwsgi.cheaper_overload = 3;
|
||||
uwsgi.async = 1;
|
||||
uwsgi.listen_queue = 100;
|
||||
|
||||
uwsgi.log_master_bufsize = 8192;
|
||||
uwsgi.cheaper_overload = 3;
|
||||
|
||||
uwsgi.max_vars = MAX_VARS;
|
||||
uwsgi.vec_size = 4 + 1 + (4 * MAX_VARS);
|
||||
uwsgi.log_master_bufsize = 8192;
|
||||
|
||||
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 4;
|
||||
uwsgi.shared->options[UWSGI_OPTION_LOGGING] = 1;
|
||||
uwsgi.max_vars = MAX_VARS;
|
||||
uwsgi.vec_size = 4 + 1 + (4 * MAX_VARS);
|
||||
|
||||
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 4;
|
||||
uwsgi.shared->options[UWSGI_OPTION_LOGGING] = 1;
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
uwsgi.shared->spooler_frequency = 30;
|
||||
uwsgi.shared->spooler_frequency = 30;
|
||||
|
||||
uwsgi.shared->spooler_signal_pipe[0] = -1;
|
||||
uwsgi.shared->spooler_signal_pipe[1] = -1;
|
||||
uwsgi.shared->spooler_signal_pipe[0] = -1;
|
||||
uwsgi.shared->spooler_signal_pipe[1] = -1;
|
||||
#endif
|
||||
uwsgi.shared->mule_signal_pipe[0] = -1;
|
||||
uwsgi.shared->mule_signal_pipe[1] = -1;
|
||||
uwsgi.shared->mule_signal_pipe[0] = -1;
|
||||
uwsgi.shared->mule_signal_pipe[1] = -1;
|
||||
|
||||
uwsgi.shared->mule_queue_pipe[0] = -1;
|
||||
uwsgi.shared->mule_queue_pipe[1] = -1;
|
||||
uwsgi.shared->mule_queue_pipe[0] = -1;
|
||||
uwsgi.shared->mule_queue_pipe[1] = -1;
|
||||
|
||||
uwsgi.shared->worker_log_pipe[0] = -1;
|
||||
uwsgi.shared->worker_log_pipe[1] = -1;
|
||||
uwsgi.shared->worker_log_pipe[0] = -1;
|
||||
uwsgi.shared->worker_log_pipe[1] = -1;
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
// 1 day of tolerance
|
||||
uwsgi.subscriptions_sign_check_tolerance = 3600 * 24;
|
||||
// 1 day of tolerance
|
||||
uwsgi.subscriptions_sign_check_tolerance = 3600 * 24;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
@@ -89,28 +91,28 @@ void uwsgi_init_default() {
|
||||
|
||||
void uwsgi_setup_reload() {
|
||||
|
||||
char env_reload_buf[11];
|
||||
char env_reload_buf[11];
|
||||
|
||||
char *env_reloads = getenv("UWSGI_RELOADS");
|
||||
if (env_reloads) {
|
||||
//convert env value to int
|
||||
uwsgi.reloads = atoi(env_reloads);
|
||||
uwsgi.reloads++;
|
||||
//convert reloads to string
|
||||
int rlen = snprintf(env_reload_buf, 10, "%u", uwsgi.reloads);
|
||||
if (rlen > 0) {
|
||||
env_reload_buf[rlen] = 0;
|
||||
if (setenv("UWSGI_RELOADS", env_reload_buf, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
}
|
||||
uwsgi.is_a_reload = 1;
|
||||
}
|
||||
else {
|
||||
if (setenv("UWSGI_RELOADS", "0", 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
}
|
||||
if (env_reloads) {
|
||||
//convert env value to int
|
||||
uwsgi.reloads = atoi(env_reloads);
|
||||
uwsgi.reloads++;
|
||||
//convert reloads to string
|
||||
int rlen = snprintf(env_reload_buf, 10, "%u", uwsgi.reloads);
|
||||
if (rlen > 0) {
|
||||
env_reload_buf[rlen] = 0;
|
||||
if (setenv("UWSGI_RELOADS", env_reload_buf, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
}
|
||||
uwsgi.is_a_reload = 1;
|
||||
}
|
||||
else {
|
||||
if (setenv("UWSGI_RELOADS", "0", 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,33 +121,33 @@ void uwsgi_autoload_plugins_by_name(char *argv_zero) {
|
||||
char *plugins_requested = NULL;
|
||||
|
||||
char *original_proc_name = getenv("UWSGI_ORIGINAL_PROC_NAME");
|
||||
if (!original_proc_name) {
|
||||
// here we use argv[0];
|
||||
original_proc_name = argv_zero;
|
||||
setenv("UWSGI_ORIGINAL_PROC_NAME", original_proc_name, 1);
|
||||
}
|
||||
char *p = strrchr(original_proc_name, '/');
|
||||
if (p == NULL)
|
||||
p = original_proc_name;
|
||||
p = strstr(p, "uwsgi_");
|
||||
if (p != NULL) {
|
||||
plugins_requested = strtok(uwsgi_str(p + 6), "_");
|
||||
while (plugins_requested) {
|
||||
uwsgi_log("[uwsgi] implicit plugin requested %s\n", plugins_requested);
|
||||
uwsgi_load_plugin(-1, plugins_requested, NULL);
|
||||
plugins_requested = strtok(NULL, "_");
|
||||
}
|
||||
}
|
||||
if (!original_proc_name) {
|
||||
// here we use argv[0];
|
||||
original_proc_name = argv_zero;
|
||||
setenv("UWSGI_ORIGINAL_PROC_NAME", original_proc_name, 1);
|
||||
}
|
||||
char *p = strrchr(original_proc_name, '/');
|
||||
if (p == NULL)
|
||||
p = original_proc_name;
|
||||
p = strstr(p, "uwsgi_");
|
||||
if (p != NULL) {
|
||||
plugins_requested = strtok(uwsgi_str(p + 6), "_");
|
||||
while (plugins_requested) {
|
||||
uwsgi_log("[uwsgi] implicit plugin requested %s\n", plugins_requested);
|
||||
uwsgi_load_plugin(-1, plugins_requested, NULL);
|
||||
plugins_requested = strtok(NULL, "_");
|
||||
}
|
||||
}
|
||||
|
||||
plugins_requested = getenv("UWSGI_PLUGINS");
|
||||
if (plugins_requested) {
|
||||
plugins_requested = uwsgi_concat2(plugins_requested, "");
|
||||
char *p = strtok(plugins_requested, ",");
|
||||
while (p != NULL) {
|
||||
uwsgi_load_plugin(-1, p, NULL);
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
plugins_requested = getenv("UWSGI_PLUGINS");
|
||||
if (plugins_requested) {
|
||||
plugins_requested = uwsgi_concat2(plugins_requested, "");
|
||||
char *p = strtok(plugins_requested, ",");
|
||||
while (p != NULL) {
|
||||
uwsgi_load_plugin(-1, p, NULL);
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -154,140 +156,140 @@ void uwsgi_commandline_config() {
|
||||
|
||||
uwsgi.option_index = -1;
|
||||
|
||||
char *optname;
|
||||
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, uwsgi.short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
|
||||
char *optname;
|
||||
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, uwsgi.short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
|
||||
|
||||
if (i == '?') {
|
||||
uwsgi_log("getopt_long() error\n");
|
||||
exit(1);
|
||||
}
|
||||
if (i == '?') {
|
||||
uwsgi_log("getopt_long() error\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.option_index > -1) {
|
||||
optname = (char *) uwsgi.long_options[uwsgi.option_index].name;
|
||||
}
|
||||
else {
|
||||
optname = uwsgi_get_optname_by_index(i);
|
||||
}
|
||||
if (!optname) {
|
||||
uwsgi_log("unable to parse command line options\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.option_index = -1;
|
||||
add_exported_option(optname, optarg, 0);
|
||||
}
|
||||
if (uwsgi.option_index > -1) {
|
||||
optname = (char *) uwsgi.long_options[uwsgi.option_index].name;
|
||||
}
|
||||
else {
|
||||
optname = uwsgi_get_optname_by_index(i);
|
||||
}
|
||||
if (!optname) {
|
||||
uwsgi_log("unable to parse command line options\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.option_index = -1;
|
||||
add_exported_option(optname, optarg, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("optind:%d argc:%d\n", optind, uwsgi.argc);
|
||||
uwsgi_log("optind:%d argc:%d\n", optind, uwsgi.argc);
|
||||
#endif
|
||||
|
||||
if (optind < uwsgi.argc) {
|
||||
for (i = optind; i < uwsgi.argc; i++) {
|
||||
char *lazy = uwsgi.argv[i];
|
||||
if (lazy[0] != '[') {
|
||||
uwsgi_opt_load(NULL, lazy, NULL);
|
||||
// manage magic mountpoint
|
||||
int magic = 0;
|
||||
int j;
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->magic) {
|
||||
if (uwsgi.gp[j]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!magic) {
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (uwsgi.p[j]->magic) {
|
||||
if (uwsgi.p[j]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (optind < uwsgi.argc) {
|
||||
for (i = optind; i < uwsgi.argc; i++) {
|
||||
char *lazy = uwsgi.argv[i];
|
||||
if (lazy[0] != '[') {
|
||||
uwsgi_opt_load(NULL, lazy, NULL);
|
||||
// manage magic mountpoint
|
||||
int magic = 0;
|
||||
int j;
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->magic) {
|
||||
if (uwsgi.gp[j]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!magic) {
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (uwsgi.p[j]->magic) {
|
||||
if (uwsgi.p[j]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_setup_workers() {
|
||||
int i,j;
|
||||
int i, j;
|
||||
// allocate shared memory for workers + master
|
||||
uwsgi.workers = (struct uwsgi_worker *) uwsgi_calloc_shared(sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1 + uwsgi.grunt));
|
||||
uwsgi.workers = (struct uwsgi_worker *) uwsgi_calloc_shared(sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1 + uwsgi.grunt));
|
||||
|
||||
for (i = 0; i <= uwsgi.numproc; i++) {
|
||||
// allocate memory for apps
|
||||
uwsgi.workers[i].apps = (struct uwsgi_app *) uwsgi_calloc_shared(sizeof(struct uwsgi_app) * uwsgi.max_apps);
|
||||
for (i = 0; i <= uwsgi.numproc; i++) {
|
||||
// allocate memory for apps
|
||||
uwsgi.workers[i].apps = (struct uwsgi_app *) uwsgi_calloc_shared(sizeof(struct uwsgi_app) * uwsgi.max_apps);
|
||||
|
||||
// allocate memory for cores
|
||||
uwsgi.workers[i].cores = (struct uwsgi_core *) uwsgi_calloc_shared(sizeof(struct uwsgi_core) * uwsgi.cores);
|
||||
// allocate memory for cores
|
||||
uwsgi.workers[i].cores = (struct uwsgi_core *) uwsgi_calloc_shared(sizeof(struct uwsgi_core) * uwsgi.cores);
|
||||
|
||||
// this is a trick for avoiding too much memory areas
|
||||
void *ts = uwsgi_calloc_shared(sizeof(void *) * uwsgi.max_apps * uwsgi.cores);
|
||||
void *buffers = uwsgi_malloc_shared(uwsgi.buffer_size * uwsgi.cores);
|
||||
void *hvec = uwsgi_malloc_shared(sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
|
||||
void *hvec = uwsgi_malloc_shared(sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
|
||||
void *post_buf = NULL;
|
||||
if (uwsgi.post_buffering > 0)
|
||||
post_buf = uwsgi_malloc_shared(uwsgi.post_buffering_bufsize * uwsgi.cores);
|
||||
|
||||
post_buf = uwsgi_malloc_shared(uwsgi.post_buffering_bufsize * uwsgi.cores);
|
||||
|
||||
for (j = 0; j < uwsgi.cores; j++) {
|
||||
// allocate shared memory for thread states (required for some language, like python)
|
||||
uwsgi.workers[i].cores[j].ts = ts + ((sizeof(void *) * uwsgi.max_apps) * j);
|
||||
// raw per-request buffer
|
||||
uwsgi.workers[i].cores[j].buffer = buffers + (uwsgi.buffer_size * j);
|
||||
// iovec for uwsgi vars
|
||||
uwsgi.workers[i].cores[j].hvec = hvec + ((sizeof(struct iovec) * uwsgi.vec_size) * j);
|
||||
if (post_buf)
|
||||
uwsgi.workers[i].cores[j].post_buf = post_buf + (uwsgi.post_buffering_bufsize *j);
|
||||
}
|
||||
|
||||
// master does not need to following steps...
|
||||
if (i == 0) continue;
|
||||
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);
|
||||
}
|
||||
for (j = 0; j < uwsgi.cores; j++) {
|
||||
// allocate shared memory for thread states (required for some language, like python)
|
||||
uwsgi.workers[i].cores[j].ts = ts + ((sizeof(void *) * uwsgi.max_apps) * j);
|
||||
// raw per-request buffer
|
||||
uwsgi.workers[i].cores[j].buffer = buffers + (uwsgi.buffer_size * j);
|
||||
// iovec for uwsgi vars
|
||||
uwsgi.workers[i].cores[j].hvec = hvec + ((sizeof(struct iovec) * uwsgi.vec_size) * j);
|
||||
if (post_buf)
|
||||
uwsgi.workers[i].cores[j].post_buf = post_buf + (uwsgi.post_buffering_bufsize * j);
|
||||
}
|
||||
|
||||
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);
|
||||
// master does not need to following steps...
|
||||
if (i == 0)
|
||||
continue;
|
||||
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);
|
||||
if (uwsgi.post_buffering > 0) {
|
||||
total_memory += (uwsgi.post_buffering_bufsize * uwsgi.cores);
|
||||
}
|
||||
|
||||
total_memory *= (uwsgi.numproc + uwsgi.master_process);
|
||||
uwsgi_log("mapped %llu bytes (%llu KB) for %d cores\n", total_memory, total_memory / 1024, uwsgi.cores*uwsgi.numproc);
|
||||
uwsgi_log("mapped %llu bytes (%llu KB) for %d cores\n", total_memory, total_memory / 1024, uwsgi.cores * uwsgi.numproc);
|
||||
|
||||
}
|
||||
|
||||
pid_t uwsgi_daemonize2() {
|
||||
if (uwsgi.has_emperor) {
|
||||
logto(uwsgi.daemonize2);
|
||||
}
|
||||
else {
|
||||
if (!uwsgi.is_a_reload) {
|
||||
uwsgi_log("*** daemonizing uWSGI ***\n");
|
||||
daemonize(uwsgi.daemonize2);
|
||||
}
|
||||
else if (uwsgi.log_reopen) {
|
||||
logto(uwsgi.daemonize2);
|
||||
}
|
||||
}
|
||||
uwsgi.mypid = getpid();
|
||||
logto(uwsgi.daemonize2);
|
||||
}
|
||||
else {
|
||||
if (!uwsgi.is_a_reload) {
|
||||
uwsgi_log("*** daemonizing uWSGI ***\n");
|
||||
daemonize(uwsgi.daemonize2);
|
||||
}
|
||||
else if (uwsgi.log_reopen) {
|
||||
logto(uwsgi.daemonize2);
|
||||
}
|
||||
}
|
||||
uwsgi.mypid = getpid();
|
||||
|
||||
uwsgi.workers[0].pid = uwsgi.mypid;
|
||||
uwsgi.workers[0].pid = uwsgi.mypid;
|
||||
|
||||
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile);
|
||||
}
|
||||
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile);
|
||||
}
|
||||
|
||||
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile2);
|
||||
}
|
||||
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile2);
|
||||
}
|
||||
|
||||
return uwsgi.mypid;
|
||||
}
|
||||
|
||||
+29
-29
@@ -31,17 +31,17 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
|
||||
int i;
|
||||
|
||||
if (uwsgi_check_scheme(file)) {
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(file, ':');
|
||||
}
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(file, ':');
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
if (colon[1] != 0) {
|
||||
object_asked = colon+1;
|
||||
object_asked = colon + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
|
||||
|
||||
json_data = uwsgi_open_and_read(file, &len, 1, magic_table);
|
||||
|
||||
#ifdef JANSSON_MAJOR_VERSION
|
||||
#ifdef JANSSON_MAJOR_VERSION
|
||||
root = json_loads(json_data, 0, &error);
|
||||
#else
|
||||
root = json_loads(json_data, &error);
|
||||
@@ -66,46 +66,46 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
|
||||
uwsgi_log("you must define a object named %s in your JSON data\n", object_asked);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
config_iter = json_object_iter(config);
|
||||
|
||||
while(config_iter) {
|
||||
while (config_iter) {
|
||||
key = json_object_iter_key(config_iter);
|
||||
config_value = json_object_iter_value(config_iter);
|
||||
config_value = json_object_iter_value(config_iter);
|
||||
|
||||
if (json_is_string(config_value)) {
|
||||
add_exported_option((char *)key, (char *) json_string_value(config_value), 0);
|
||||
add_exported_option((char *) key, (char *) json_string_value(config_value), 0);
|
||||
}
|
||||
else if (json_is_true(config_value)) {
|
||||
add_exported_option((char *)key, strdup("1"), 0);
|
||||
add_exported_option((char *) key, strdup("1"), 0);
|
||||
}
|
||||
else if (json_is_false(config_value) || json_is_null(config_value)) {
|
||||
add_exported_option((char *)key, strdup("0"), 0);
|
||||
add_exported_option((char *) key, strdup("0"), 0);
|
||||
}
|
||||
else if (json_is_integer(config_value)) {
|
||||
add_exported_option((char *)key, uwsgi_num2str(json_integer_value(config_value)), 0);
|
||||
add_exported_option((char *) key, uwsgi_num2str(json_integer_value(config_value)), 0);
|
||||
}
|
||||
else if (json_is_array(config_value)) {
|
||||
for(i=0;i<(int)json_array_size(config_value);i++) {
|
||||
config_array_item = json_array_get(config_value, i);
|
||||
for (i = 0; i < (int) json_array_size(config_value); i++) {
|
||||
config_array_item = json_array_get(config_value, i);
|
||||
if (json_is_string(config_array_item)) {
|
||||
add_exported_option((char *)key, (char *) json_string_value(config_array_item), 0);
|
||||
}
|
||||
else if (json_is_true(config_array_item)) {
|
||||
add_exported_option((char *)key, strdup("1"), 0);
|
||||
}
|
||||
else if (json_is_false(config_array_item) || json_is_null(config_array_item)) {
|
||||
add_exported_option((char *)key, strdup("0"), 0);
|
||||
}
|
||||
else if (json_is_integer(config_array_item)) {
|
||||
add_exported_option((char *)key, uwsgi_num2str(json_integer_value(config_array_item)), 0);
|
||||
}
|
||||
add_exported_option((char *) key, (char *) json_string_value(config_array_item), 0);
|
||||
}
|
||||
else if (json_is_true(config_array_item)) {
|
||||
add_exported_option((char *) key, strdup("1"), 0);
|
||||
}
|
||||
else if (json_is_false(config_array_item) || json_is_null(config_array_item)) {
|
||||
add_exported_option((char *) key, strdup("0"), 0);
|
||||
}
|
||||
else if (json_is_integer(config_array_item)) {
|
||||
add_exported_option((char *) key, uwsgi_num2str(json_integer_value(config_array_item)), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config_iter = json_object_iter_next(config, config_iter);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+68
-67
@@ -19,25 +19,25 @@ void ldap2uwsgi(char *ldapname, char *uwsginame) {
|
||||
|
||||
int i;
|
||||
|
||||
for(i=0;i< (int) strlen(ldapname);i++) {
|
||||
if (isupper( (int)ldapname[i])) {
|
||||
for (i = 0; i < (int) strlen(ldapname); i++) {
|
||||
if (isupper((int) ldapname[i])) {
|
||||
*ptr++ = '-';
|
||||
*ptr++ = tolower( (int) ldapname[i]);
|
||||
*ptr++ = tolower((int) ldapname[i]);
|
||||
}
|
||||
else {
|
||||
*ptr++ = ldapname[i];
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++= 0;
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
int calc_ldap_name(char *name) {
|
||||
int i;
|
||||
int counter = 0;
|
||||
|
||||
for(i=0;i< (int)strlen(name);i++) {
|
||||
if (isupper( (int) name[i])) {
|
||||
for (i = 0; i < (int) strlen(name); i++) {
|
||||
if (isupper((int) name[i])) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ struct uwsgi_ldap_entry {
|
||||
};
|
||||
|
||||
|
||||
void uwsgi_name_to_ldap(char *src, char *dst) {
|
||||
void uwsgi_name_to_ldap(char *src, char *dst) {
|
||||
|
||||
int i;
|
||||
char *ptr = dst;
|
||||
@@ -61,16 +61,16 @@ void uwsgi_name_to_ldap(char *src, char *dst) {
|
||||
|
||||
strcat(dst, " 'uWSGI");
|
||||
|
||||
ptr+= 7;
|
||||
ptr += 7;
|
||||
|
||||
for(i=0;i< (int)strlen(src);i++) {
|
||||
if (src[i] == '-') {
|
||||
i++;
|
||||
*ptr++= toupper( (int) src[i]);
|
||||
}
|
||||
else {
|
||||
*ptr++= src[i];
|
||||
}
|
||||
for (i = 0; i < (int) strlen(src); i++) {
|
||||
if (src[i] == '-') {
|
||||
i++;
|
||||
*ptr++ = toupper((int) src[i]);
|
||||
}
|
||||
else {
|
||||
*ptr++ = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
strcat(dst, "'");
|
||||
@@ -82,7 +82,7 @@ struct uwsgi_ldap_entry *get_ldap_by_num(struct uwsgi_ldap_entry *root, int num,
|
||||
int i;
|
||||
struct uwsgi_ldap_entry *ule;
|
||||
|
||||
for(i=0;i<count;i++) {
|
||||
for (i = 0; i < count; i++) {
|
||||
ule = &root[i];
|
||||
if (ule->num == num) {
|
||||
return ule;
|
||||
@@ -96,9 +96,9 @@ struct uwsgi_ldap_entry *search_ldap_cache(struct uwsgi_ldap_entry *root, char *
|
||||
int i;
|
||||
struct uwsgi_ldap_entry *ule;
|
||||
|
||||
for(i=0;i<count;i++) {
|
||||
for (i = 0; i < count; i++) {
|
||||
ule = &root[i];
|
||||
if (uwsgi_list_has_str(ule->names, name+1)) {
|
||||
if (uwsgi_list_has_str(ule->names, name + 1)) {
|
||||
return ule;
|
||||
}
|
||||
}
|
||||
@@ -114,23 +114,24 @@ struct uwsgi_ldap_entry *get_ldap_names(int *count) {
|
||||
|
||||
*count = 0;
|
||||
|
||||
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry)*uwsgi_count_options(op));
|
||||
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry) * uwsgi_count_options(op));
|
||||
|
||||
while( op && op->name ) {
|
||||
while (op && op->name) {
|
||||
|
||||
uwsgi_name_to_ldap((char *)op->name, ldap_name);
|
||||
uwsgi_name_to_ldap((char *) op->name, ldap_name);
|
||||
|
||||
entry = search_ldap_cache(ule, ldap_name, *count);
|
||||
|
||||
if (entry) goto next;
|
||||
if (entry)
|
||||
goto next;
|
||||
|
||||
entry = &ule[*count] ;
|
||||
entry = &ule[*count];
|
||||
entry->num = *count;
|
||||
strcpy(entry->names, ldap_name);
|
||||
*count = *count+1;
|
||||
*count = *count + 1;
|
||||
|
||||
entry->has_arg = op->type;
|
||||
|
||||
|
||||
next:
|
||||
op++;
|
||||
}
|
||||
@@ -150,7 +151,7 @@ void uwsgi_opt_ldap_dump_ldif(char *opt, char *foo, void *bar) {
|
||||
|
||||
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
for (i = 0; i < items; i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
@@ -168,19 +169,19 @@ void uwsgi_opt_ldap_dump_ldif(char *opt, char *foo, void *bar) {
|
||||
|
||||
uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
||||
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
for (i = 0; i < items; i++) {
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names+1, "");
|
||||
entry = &ule[i];
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names + 1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p) - 2, p + 1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
free(list2);
|
||||
|
||||
}
|
||||
|
||||
@@ -198,38 +199,38 @@ void uwsgi_opt_ldap_dump(char *opt, char *foo, void *bar) {
|
||||
|
||||
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
for (i = 0; i < items; i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
entry = &ule[i];
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
|
||||
if (entry->has_arg) {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
}
|
||||
if (entry->has_arg) {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
|
||||
uwsgi_log("objectclass ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
for (i = 0; i < items; i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
entry = &ule[i];
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names+1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
char *list2 = uwsgi_concat2(entry->names + 1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p) - 2, p + 1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
free(list2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -264,7 +265,7 @@ void uwsgi_ldap_config(char *url) {
|
||||
uwsgi_log("unable to parse LDAP url.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url);
|
||||
|
||||
url_slash = strchr(url, '/');
|
||||
@@ -281,25 +282,25 @@ void uwsgi_ldap_config(char *url) {
|
||||
#endif
|
||||
|
||||
#if LDAP_API_VERSION >= 3000
|
||||
if ( (ret = ldap_initialize( &ldp, url)) != LDAP_SUCCESS) {
|
||||
if ((ret = ldap_initialize(&ldp, url)) != LDAP_SUCCESS) {
|
||||
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
if ( (ldp = ldap_init( ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
|
||||
if ((ldp = ldap_init(ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
|
||||
uwsgi_error("ldap_init()");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if ( (ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
|
||||
if ((ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
|
||||
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if ( (ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) {
|
||||
if ((ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) {
|
||||
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
||||
exit(1);
|
||||
}
|
||||
@@ -318,17 +319,17 @@ void uwsgi_ldap_config(char *url) {
|
||||
entry = ldap_first_entry(ldp, results);
|
||||
|
||||
int found = 0;
|
||||
for( attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
|
||||
if (!strncmp(attr,"uWSGI",5)) {
|
||||
for (attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
|
||||
if (!strncmp(attr, "uWSGI", 5)) {
|
||||
|
||||
found = 1;
|
||||
uwsgi_attr = malloc( calc_ldap_name(attr) + 1 );
|
||||
uwsgi_attr = malloc(calc_ldap_name(attr) + 1);
|
||||
if (!uwsgi_attr) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ldap2uwsgi(attr+5, uwsgi_attr);
|
||||
ldap2uwsgi(attr + 5, uwsgi_attr);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("LDAP attribute: %s = --%s\n", attr, uwsgi_attr);
|
||||
@@ -336,7 +337,7 @@ void uwsgi_ldap_config(char *url) {
|
||||
bervalues = ldap_get_values_len(ldp, entry, attr);
|
||||
if (bervalues) {
|
||||
// do not free uwsgi_attr/uwsgi_val;
|
||||
char *uwsgi_val = malloc( bervalues[0]->bv_len + 1 );
|
||||
char *uwsgi_val = malloc(bervalues[0]->bv_len + 1);
|
||||
if (!uwsgi_val) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
@@ -345,7 +346,7 @@ void uwsgi_ldap_config(char *url) {
|
||||
memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len);
|
||||
uwsgi_val[bervalues[0]->bv_len] = 0;
|
||||
|
||||
add_exported_option((char*) uwsgi_attr, uwsgi_val, 0);
|
||||
add_exported_option((char *) uwsgi_attr, uwsgi_val, 0);
|
||||
free(bervalues);
|
||||
}
|
||||
else {
|
||||
|
||||
+182
-141
@@ -20,7 +20,7 @@ static struct uwsgi_lock_item *uwsgi_register_lock(char *id, int rw) {
|
||||
return uwsgi.registered_locks;
|
||||
}
|
||||
|
||||
while(uli) {
|
||||
while (uli) {
|
||||
if (!uli->next) {
|
||||
uli->next = uwsgi_malloc_shared(sizeof(struct uwsgi_lock_item));
|
||||
if (rw) {
|
||||
@@ -64,32 +64,32 @@ int uwsgi_pthread_robust_mutexes_enabled = 1;
|
||||
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
|
||||
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
|
||||
|
||||
#ifdef EOWNERDEAD
|
||||
retry:
|
||||
#endif
|
||||
if (pthread_mutexattr_init(&attr)) {
|
||||
uwsgi_log("unable to allocate mutexattr structure\n");
|
||||
exit(1);
|
||||
uwsgi_log("unable to allocate mutexattr structure\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
|
||||
uwsgi_log("unable to share mutex\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
|
||||
uwsgi_log("unable to share mutex\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef EOWNERDEAD
|
||||
if (uwsgi_pthread_robust_mutexes_enabled) {
|
||||
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP)) {
|
||||
uwsgi_log("unable to make the mutex 'robust'\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP)) {
|
||||
uwsgi_log("unable to make the mutex 'robust'\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pthread_mutex_init((pthread_mutex_t *) uli->lock_ptr, &attr)) {
|
||||
if (pthread_mutex_init((pthread_mutex_t *) uli->lock_ptr, &attr)) {
|
||||
#ifdef EOWNERDEAD
|
||||
if (uwsgi_pthread_robust_mutexes_enabled) {
|
||||
uwsgi_log("!!! it looks like your kernel does not support pthread robust mutexes !!!\n");
|
||||
@@ -99,9 +99,9 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
#endif
|
||||
uwsgi_log("unable to initialize mutex\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("unable to initialize mutex\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
|
||||
@@ -116,25 +116,25 @@ retry:
|
||||
return uli;
|
||||
}
|
||||
|
||||
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item * uli) {
|
||||
|
||||
if (pthread_mutex_trylock((pthread_mutex_t *) uli->lock_ptr) == 0 ) {
|
||||
pthread_mutex_unlock((pthread_mutex_t *) uli->lock_ptr);
|
||||
if (pthread_mutex_trylock((pthread_mutex_t *) uli->lock_ptr) == 0) {
|
||||
pthread_mutex_unlock((pthread_mutex_t *) uli->lock_ptr);
|
||||
return 0;
|
||||
}
|
||||
return uli->pid;
|
||||
}
|
||||
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item * uli) {
|
||||
#ifdef OBSOLETE_LINUX_KERNEL
|
||||
return uwsgi_lock_fast_check(uli);
|
||||
#else
|
||||
|
||||
if (pthread_rwlock_trywrlock((pthread_rwlock_t *) uli->lock_ptr) == 0 ) {
|
||||
pthread_rwlock_unlock((pthread_rwlock_t *) uli->lock_ptr);
|
||||
if (pthread_rwlock_trywrlock((pthread_rwlock_t *) uli->lock_ptr) == 0) {
|
||||
pthread_rwlock_unlock((pthread_rwlock_t *) uli->lock_ptr);
|
||||
return 0;
|
||||
}
|
||||
return uli->pid;
|
||||
return uli->pid;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
|
||||
#else
|
||||
pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr);
|
||||
#endif
|
||||
uli->pid = uwsgi.mypid;
|
||||
uli->pid = uwsgi.mypid;
|
||||
}
|
||||
|
||||
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
|
||||
@@ -164,7 +164,7 @@ void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
#else
|
||||
pthread_rwlock_rdlock((pthread_rwlock_t *) uli->lock_ptr);
|
||||
uli->pid = uwsgi.mypid;
|
||||
uli->pid = uwsgi.mypid;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
#else
|
||||
pthread_rwlock_wrlock((pthread_rwlock_t *) uli->lock_ptr);
|
||||
uli->pid = uwsgi.mypid;
|
||||
uli->pid = uwsgi.mypid;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_fast(uli);
|
||||
#else
|
||||
pthread_rwlock_unlock((pthread_rwlock_t *) uli->lock_ptr);
|
||||
uli->pid = 0;
|
||||
uli->pid = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -196,20 +196,20 @@ struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 1);
|
||||
|
||||
if (pthread_rwlockattr_init(&attr)) {
|
||||
uwsgi_log("unable to allocate rwlock structure\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_rwlockattr_init(&attr)) {
|
||||
uwsgi_log("unable to allocate rwlock structure\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
|
||||
uwsgi_log("unable to share rwlock\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
|
||||
uwsgi_log("unable to share rwlock\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_rwlock_init((pthread_rwlock_t *) uli->lock_ptr, &attr)) {
|
||||
uwsgi_log("unable to initialize rwlock\n");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_rwlock_init((pthread_rwlock_t *) uli->lock_ptr, &attr)) {
|
||||
uwsgi_log("unable to initialize rwlock\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_rwlockattr_destroy(&attr);
|
||||
|
||||
@@ -235,36 +235,46 @@ struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
#define UWSGI_RWLOCK_SIZE sizeof(struct umtx)
|
||||
#define UWSGI_LOCK_ENGINE_NAME "FreeBSD umtx"
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) { return uwsgi_lock_fast_init(id) ;}
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) { uwsgi_unlock_fast(uli); }
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
return uwsgi_lock_fast_init(id);
|
||||
}
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_fast(uli);
|
||||
}
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
|
||||
umtx_init((struct umtx*) uli->lock_ptr);
|
||||
umtx_init((struct umtx *) uli->lock_ptr);
|
||||
return uli;
|
||||
}
|
||||
|
||||
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
|
||||
umtx_lock((struct umtx*) uli->lock_ptr, (u_long) getpid() );
|
||||
umtx_lock((struct umtx *) uli->lock_ptr, (u_long) getpid());
|
||||
uli->pid = uwsgi.mypid;
|
||||
}
|
||||
|
||||
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
|
||||
umtx_unlock((struct umtx*) uli->lock_ptr, (u_long) getpid() );
|
||||
umtx_unlock((struct umtx *) uli->lock_ptr, (u_long) getpid());
|
||||
uli->pid = 0;
|
||||
}
|
||||
|
||||
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
if (umtx_trylock((struct umtx*) uli->lock_ptr, (u_long) getpid() )) {
|
||||
umtx_unlock((struct umtx*) uli->lock_ptr, (u_long) getpid() );
|
||||
if (umtx_trylock((struct umtx *) uli->lock_ptr, (u_long) getpid())) {
|
||||
umtx_unlock((struct umtx *) uli->lock_ptr, (u_long) getpid());
|
||||
return 0;
|
||||
}
|
||||
return uli->pid;
|
||||
}
|
||||
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); }
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item * uli) {
|
||||
return uwsgi_lock_fast_check(uli);
|
||||
}
|
||||
|
||||
#elif defined(UWSGI_LOCK_USE_POSIX_SEM)
|
||||
|
||||
@@ -275,36 +285,46 @@ pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_f
|
||||
#include <semaphore.h>
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
|
||||
sem_init((sem_t*) uli->lock_ptr, 1, 1);
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
|
||||
sem_init((sem_t *) uli->lock_ptr, 1, 1);
|
||||
uli->can_deadlock = 1;
|
||||
return uli;
|
||||
return uli;
|
||||
}
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) { return uwsgi_lock_fast_init(id) ;}
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
return uwsgi_lock_fast_init(id);
|
||||
}
|
||||
|
||||
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
|
||||
sem_wait((sem_t *) uli->lock_ptr);
|
||||
uli->pid = uwsgi.mypid;
|
||||
sem_wait((sem_t *) uli->lock_ptr);
|
||||
uli->pid = uwsgi.mypid;
|
||||
}
|
||||
|
||||
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
|
||||
sem_post((sem_t*) uli->lock_ptr);
|
||||
uli->pid = 0;
|
||||
sem_post((sem_t *) uli->lock_ptr);
|
||||
uli->pid = 0;
|
||||
}
|
||||
|
||||
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
if (sem_trywait((sem_t *) uli->lock_ptr) == 0) {
|
||||
sem_post((sem_t*) uli->lock_ptr);
|
||||
return 0;
|
||||
}
|
||||
return uli->pid;
|
||||
sem_post((sem_t *) uli->lock_ptr);
|
||||
return 0;
|
||||
}
|
||||
return uli->pid;
|
||||
}
|
||||
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); }
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) { uwsgi_unlock_fast(uli); }
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item * uli) {
|
||||
return uwsgi_lock_fast_check(uli);
|
||||
}
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_fast(uli);
|
||||
}
|
||||
|
||||
|
||||
#elif defined(UWSGI_LOCK_USE_OSX_SPINLOCK)
|
||||
@@ -342,19 +362,27 @@ pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
return uli->pid;
|
||||
}
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 1);
|
||||
memset(uli->lock_ptr, 0, UWSGI_LOCK_SIZE);
|
||||
uli->can_deadlock = 1;
|
||||
return uli;
|
||||
}
|
||||
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);}
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); }
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
return uwsgi_lock_fast_check(uli);
|
||||
}
|
||||
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) { uwsgi_unlock_fast(uli); }
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_fast(uli);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -384,10 +412,10 @@ struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *id) {
|
||||
// used by ftok
|
||||
static int counter = 1;
|
||||
union semun {
|
||||
int val;
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
ushort *array;
|
||||
} semu ;
|
||||
} semu;
|
||||
int semid;
|
||||
key_t myKey;
|
||||
|
||||
@@ -400,10 +428,10 @@ struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *id) {
|
||||
exit(1);
|
||||
}
|
||||
counter++;
|
||||
semid = semget(myKey, 1, IPC_CREAT|0666);
|
||||
semid = semget(myKey, 1, IPC_CREAT | 0666);
|
||||
}
|
||||
else {
|
||||
semid = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL| 0666);
|
||||
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);
|
||||
}
|
||||
|
||||
if (semid < 0) {
|
||||
@@ -418,7 +446,7 @@ struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *id) {
|
||||
uwsgi_error("semctl()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
return uli;
|
||||
}
|
||||
|
||||
@@ -434,7 +462,7 @@ void uwsgi_lock_ipcsem(struct uwsgi_lock_item *uli) {
|
||||
|
||||
if (semop(semid, &sb, 1)) {
|
||||
uwsgi_error("semop()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_unlock_ipcsem(struct uwsgi_lock_item *uli) {
|
||||
@@ -449,14 +477,22 @@ void uwsgi_unlock_ipcsem(struct uwsgi_lock_item *uli) {
|
||||
|
||||
if (semop(semid, &sb, 1)) {
|
||||
uwsgi_error("semop()");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_ipcsem_init(char *id) { return uwsgi_lock_ipcsem_init(id);}
|
||||
void uwsgi_rlock_ipcsem(struct uwsgi_lock_item *uli) { uwsgi_lock_ipcsem(uli);}
|
||||
void uwsgi_wlock_ipcsem(struct uwsgi_lock_item *uli) { uwsgi_lock_ipcsem(uli);}
|
||||
void uwsgi_rwunlock_ipcsem(struct uwsgi_lock_item *uli) { uwsgi_unlock_ipcsem(uli); }
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_ipcsem_init(char *id) {
|
||||
return uwsgi_lock_ipcsem_init(id);
|
||||
}
|
||||
void uwsgi_rlock_ipcsem(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_ipcsem(uli);
|
||||
}
|
||||
void uwsgi_wlock_ipcsem(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_ipcsem(uli);
|
||||
}
|
||||
void uwsgi_rwunlock_ipcsem(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_ipcsem(uli);
|
||||
}
|
||||
|
||||
// ipc cannot deadlock
|
||||
pid_t uwsgi_lock_ipcsem_check(struct uwsgi_lock_item *uli) {
|
||||
@@ -467,13 +503,17 @@ void uwsgi_ipcsem_clear(void) {
|
||||
|
||||
struct uwsgi_lock_item *uli = uwsgi.registered_locks;
|
||||
|
||||
if (!uwsgi.workers) goto clear;
|
||||
if (!uwsgi.workers)
|
||||
goto clear;
|
||||
|
||||
if (uwsgi.mywid == 0) goto clear;
|
||||
if (uwsgi.mywid == 0)
|
||||
goto clear;
|
||||
|
||||
if (uwsgi.master_process && getpid() == uwsgi.workers[0].pid) goto clear;
|
||||
if (uwsgi.master_process && getpid() == uwsgi.workers[0].pid)
|
||||
goto clear;
|
||||
|
||||
if (!uwsgi.master_process && uwsgi.mywid == 1) goto clear;
|
||||
if (!uwsgi.master_process && uwsgi.mywid == 1)
|
||||
goto clear;
|
||||
|
||||
return;
|
||||
|
||||
@@ -482,7 +522,7 @@ clear:
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("removing sysvipc semaphores...\n");
|
||||
#endif
|
||||
while(uli) {
|
||||
while (uli) {
|
||||
int semid = 0;
|
||||
memcpy(&semid, uli->lock_ptr, sizeof(int));
|
||||
if (semctl(semid, 0, IPC_RMID)) {
|
||||
@@ -493,7 +533,9 @@ clear:
|
||||
}
|
||||
|
||||
|
||||
pid_t uwsgi_rwlock_ipcsem_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_ipcsem_check(uli); }
|
||||
pid_t uwsgi_rwlock_ipcsem_check(struct uwsgi_lock_item *uli) {
|
||||
return uwsgi_lock_ipcsem_check(uli);
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_setup_locking() {
|
||||
@@ -536,37 +578,37 @@ void uwsgi_setup_locking() {
|
||||
|
||||
// application generic lock
|
||||
int i;
|
||||
uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
|
||||
for (i = 0; i < uwsgi.locks + 1; i++) {
|
||||
uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i)));
|
||||
}
|
||||
uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
|
||||
for (i = 0; i < uwsgi.locks + 1; i++) {
|
||||
uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i)));
|
||||
}
|
||||
|
||||
// event queue lock (mitigate same event on multiple queues)
|
||||
if (uwsgi.threads > 1) {
|
||||
pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
|
||||
}
|
||||
if (uwsgi.threads > 1) {
|
||||
pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
|
||||
}
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
// signal table lock
|
||||
uwsgi.signal_table_lock = uwsgi_lock_init("signal");
|
||||
if (uwsgi.master_process) {
|
||||
// signal table lock
|
||||
uwsgi.signal_table_lock = uwsgi_lock_init("signal");
|
||||
|
||||
// fmon table lock
|
||||
uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");
|
||||
// fmon table lock
|
||||
uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");
|
||||
|
||||
// timer table lock
|
||||
uwsgi.timer_table_lock = uwsgi_lock_init("timer");
|
||||
// timer table lock
|
||||
uwsgi.timer_table_lock = uwsgi_lock_init("timer");
|
||||
|
||||
// probe table lock
|
||||
uwsgi.probe_table_lock = uwsgi_lock_init("probe");
|
||||
// probe table lock
|
||||
uwsgi.probe_table_lock = uwsgi_lock_init("probe");
|
||||
|
||||
// rb_timer table lock
|
||||
uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");
|
||||
// rb_timer table lock
|
||||
uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");
|
||||
|
||||
// cron table lock
|
||||
uwsgi.cron_table_lock = uwsgi_lock_init("cron");
|
||||
}
|
||||
// cron table lock
|
||||
uwsgi.cron_table_lock = uwsgi_lock_init("cron");
|
||||
}
|
||||
|
||||
uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");
|
||||
uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");
|
||||
|
||||
}
|
||||
|
||||
@@ -589,52 +631,51 @@ int uwsgi_fcntl_lock(int fd) {
|
||||
int uwsgi_fcntl_is_locked(int fd) {
|
||||
|
||||
struct flock fl;
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
fl.l_pid = 0;
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
fl.l_pid = 0;
|
||||
|
||||
if (fcntl(fd, F_SETLK, &fl)) {
|
||||
if (fcntl(fd, F_SETLK, &fl)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_deadlock_check(pid_t diedpid) {
|
||||
struct uwsgi_lock_item *uli = uwsgi.registered_locks;
|
||||
while (uli) {
|
||||
if (!uli->can_deadlock)
|
||||
goto nextlock;
|
||||
pid_t locked_pid = 0;
|
||||
if (uli->rw) {
|
||||
locked_pid = uwsgi_rwlock_check(uli);
|
||||
}
|
||||
else {
|
||||
locked_pid = uwsgi_lock_check(uli);
|
||||
}
|
||||
if (locked_pid == diedpid) {
|
||||
uwsgi_log("[deadlock-detector] pid %d was holding lock %s (%p)\n", (int) diedpid, uli->id, uli->lock_ptr);
|
||||
if (uli->rw) {
|
||||
uwsgi_rwunlock(uli);
|
||||
}
|
||||
else {
|
||||
uwsgi_unlock(uli);
|
||||
}
|
||||
}
|
||||
while (uli) {
|
||||
if (!uli->can_deadlock)
|
||||
goto nextlock;
|
||||
pid_t locked_pid = 0;
|
||||
if (uli->rw) {
|
||||
locked_pid = uwsgi_rwlock_check(uli);
|
||||
}
|
||||
else {
|
||||
locked_pid = uwsgi_lock_check(uli);
|
||||
}
|
||||
if (locked_pid == diedpid) {
|
||||
uwsgi_log("[deadlock-detector] pid %d was holding lock %s (%p)\n", (int) diedpid, uli->id, uli->lock_ptr);
|
||||
if (uli->rw) {
|
||||
uwsgi_rwunlock(uli);
|
||||
}
|
||||
else {
|
||||
uwsgi_unlock(uli);
|
||||
}
|
||||
}
|
||||
nextlock:
|
||||
uli = uli->next;
|
||||
}
|
||||
uli = uli->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_user_lock(int lock_num) {
|
||||
uwsgi_lock(uwsgi.user_lock[lock_num]);
|
||||
uwsgi_lock(uwsgi.user_lock[lock_num]);
|
||||
}
|
||||
|
||||
void uwsgi_user_unlock(int lock_num) {
|
||||
uwsgi_unlock(uwsgi.user_lock[lock_num]);
|
||||
uwsgi_unlock(uwsgi.user_lock[lock_num]);
|
||||
}
|
||||
|
||||
|
||||
+404
-405
File diff suppressed because it is too large
Load Diff
+34
-33
@@ -10,18 +10,19 @@ struct wsgi_request *simple_current_wsgi_req() {
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_register_loop(char *name, void (*func)(void)) {
|
||||
void uwsgi_register_loop(char *name, void (*func) (void)) {
|
||||
|
||||
struct uwsgi_loop *old_loop = NULL, *loop = uwsgi.loops;
|
||||
|
||||
while(loop) {
|
||||
while (loop) {
|
||||
// check if the loop engine is already registered
|
||||
if (!strcmp(name, loop->name)) return;
|
||||
if (!strcmp(name, loop->name))
|
||||
return;
|
||||
old_loop = loop;
|
||||
loop = loop->next;
|
||||
}
|
||||
|
||||
loop = uwsgi_calloc(sizeof(struct uwsgi_loop));
|
||||
loop = uwsgi_calloc(sizeof(struct uwsgi_loop));
|
||||
loop->name = name;
|
||||
loop->loop = func;
|
||||
|
||||
@@ -37,7 +38,7 @@ void *uwsgi_get_loop(char *name) {
|
||||
|
||||
struct uwsgi_loop *loop = uwsgi.loops;
|
||||
|
||||
while(loop) {
|
||||
while (loop) {
|
||||
if (!strcmp(name, loop->name)) {
|
||||
return loop->loop;
|
||||
}
|
||||
@@ -61,56 +62,56 @@ void simple_loop() {
|
||||
uwsgi_loop_cores_run(simple_loop_run);
|
||||
}
|
||||
|
||||
void uwsgi_loop_cores_run(void *(*func)(void *)) {
|
||||
void uwsgi_loop_cores_run(void *(*func) (void *)) {
|
||||
int i;
|
||||
#ifdef UWSGI_THREADING
|
||||
for (i = 1; i < uwsgi.threads; i++) {
|
||||
long j = i;
|
||||
pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, func, (void *) j);
|
||||
long j = i;
|
||||
pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, func, (void *) j);
|
||||
}
|
||||
#endif
|
||||
long y = 0;
|
||||
func((void *) y);
|
||||
func((void *) y);
|
||||
}
|
||||
|
||||
void uwsgi_setup_thread_req(long core_id, struct wsgi_request *wsgi_req) {
|
||||
int i;
|
||||
sigset_t smask;
|
||||
sigset_t smask;
|
||||
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i);
|
||||
pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i);
|
||||
pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req);
|
||||
|
||||
if (core_id > 0) {
|
||||
// block all signals on new threads
|
||||
sigfillset(&smask);
|
||||
if (core_id > 0) {
|
||||
// block all signals on new threads
|
||||
sigfillset(&smask);
|
||||
#ifdef UWSGI_DEBUG
|
||||
sigdelset(&smask, SIGSEGV);
|
||||
sigdelset(&smask, SIGSEGV);
|
||||
#endif
|
||||
pthread_sigmask(SIG_BLOCK, &smask, NULL);
|
||||
pthread_sigmask(SIG_BLOCK, &smask, NULL);
|
||||
|
||||
// run per-thread socket hook
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
if (uwsgi_sock->proto_thread_fixup) {
|
||||
uwsgi_sock->proto_thread_fixup(uwsgi_sock, core_id);
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
// run per-thread socket hook
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->proto_thread_fixup) {
|
||||
uwsgi_sock->proto_thread_fixup(uwsgi_sock, core_id);
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->init_thread) {
|
||||
uwsgi.p[i]->init_thread(core_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->init_thread) {
|
||||
uwsgi.p[i]->init_thread(core_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void simple_loop_run_int(int core_id) {
|
||||
long y = core_id;
|
||||
simple_loop_run((void *) y);
|
||||
simple_loop_run((void *) y);
|
||||
}
|
||||
|
||||
void *simple_loop_run(void *arg1) {
|
||||
|
||||
+29
-25
@@ -15,8 +15,8 @@ void uwsgi_restore_auto_snapshot(int signum) {
|
||||
|
||||
void uwsgi_block_signal(int signum) {
|
||||
sigset_t smask;
|
||||
sigemptyset(&smask);
|
||||
sigaddset(&smask, signum);
|
||||
sigemptyset(&smask);
|
||||
sigaddset(&smask, signum);
|
||||
if (sigprocmask(SIG_BLOCK, &smask, NULL)) {
|
||||
uwsgi_error("sigprocmask()");
|
||||
}
|
||||
@@ -24,8 +24,8 @@ void uwsgi_block_signal(int signum) {
|
||||
|
||||
void uwsgi_unblock_signal(int signum) {
|
||||
sigset_t smask;
|
||||
sigemptyset(&smask);
|
||||
sigaddset(&smask, signum);
|
||||
sigemptyset(&smask);
|
||||
sigaddset(&smask, signum);
|
||||
if (sigprocmask(SIG_UNBLOCK, &smask, NULL)) {
|
||||
uwsgi_error("sigprocmask()");
|
||||
}
|
||||
@@ -270,7 +270,7 @@ int uwsgi_master_log(void) {
|
||||
#endif
|
||||
#ifdef UWSGI_PCRE
|
||||
struct uwsgi_regexp_list *url = uwsgi.log_drain_rules;
|
||||
while(url) {
|
||||
while (url) {
|
||||
if (uwsgi_regexp_match(url->pattern, url->pattern_extra, uwsgi.log_master_buf, rlen) >= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -279,35 +279,37 @@ int uwsgi_master_log(void) {
|
||||
if (uwsgi.log_filter_rules) {
|
||||
int show = 0;
|
||||
url = uwsgi.log_filter_rules;
|
||||
while(url) {
|
||||
while (url) {
|
||||
if (uwsgi_regexp_match(url->pattern, url->pattern_extra, uwsgi.log_master_buf, rlen) >= 0) {
|
||||
show = 1;
|
||||
break;
|
||||
}
|
||||
url = url->next;
|
||||
}
|
||||
if (!show) return 0;
|
||||
if (!show)
|
||||
return 0;
|
||||
}
|
||||
|
||||
url = uwsgi.log_route;
|
||||
int finish = 0;
|
||||
while(url) {
|
||||
while (url) {
|
||||
if (uwsgi_regexp_match(url->pattern, url->pattern_extra, uwsgi.log_master_buf, rlen) >= 0) {
|
||||
struct uwsgi_logger *ul_route = (struct uwsgi_logger *) url->custom_ptr;
|
||||
if (ul_route) {
|
||||
ul_route->func(ul_route, uwsgi.log_master_buf, rlen);
|
||||
finish = 1;
|
||||
}
|
||||
}
|
||||
url = url->next;
|
||||
}
|
||||
url = url->next;
|
||||
}
|
||||
if (finish) return 0;
|
||||
if (finish)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
int raw_log = 1;
|
||||
|
||||
struct uwsgi_logger *ul = uwsgi.choosen_logger;
|
||||
while(ul) {
|
||||
struct uwsgi_logger *ul = uwsgi.choosen_logger;
|
||||
while (ul) {
|
||||
// check for named logger
|
||||
if (ul->id) {
|
||||
goto next;
|
||||
@@ -738,10 +740,10 @@ int master_loop(char **argv, char **environ) {
|
||||
|
||||
if (uwsgi.requested_stats_pushers) {
|
||||
if (!uwsgi_thread_new(uwsgi_stats_pusher_loop)) {
|
||||
uwsgi_log("!!! unable to spawn stats pusher thread !!!\n");
|
||||
exit(1);
|
||||
uwsgi_log("!!! unable to spawn stats pusher thread !!!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket) {
|
||||
@@ -1243,12 +1245,12 @@ health_cycle:
|
||||
|
||||
int busy_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
if (uwsgi.workers[i].busy == 1) {
|
||||
busy_workers = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
if (uwsgi.workers[i].busy == 1) {
|
||||
busy_workers = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last_request_count != uwsgi.workers[0].requests) {
|
||||
@@ -1533,7 +1535,8 @@ health_cycle:
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_daemon_check_pid_death(diedpid)) goto next;
|
||||
if (uwsgi_daemon_check_pid_death(diedpid))
|
||||
goto next;
|
||||
|
||||
if (WIFEXITED(waitpid_status)) {
|
||||
uwsgi_log("subprocess %d exited with code %d\n", (int) diedpid, WEXITSTATUS(waitpid_status));
|
||||
@@ -1592,8 +1595,9 @@ next:
|
||||
uwsgi_log("DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int) diedpid);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("DAMN ! worker %d (pid: %d) MISTERIOUSLY died :( trying respawn ...\n", uwsgi.mywid, (int) diedpid);
|
||||
// manage_next_request is zero, but killed by signal...
|
||||
else if (WIFSIGNALED(waitpid_status)) {
|
||||
uwsgi_log("DAMN ! worker %d (pid: %d) MISTERIOUSLY killed by signal :( trying respawn ...\n", uwsgi.mywid, (int) diedpid, (int) WTERMSIG(waitpid_status));
|
||||
}
|
||||
|
||||
if (uwsgi.workers[uwsgi.mywid].cheaped == 1) {
|
||||
|
||||
+89
-83
@@ -7,24 +7,25 @@ void worker_wakeup() {
|
||||
|
||||
void uwsgi_master_cleanup_hooks(void) {
|
||||
|
||||
int j;
|
||||
int j;
|
||||
|
||||
// could be an inherited atexit hook
|
||||
if (uwsgi.mywid > 0) return ;
|
||||
|
||||
if (uwsgi.mywid > 0)
|
||||
return;
|
||||
|
||||
uwsgi.cleaning = 1;
|
||||
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->master_cleanup) {
|
||||
uwsgi.gp[j]->master_cleanup();
|
||||
}
|
||||
}
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->master_cleanup) {
|
||||
uwsgi.gp[j]->master_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (uwsgi.p[j]->master_cleanup) {
|
||||
uwsgi.p[j]->master_cleanup();
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (uwsgi.p[j]->master_cleanup) {
|
||||
uwsgi.p[j]->master_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -531,11 +532,11 @@ int uwsgi_respawn_worker(int wid) {
|
||||
// OVERENGINEERING (just to be safe)
|
||||
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
|
||||
/*
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = 0;
|
||||
uwsgi.workers[uwsgi.mywid].user_harakiri = 0;
|
||||
uwsgi.workers[uwsgi.mywid].rss_size = 0;
|
||||
uwsgi.workers[uwsgi.mywid].vsz_size = 0;
|
||||
*/
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = 0;
|
||||
uwsgi.workers[uwsgi.mywid].user_harakiri = 0;
|
||||
uwsgi.workers[uwsgi.mywid].rss_size = 0;
|
||||
uwsgi.workers[uwsgi.mywid].vsz_size = 0;
|
||||
*/
|
||||
// do not reset worker counters on reload !!!
|
||||
//uwsgi.workers[uwsgi.mywid].requests = 0;
|
||||
// ...but maintain a delta counter (yes this is racy in multithread)
|
||||
@@ -545,11 +546,11 @@ int uwsgi_respawn_worker(int wid) {
|
||||
//uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
|
||||
/*
|
||||
uwsgi.workers[uwsgi.mywid].cheaped = 0;
|
||||
uwsgi.workers[uwsgi.mywid].busy = 0;
|
||||
uwsgi.workers[uwsgi.mywid].suspended = 0;
|
||||
uwsgi.workers[uwsgi.mywid].sig = 0;
|
||||
*/
|
||||
uwsgi.workers[uwsgi.mywid].cheaped = 0;
|
||||
uwsgi.workers[uwsgi.mywid].busy = 0;
|
||||
uwsgi.workers[uwsgi.mywid].suspended = 0;
|
||||
uwsgi.workers[uwsgi.mywid].sig = 0;
|
||||
*/
|
||||
|
||||
// reset the apps count with a copy from the master
|
||||
uwsgi.workers[uwsgi.mywid].apps_cnt = uwsgi.workers[0].apps_cnt;
|
||||
@@ -576,7 +577,7 @@ int uwsgi_respawn_worker(int wid) {
|
||||
else {
|
||||
// the pid is set only in the master, as the worker should never use it
|
||||
uwsgi.workers[wid].pid = pid;
|
||||
|
||||
|
||||
if (respawns > 0) {
|
||||
uwsgi_log("Respawned uWSGI worker %d (new pid: %d)\n", wid, (int) pid);
|
||||
}
|
||||
@@ -861,43 +862,43 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_key(us, "sockets"))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_stats_object_open(us))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keyval_comma(us, "name", uwsgi_sock->name))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keyval_comma(us, "proto", uwsgi_sock->proto_name ? uwsgi_sock->proto_name : "uwsgi"))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "queue", (unsigned long long) uwsgi_sock->queue))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "shared", (unsigned long long) uwsgi_sock->shared))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "can_offload", (unsigned long long) uwsgi_sock->can_offload))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_object_close(us))
|
||||
goto end;
|
||||
|
||||
goto end;
|
||||
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
if (uwsgi_sock) {
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_stats_list_close(us))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end;
|
||||
@@ -926,16 +927,12 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
|
||||
if (uwsgi_stats_keylong_comma(us, "signals", (unsigned long long) uwsgi.workers[i + 1].signals))
|
||||
goto end;
|
||||
|
||||
if (ioctl(uwsgi.workers[i+1].signal_pipe[1], FIONREAD, &signal_queue)) {
|
||||
if (ioctl(uwsgi.workers[i + 1].signal_pipe[1], FIONREAD, &signal_queue)) {
|
||||
uwsgi_error("uwsgi_master_generate_stats() -> ioctl()\n");
|
||||
}
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "signal_queue", (unsigned long long) signal_queue))
|
||||
goto end;
|
||||
/*
|
||||
if (uwsgi_stats_keylong_comma(us, "static_offload_threads", (unsigned long long) uwsgi.workers[i + 1].static_offload_threads))
|
||||
goto end;
|
||||
*/
|
||||
|
||||
if (uwsgi.workers[i + 1].cheaped) {
|
||||
if (uwsgi_stats_keyval_comma(us, "status", "cheap"))
|
||||
@@ -1028,34 +1025,43 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
// cores list
|
||||
if (uwsgi_stats_key(us, "cores"))
|
||||
goto end;
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end;
|
||||
goto end;
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end;
|
||||
|
||||
for (j = 0; j < uwsgi.cores; j++) {
|
||||
struct uwsgi_core *uc = &uwsgi.workers[i + 1].cores[j];
|
||||
if (uwsgi_stats_object_open(us))
|
||||
goto end;
|
||||
goto end;
|
||||
if (uwsgi_stats_keylong_comma(us, "id", (unsigned long long) j))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "requests", (unsigned long long) uc->requests))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "static_requests", (unsigned long long) uc->static_requests))
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "routed_requests", (unsigned long long) uc->routed_requests))
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "offloaded_requests", (unsigned long long) uc->offloaded_requests))
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "in_request", (unsigned long long) uc->in_request))
|
||||
goto end;
|
||||
|
||||
goto end;
|
||||
|
||||
|
||||
if (uwsgi_stats_object_close(us))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (j < uwsgi.cores-1) {
|
||||
if (j < uwsgi.cores - 1) {
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,38 +1086,38 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end;
|
||||
if (uwsgi_stats_key(us, "spoolers"))
|
||||
goto end;
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end;
|
||||
while (uspool) {
|
||||
goto end;
|
||||
if (uwsgi_stats_list_open(us))
|
||||
goto end;
|
||||
while (uspool) {
|
||||
if (uwsgi_stats_object_open(us))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keyval_comma(us, "dir", uspool->dir))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) uspool->pid))
|
||||
goto end;
|
||||
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "tasks", (unsigned long long) uspool->tasks))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "respawns", (unsigned long long) uspool->respawned))
|
||||
goto end;
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "running", (unsigned long long) uspool->running))
|
||||
goto end;
|
||||
|
||||
goto end;
|
||||
|
||||
if (uwsgi_stats_object_close(us))
|
||||
goto end;
|
||||
uspool = uspool->next;
|
||||
goto end;
|
||||
uspool = uspool->next;
|
||||
if (uspool) {
|
||||
if (uwsgi_stats_comma(us))
|
||||
goto end;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uwsgi_stats_list_close(us))
|
||||
goto end;
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1156,7 +1162,7 @@ void uwsgi_register_cheaper_algo(char *name, int (*func) (void)) {
|
||||
|
||||
void trigger_harakiri(int i) {
|
||||
int j;
|
||||
uwsgi_log("*** HARAKIRI ON WORKER %d (pid: %d, try: %d) ***\n", i, uwsgi.workers[i].pid, uwsgi.workers[i].pending_harakiri+1);
|
||||
uwsgi_log("*** HARAKIRI ON WORKER %d (pid: %d, try: %d) ***\n", i, uwsgi.workers[i].pid, uwsgi.workers[i].pending_harakiri + 1);
|
||||
if (uwsgi.harakiri_verbose) {
|
||||
#ifdef __linux__
|
||||
int proc_file;
|
||||
@@ -1193,16 +1199,16 @@ void trigger_harakiri(int i) {
|
||||
}
|
||||
|
||||
if (uwsgi.workers[i].pid > 0) {
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->harakiri) {
|
||||
uwsgi.gp[j]->harakiri(i);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (uwsgi.p[j]->harakiri) {
|
||||
uwsgi.p[j]->harakiri(i);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->harakiri) {
|
||||
uwsgi.gp[j]->harakiri(i);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 256; j++) {
|
||||
if (uwsgi.p[j]->harakiri) {
|
||||
uwsgi.p[j]->harakiri(i);
|
||||
}
|
||||
}
|
||||
|
||||
kill(uwsgi.workers[i].pid, SIGUSR2);
|
||||
// allow SIGUSR2 to be delivered
|
||||
@@ -1210,7 +1216,7 @@ void trigger_harakiri(int i) {
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
if (!uwsgi.workers[i].pending_harakiri)
|
||||
uwsgi.workers[i].harakiri_count++;
|
||||
uwsgi.workers[i].pending_harakiri++;
|
||||
uwsgi.workers[i].pending_harakiri++;
|
||||
}
|
||||
// to avoid races
|
||||
|
||||
|
||||
+213
-208
@@ -19,14 +19,14 @@ void mule_send_msg(int fd, char *message, size_t len) {
|
||||
|
||||
if (write(fd, message, len) != (ssize_t) len) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
|
||||
uwsgi_error("getsockopt()");
|
||||
}
|
||||
uwsgi_log("*** MULE MSG QUEUE IS FULL: buffer size %d bytes (you can tune it with --signal-bufsize) ***\n", so_bufsize);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("mule_send_msg()");
|
||||
}
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
|
||||
uwsgi_error("getsockopt()");
|
||||
}
|
||||
uwsgi_log("*** MULE MSG QUEUE IS FULL: buffer size %d bytes (you can tune it with --signal-bufsize) ***\n", so_bufsize);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("mule_send_msg()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,54 +34,54 @@ void uwsgi_mule(int id) {
|
||||
|
||||
int i;
|
||||
|
||||
pid_t pid = uwsgi_fork(uwsgi.mules[id-1].name);
|
||||
pid_t pid = uwsgi_fork(uwsgi.mules[id - 1].name);
|
||||
if (pid == 0) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
uwsgi.muleid = id;
|
||||
// avoid race conditions
|
||||
uwsgi.mules[id-1].id = id;
|
||||
uwsgi.mules[id-1].pid = getpid();
|
||||
uwsgi.mules[id - 1].id = id;
|
||||
uwsgi.mules[id - 1].pid = getpid();
|
||||
|
||||
uwsgi_fixup_fds(0, id, NULL);
|
||||
|
||||
uwsgi.my_signal_socket = uwsgi.mules[id-1].signal_pipe[1];
|
||||
uwsgi.my_signal_socket = uwsgi.mules[id - 1].signal_pipe[1];
|
||||
uwsgi.signal_socket = uwsgi.shared->mule_signal_pipe[1];
|
||||
|
||||
uwsgi_close_all_sockets();
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->post_fork) {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->post_fork) {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.mules[id-1].patch) {
|
||||
if (uwsgi.mules[id - 1].patch) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->mule) {
|
||||
if (uwsgi.p[i]->mule(uwsgi.mules[id-1].patch) == 1) {
|
||||
if (uwsgi.p[i]->mule) {
|
||||
if (uwsgi.p[i]->mule(uwsgi.mules[id - 1].patch) == 1) {
|
||||
// never here
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_mule_handler();
|
||||
}
|
||||
else if (pid > 0) {
|
||||
uwsgi.mules[id-1].id = id;
|
||||
uwsgi.mules[id-1].pid = pid;
|
||||
uwsgi.mules[id - 1].id = id;
|
||||
uwsgi.mules[id - 1].pid = pid;
|
||||
uwsgi_log("spawned uWSGI mule %d (pid: %d)\n", id, (int) pid);
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ int uwsgi_farm_has_mule(struct uwsgi_farm *farm, int muleid) {
|
||||
|
||||
struct uwsgi_mule_farm *umf = farm->mules;
|
||||
|
||||
while(umf) {
|
||||
while (umf) {
|
||||
if (umf->mule->id == muleid) {
|
||||
return 1;
|
||||
}
|
||||
@@ -103,54 +103,54 @@ int uwsgi_farm_has_mule(struct uwsgi_farm *farm, int muleid) {
|
||||
int farm_has_signaled(int fd) {
|
||||
|
||||
int i;
|
||||
for(i=0;i<uwsgi.farms_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
|
||||
while(umf) {
|
||||
while (umf) {
|
||||
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].signal_pipe[1] == fd) {
|
||||
return 1;
|
||||
}
|
||||
umf = umf->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int farm_has_msg(int fd) {
|
||||
|
||||
int i;
|
||||
for(i=0;i<uwsgi.farms_cnt;i++) {
|
||||
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
|
||||
while(umf) {
|
||||
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].queue_pipe[1] == fd) {
|
||||
return 1;
|
||||
}
|
||||
umf = umf->next;
|
||||
}
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
|
||||
while (umf) {
|
||||
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].queue_pipe[1] == fd) {
|
||||
return 1;
|
||||
}
|
||||
umf = umf->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_mule_add_farm_to_queue(int queue) {
|
||||
|
||||
int i;
|
||||
for(i=0;i<uwsgi.farms_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
|
||||
event_queue_add_fd_read(queue, uwsgi.farms[i].signal_pipe[1]);
|
||||
event_queue_add_fd_read(queue, uwsgi.farms[i].queue_pipe[1]);
|
||||
event_queue_add_fd_read(queue, uwsgi.farms[i].signal_pipe[1]);
|
||||
event_queue_add_fd_read(queue, uwsgi.farms[i].queue_pipe[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_mule_handler() {
|
||||
|
||||
|
||||
ssize_t len;
|
||||
uint8_t uwsgi_signal;
|
||||
int rlen;
|
||||
int interesting_fd;
|
||||
|
||||
|
||||
// this must be configurable
|
||||
char message[65536];
|
||||
|
||||
@@ -158,12 +158,12 @@ void uwsgi_mule_handler() {
|
||||
|
||||
event_queue_add_fd_read(mule_queue, uwsgi.signal_socket);
|
||||
event_queue_add_fd_read(mule_queue, uwsgi.my_signal_socket);
|
||||
event_queue_add_fd_read(mule_queue, uwsgi.mules[uwsgi.muleid-1].queue_pipe[1]);
|
||||
event_queue_add_fd_read(mule_queue, uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1]);
|
||||
event_queue_add_fd_read(mule_queue, uwsgi.shared->mule_queue_pipe[1]);
|
||||
|
||||
uwsgi_mule_add_farm_to_queue(mule_queue);
|
||||
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
rlen = event_queue_wait(mule_queue, -1, &interesting_fd);
|
||||
if (rlen <= 0) {
|
||||
continue;
|
||||
@@ -172,31 +172,31 @@ void uwsgi_mule_handler() {
|
||||
if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket || farm_has_signaled(interesting_fd)) {
|
||||
len = read(interesting_fd, &uwsgi_signal, 1);
|
||||
if (len <= 0) {
|
||||
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
|
||||
end_me(0);
|
||||
}
|
||||
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
|
||||
end_me(0);
|
||||
}
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
|
||||
}
|
||||
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
|
||||
}
|
||||
}
|
||||
else if (interesting_fd == uwsgi.mules[uwsgi.muleid-1].queue_pipe[1] || interesting_fd == uwsgi.shared->mule_queue_pipe[1] || farm_has_msg(interesting_fd)) {
|
||||
else if (interesting_fd == uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1] || interesting_fd == uwsgi.shared->mule_queue_pipe[1] || farm_has_msg(interesting_fd)) {
|
||||
len = read(interesting_fd, message, 65536);
|
||||
if (len < 0) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
}
|
||||
else {
|
||||
int i,found = 0;
|
||||
for(i=0;i<256;i++) {
|
||||
if (uwsgi.p[i]->mule_msg) {
|
||||
if (uwsgi.p[i]->mule_msg(message, len)) {
|
||||
int i, found = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->mule_msg) {
|
||||
if (uwsgi.p[i]->mule_msg(message, len)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
uwsgi_log("*** mule %d received a %d bytes message ***\n", uwsgi.muleid, len);
|
||||
}
|
||||
@@ -209,7 +209,7 @@ struct uwsgi_mule *get_mule_by_id(int id) {
|
||||
|
||||
int i;
|
||||
|
||||
for(i=0;i<uwsgi.mules_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.mules_cnt; i++) {
|
||||
if (uwsgi.mules[i].id == id) {
|
||||
return &uwsgi.mules[i];
|
||||
}
|
||||
@@ -220,229 +220,234 @@ struct uwsgi_mule *get_mule_by_id(int id) {
|
||||
|
||||
struct uwsgi_farm *get_farm_by_name(char *name) {
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for(i=0;i<uwsgi.farms_cnt;i++) {
|
||||
if (!strcmp(uwsgi.farms[i].name, name)) {
|
||||
return &uwsgi.farms[i];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
if (!strcmp(uwsgi.farms[i].name, name)) {
|
||||
return &uwsgi.farms[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_mule_farm *uwsgi_mule_farm_new(struct uwsgi_mule_farm **umf, struct uwsgi_mule *um) {
|
||||
|
||||
struct uwsgi_mule_farm *uwsgi_mf = *umf, *old_umf;
|
||||
struct uwsgi_mule_farm *uwsgi_mf = *umf, *old_umf;
|
||||
|
||||
if (!uwsgi_mf) {
|
||||
*umf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
|
||||
uwsgi_mf = *umf;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_mf) {
|
||||
old_umf = uwsgi_mf;
|
||||
if (!uwsgi_mf) {
|
||||
*umf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
|
||||
uwsgi_mf = *umf;
|
||||
}
|
||||
else {
|
||||
while (uwsgi_mf) {
|
||||
old_umf = uwsgi_mf;
|
||||
uwsgi_mf = uwsgi_mf->next;
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_mf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
|
||||
old_umf->next = uwsgi_mf;
|
||||
}
|
||||
uwsgi_mf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
|
||||
old_umf->next = uwsgi_mf;
|
||||
}
|
||||
|
||||
uwsgi_mf->mule = um;
|
||||
uwsgi_mf->next = NULL;
|
||||
uwsgi_mf->mule = um;
|
||||
uwsgi_mf->next = NULL;
|
||||
|
||||
return uwsgi_mf;
|
||||
return uwsgi_mf;
|
||||
}
|
||||
|
||||
ssize_t uwsgi_mule_get_msg(int manage_signals, int manage_farms, char *message, size_t buffer_size, int timeout) {
|
||||
|
||||
ssize_t len = 0;
|
||||
struct pollfd *mulepoll;
|
||||
int count = 4;
|
||||
int farms_count = 0;
|
||||
uint8_t uwsgi_signal;
|
||||
int i;
|
||||
ssize_t len = 0;
|
||||
struct pollfd *mulepoll;
|
||||
int count = 4;
|
||||
int farms_count = 0;
|
||||
uint8_t uwsgi_signal;
|
||||
int i;
|
||||
|
||||
if (uwsgi.muleid == 0) return -1;
|
||||
if (uwsgi.muleid == 0)
|
||||
return -1;
|
||||
|
||||
if (manage_signals) count = 2;
|
||||
if (manage_signals)
|
||||
count = 2;
|
||||
|
||||
if (!manage_farms) goto next;
|
||||
if (!manage_farms)
|
||||
goto next;
|
||||
|
||||
for(i=0;i<uwsgi.farms_cnt;i++) {
|
||||
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) farms_count++;
|
||||
}
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid))
|
||||
farms_count++;
|
||||
}
|
||||
next:
|
||||
|
||||
if (timeout > -1) timeout = timeout*1000;
|
||||
if (timeout > -1)
|
||||
timeout = timeout * 1000;
|
||||
|
||||
mulepoll = uwsgi_malloc(sizeof(struct pollfd) * (count+farms_count));
|
||||
mulepoll = uwsgi_malloc(sizeof(struct pollfd) * (count + farms_count));
|
||||
|
||||
mulepoll[0].fd = uwsgi.mules[uwsgi.muleid-1].queue_pipe[1];
|
||||
mulepoll[0].events = POLLIN;
|
||||
mulepoll[1].fd = uwsgi.shared->mule_queue_pipe[1];
|
||||
mulepoll[1].events = POLLIN;
|
||||
if (count > 2) {
|
||||
mulepoll[2].fd = uwsgi.signal_socket;
|
||||
mulepoll[2].events = POLLIN;
|
||||
mulepoll[3].fd = uwsgi.my_signal_socket;
|
||||
mulepoll[3].events = POLLIN;
|
||||
}
|
||||
mulepoll[0].fd = uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1];
|
||||
mulepoll[0].events = POLLIN;
|
||||
mulepoll[1].fd = uwsgi.shared->mule_queue_pipe[1];
|
||||
mulepoll[1].events = POLLIN;
|
||||
if (count > 2) {
|
||||
mulepoll[2].fd = uwsgi.signal_socket;
|
||||
mulepoll[2].events = POLLIN;
|
||||
mulepoll[3].fd = uwsgi.my_signal_socket;
|
||||
mulepoll[3].events = POLLIN;
|
||||
}
|
||||
|
||||
if (farms_count > 0) {
|
||||
int tmp_cnt = 0;
|
||||
for(i=0;i<uwsgi.farms_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
|
||||
mulepoll[count+tmp_cnt].fd = uwsgi.farms[i].queue_pipe[1];
|
||||
mulepoll[count+tmp_cnt].events = POLLIN;
|
||||
mulepoll[count + tmp_cnt].fd = uwsgi.farms[i].queue_pipe[1];
|
||||
mulepoll[count + tmp_cnt].events = POLLIN;
|
||||
tmp_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ret = poll(mulepoll, count+farms_count, timeout);
|
||||
if (ret <= 0) {
|
||||
uwsgi_error("poll");
|
||||
}
|
||||
else {
|
||||
if (mulepoll[0].revents & POLLIN) {
|
||||
len = read(uwsgi.mules[uwsgi.muleid-1].queue_pipe[1], message, buffer_size);
|
||||
}
|
||||
else if (mulepoll[1].revents & POLLIN) {
|
||||
len = read(uwsgi.shared->mule_queue_pipe[1], message, buffer_size);
|
||||
}
|
||||
else {
|
||||
if (count > 2) {
|
||||
int interesting_fd = -1;
|
||||
if (mulepoll[2].revents & POLLIN) {
|
||||
interesting_fd = mulepoll[2].fd;
|
||||
}
|
||||
else if (mulepoll[3].revents & POLLIN) {
|
||||
interesting_fd = mulepoll[3].fd;
|
||||
}
|
||||
int ret = poll(mulepoll, count + farms_count, timeout);
|
||||
if (ret <= 0) {
|
||||
uwsgi_error("poll");
|
||||
}
|
||||
else {
|
||||
if (mulepoll[0].revents & POLLIN) {
|
||||
len = read(uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1], message, buffer_size);
|
||||
}
|
||||
else if (mulepoll[1].revents & POLLIN) {
|
||||
len = read(uwsgi.shared->mule_queue_pipe[1], message, buffer_size);
|
||||
}
|
||||
else {
|
||||
if (count > 2) {
|
||||
int interesting_fd = -1;
|
||||
if (mulepoll[2].revents & POLLIN) {
|
||||
interesting_fd = mulepoll[2].fd;
|
||||
}
|
||||
else if (mulepoll[3].revents & POLLIN) {
|
||||
interesting_fd = mulepoll[3].fd;
|
||||
}
|
||||
|
||||
if (interesting_fd > -1) {
|
||||
len = read(interesting_fd, &uwsgi_signal, 1);
|
||||
if (len <= 0) {
|
||||
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
|
||||
end_me(0);
|
||||
}
|
||||
if (interesting_fd > -1) {
|
||||
len = read(interesting_fd, &uwsgi_signal, 1);
|
||||
if (len <= 0) {
|
||||
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
|
||||
end_me(0);
|
||||
}
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
|
||||
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
}
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
}
|
||||
// set the error condition
|
||||
len = -1;
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
|
||||
// read messages in the farm
|
||||
for(i=0;i<farms_count;i++) {
|
||||
if (mulepoll[count+i].revents & POLLIN) {
|
||||
len = read(mulepoll[count+i].fd, message, buffer_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < farms_count; i++) {
|
||||
if (mulepoll[count + i].revents & POLLIN) {
|
||||
len = read(mulepoll[count + i].fd, message, buffer_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
uwsgi_error("read()");
|
||||
goto clear;
|
||||
}
|
||||
if (len < 0) {
|
||||
uwsgi_error("read()");
|
||||
goto clear;
|
||||
}
|
||||
|
||||
clear:
|
||||
free(mulepoll);
|
||||
return len;
|
||||
free(mulepoll);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_opt_add_mule(char *opt, char *value, void *foobar) {
|
||||
|
||||
uwsgi.mules_cnt++;
|
||||
uwsgi_string_new_list(&uwsgi.mules_patches, value);
|
||||
uwsgi_string_new_list(&uwsgi.mules_patches, value);
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_mules(char *opt, char *value, void *foobar) {
|
||||
int i;
|
||||
|
||||
for(i=0;i<atoi(value);i++) {
|
||||
uwsgi.mules_cnt++;
|
||||
uwsgi_string_new_list(&uwsgi.mules_patches, NULL);
|
||||
}
|
||||
for (i = 0; i < atoi(value); i++) {
|
||||
uwsgi.mules_cnt++;
|
||||
uwsgi_string_new_list(&uwsgi.mules_patches, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_farm(char *opt, char *value, void *foobar) {
|
||||
uwsgi.farms_cnt++;
|
||||
uwsgi_string_new_list(&uwsgi.farms_list, value);
|
||||
uwsgi_string_new_list(&uwsgi.farms_list, value);
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_setup_mules_and_farms() {
|
||||
int i;
|
||||
if (uwsgi.mules_cnt > 0) {
|
||||
uwsgi.mules = (struct uwsgi_mule *) uwsgi_calloc_shared(sizeof(struct uwsgi_mule) * uwsgi.mules_cnt);
|
||||
uwsgi.mules = (struct uwsgi_mule *) uwsgi_calloc_shared(sizeof(struct uwsgi_mule) * uwsgi.mules_cnt);
|
||||
|
||||
create_signal_pipe(uwsgi.shared->mule_signal_pipe);
|
||||
create_signal_pipe(uwsgi.shared->mule_queue_pipe);
|
||||
create_signal_pipe(uwsgi.shared->mule_signal_pipe);
|
||||
create_signal_pipe(uwsgi.shared->mule_queue_pipe);
|
||||
|
||||
for (i = 0; i < uwsgi.mules_cnt; i++) {
|
||||
// create the socket pipe
|
||||
create_signal_pipe(uwsgi.mules[i].signal_pipe);
|
||||
create_signal_pipe(uwsgi.mules[i].queue_pipe);
|
||||
for (i = 0; i < uwsgi.mules_cnt; i++) {
|
||||
// create the socket pipe
|
||||
create_signal_pipe(uwsgi.mules[i].signal_pipe);
|
||||
create_signal_pipe(uwsgi.mules[i].queue_pipe);
|
||||
|
||||
uwsgi.mules[i].id = i + 1;
|
||||
uwsgi.mules[i].id = i + 1;
|
||||
|
||||
snprintf(uwsgi.mules[i].name, 0xff, "uWSGI mule %d", i + 1);
|
||||
}
|
||||
}
|
||||
snprintf(uwsgi.mules[i].name, 0xff, "uWSGI mule %d", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.farms_cnt > 0) {
|
||||
uwsgi.farms = (struct uwsgi_farm *) uwsgi_calloc_shared(sizeof(struct uwsgi_farm) * uwsgi.farms_cnt);
|
||||
if (uwsgi.farms_cnt > 0) {
|
||||
uwsgi.farms = (struct uwsgi_farm *) uwsgi_calloc_shared(sizeof(struct uwsgi_farm) * uwsgi.farms_cnt);
|
||||
|
||||
struct uwsgi_string_list *farm_name = uwsgi.farms_list;
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
struct uwsgi_string_list *farm_name = uwsgi.farms_list;
|
||||
for (i = 0; i < uwsgi.farms_cnt; i++) {
|
||||
|
||||
char *farm_value = uwsgi_str(farm_name->value);
|
||||
char *farm_value = uwsgi_str(farm_name->value);
|
||||
|
||||
char *mules_list = strchr(farm_value, ':');
|
||||
if (!mules_list) {
|
||||
uwsgi_log("invalid farm value (%s) must be in the form name:mule[,muleN].\n", farm_value);
|
||||
exit(1);
|
||||
}
|
||||
char *mules_list = strchr(farm_value, ':');
|
||||
if (!mules_list) {
|
||||
uwsgi_log("invalid farm value (%s) must be in the form name:mule[,muleN].\n", farm_value);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mules_list[0] = 0;
|
||||
mules_list++;
|
||||
mules_list[0] = 0;
|
||||
mules_list++;
|
||||
|
||||
strncpy(uwsgi.farms[i].name, farm_value, 0xff);
|
||||
strncpy(uwsgi.farms[i].name, farm_value, 0xff);
|
||||
|
||||
// create the socket pipe
|
||||
create_signal_pipe(uwsgi.farms[i].signal_pipe);
|
||||
create_signal_pipe(uwsgi.farms[i].queue_pipe);
|
||||
// create the socket pipe
|
||||
create_signal_pipe(uwsgi.farms[i].signal_pipe);
|
||||
create_signal_pipe(uwsgi.farms[i].queue_pipe);
|
||||
|
||||
char *p = strtok(mules_list, ",");
|
||||
while (p != NULL) {
|
||||
struct uwsgi_mule *um = get_mule_by_id(atoi(p));
|
||||
if (!um) {
|
||||
uwsgi_log("invalid mule id: %s\n", p);
|
||||
exit(1);
|
||||
}
|
||||
char *p = strtok(mules_list, ",");
|
||||
while (p != NULL) {
|
||||
struct uwsgi_mule *um = get_mule_by_id(atoi(p));
|
||||
if (!um) {
|
||||
uwsgi_log("invalid mule id: %s\n", p);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_mule_farm_new(&uwsgi.farms[i].mules, um);
|
||||
uwsgi_mule_farm_new(&uwsgi.farms[i].mules, um);
|
||||
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
uwsgi_log("created farm %d name: %s mules:%s\n", i + 1, uwsgi.farms[i].name, strchr(farm_name->value, ':') + 1);
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
uwsgi_log("created farm %d name: %s mules:%s\n", i + 1, uwsgi.farms[i].name, strchr(farm_name->value, ':') + 1);
|
||||
|
||||
farm_name = farm_name->next;
|
||||
farm_name = farm_name->next;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-10
@@ -16,7 +16,7 @@ void uwsgi_systemd_notify(char *message) {
|
||||
iovec[1].iov_len = strlen(message);
|
||||
|
||||
iovec[2].iov_base = "\n";
|
||||
iovec[2].iov_len = 1;
|
||||
iovec[2].iov_len = 1;
|
||||
|
||||
msghdr->msg_iovlen = 3;
|
||||
|
||||
@@ -26,15 +26,15 @@ void uwsgi_systemd_notify(char *message) {
|
||||
void uwsgi_systemd_notify_ready(void) {
|
||||
|
||||
struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object;
|
||||
struct iovec *iovec = msghdr->msg_iov;
|
||||
struct iovec *iovec = msghdr->msg_iov;
|
||||
|
||||
iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n";
|
||||
iovec[0].iov_len = 30;
|
||||
iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n";
|
||||
iovec[0].iov_len = 30;
|
||||
|
||||
msghdr->msg_iovlen = 1;
|
||||
|
||||
sendmsg(uwsgi.notification_fd, msghdr, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -54,20 +54,21 @@ void uwsgi_systemd_init(char *systemd_socket) {
|
||||
memset(sd_sun, 0, sizeof(struct sockaddr_un));
|
||||
sd_sun->sun_family = AF_UNIX;
|
||||
strncpy(sd_sun->sun_path, systemd_socket, UMIN(len, sizeof(sd_sun->sun_path)));
|
||||
if (sd_sun->sun_path[0] == '@') sd_sun->sun_path[0] = 0;
|
||||
if (sd_sun->sun_path[0] == '@')
|
||||
sd_sun->sun_path[0] = 0;
|
||||
|
||||
msghdr = uwsgi_malloc(sizeof(struct msghdr));
|
||||
memset(msghdr, 0, sizeof(struct msghdr));
|
||||
|
||||
msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec)*3);
|
||||
memset(msghdr->msg_iov, 0, sizeof(struct iovec)*3);
|
||||
msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec) * 3);
|
||||
memset(msghdr->msg_iov, 0, sizeof(struct iovec) * 3);
|
||||
|
||||
msghdr->msg_name = sd_sun;
|
||||
msghdr->msg_namelen = sizeof(struct sockaddr_un) - (sizeof(sd_sun->sun_path)-len);
|
||||
msghdr->msg_namelen = sizeof(struct sockaddr_un) - (sizeof(sd_sun->sun_path) - len);
|
||||
|
||||
uwsgi.notification_object = msghdr;
|
||||
|
||||
uwsgi.notify = uwsgi_systemd_notify;
|
||||
uwsgi.notify_ready = uwsgi_systemd_notify_ready;
|
||||
|
||||
|
||||
}
|
||||
|
||||
+389
@@ -0,0 +1,389 @@
|
||||
#include "uwsgi.h"
|
||||
|
||||
/*
|
||||
|
||||
uWSGI offloading subsystem
|
||||
|
||||
*/
|
||||
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#define uwsgi_offload_retry if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) return 0;
|
||||
#define uwsgi_offload_0r_1w(x, y) if (event_queue_del_fd(ut->queue, x, event_queue_read())) return -1;\
|
||||
if (event_queue_fd_read_to_write(ut->queue, y)) return -1;
|
||||
|
||||
static int uwsgi_offload_net_transfer(struct uwsgi_thread *, struct uwsgi_offload_request *, int);
|
||||
static int uwsgi_offload_sendfile_transfer(struct uwsgi_thread *, struct uwsgi_offload_request *, int);
|
||||
|
||||
static void uwsgi_offload_setup(struct uwsgi_offload_request *uor, struct wsgi_request *wsgi_req,
|
||||
int (*func)(struct uwsgi_thread *, struct uwsgi_offload_request *, int)) {
|
||||
|
||||
wsgi_req->fd_closed = 1;
|
||||
memset(uor, 0, sizeof(struct uwsgi_offload_request));
|
||||
uor->s = wsgi_req->poll.fd;
|
||||
uor->func = func;
|
||||
// put socket in non-blocking mode
|
||||
uwsgi_socket_nb(uor->s);
|
||||
|
||||
}
|
||||
|
||||
static int uwsgi_offload_enqueue(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor) {
|
||||
struct uwsgi_core *uc = &uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id];
|
||||
uc->offloaded_requests++;
|
||||
// round robin
|
||||
if (uc->offload_rr >= uwsgi.offload_threads) {
|
||||
uc->offload_rr = 0;
|
||||
}
|
||||
struct uwsgi_thread *ut = uwsgi.offload_thread[uc->offload_rr];
|
||||
uc->offload_rr++;
|
||||
if (write(ut->pipe[0], uor, sizeof(struct uwsgi_offload_request)) != sizeof(struct uwsgi_offload_request)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_offload_request_net_do(struct wsgi_request *wsgi_req, char *socket, struct uwsgi_buffer *ubuf) {
|
||||
|
||||
// fill offload request
|
||||
struct uwsgi_offload_request uor;
|
||||
uwsgi_offload_setup(&uor, wsgi_req, uwsgi_offload_net_transfer);
|
||||
|
||||
uor.fd = uwsgi_connect(socket, 0, 1);
|
||||
if (uor.fd < 0) {
|
||||
uwsgi_error("uwsgi_offload_request_net_do() -> connect()");
|
||||
goto error;
|
||||
}
|
||||
|
||||
uor.ubuf = ubuf;
|
||||
|
||||
if (uwsgi_offload_enqueue(wsgi_req, &uor)) {
|
||||
goto error2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error2:
|
||||
close(uor.fd);
|
||||
error:
|
||||
wsgi_req->fd_closed = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int uwsgi_offload_request_sendfile_do(struct wsgi_request *wsgi_req, char *filename, size_t len) {
|
||||
|
||||
// fill offload request
|
||||
struct uwsgi_offload_request uor;
|
||||
uwsgi_offload_setup(&uor, wsgi_req, uwsgi_offload_sendfile_transfer);
|
||||
|
||||
uor.fd = open(filename, O_RDONLY | O_NONBLOCK);
|
||||
if (uor.fd < 0) {
|
||||
uwsgi_error_open(filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// make a fstat to get the file size
|
||||
if (!len) {
|
||||
struct stat st;
|
||||
if (fstat(uor.fd, &st)) {
|
||||
uwsgi_error("fstat()");
|
||||
goto error2;
|
||||
}
|
||||
len = st.st_size;
|
||||
}
|
||||
|
||||
uor.len = len;
|
||||
|
||||
if (uwsgi_offload_enqueue(wsgi_req, &uor)) {
|
||||
goto error2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error2:
|
||||
close(uor.fd);
|
||||
error:
|
||||
wsgi_req->fd_closed = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void uwsgi_offload_close(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor) {
|
||||
// close the socket and the file descriptor
|
||||
close(uor->s);
|
||||
close(uor->fd);
|
||||
// remove the structure from the linked list;
|
||||
struct uwsgi_offload_request *prev = uor->prev;
|
||||
struct uwsgi_offload_request *next = uor->next;
|
||||
|
||||
if (uor == ut->offload_requests_head) {
|
||||
ut->offload_requests_head = next;
|
||||
}
|
||||
|
||||
if (uor == ut->offload_requests_tail) {
|
||||
ut->offload_requests_tail = prev;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
if (uor->buf) {
|
||||
free(uor->buf);
|
||||
}
|
||||
|
||||
if (uor->ubuf) {
|
||||
uwsgi_buffer_destroy(uor->ubuf);
|
||||
}
|
||||
|
||||
free(uor);
|
||||
}
|
||||
|
||||
static void uwsgi_offload_append(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor) {
|
||||
|
||||
if (!ut->offload_requests_head) {
|
||||
ut->offload_requests_head = uor;
|
||||
}
|
||||
|
||||
if (ut->offload_requests_tail) {
|
||||
ut->offload_requests_tail->next = uor;
|
||||
uor->prev = ut->offload_requests_tail;
|
||||
}
|
||||
|
||||
ut->offload_requests_tail = uor;
|
||||
}
|
||||
|
||||
static struct uwsgi_offload_request *uwsgi_offload_get_by_fd(struct uwsgi_thread *ut, int s) {
|
||||
struct uwsgi_offload_request *uor = ut->offload_requests_head;
|
||||
while (uor) {
|
||||
if (uor->s == s || uor->fd == s) {
|
||||
return uor;
|
||||
}
|
||||
uor = uor->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void uwsgi_offload_loop(struct uwsgi_thread *ut) {
|
||||
|
||||
int i;
|
||||
void *events = event_queue_alloc(uwsgi.offload_threads_events);
|
||||
|
||||
for (;;) {
|
||||
int nevents = event_queue_wait_multi(ut->queue, -1, events, uwsgi.offload_threads_events);
|
||||
for (i = 0; i < nevents; i++) {
|
||||
int interesting_fd = event_queue_interesting_fd(events, i);
|
||||
if (interesting_fd == ut->pipe[1]) {
|
||||
struct uwsgi_offload_request *uor = uwsgi_malloc(sizeof(struct uwsgi_offload_request));
|
||||
ssize_t len = read(ut->pipe[1], uor, sizeof(struct uwsgi_offload_request));
|
||||
if (len != sizeof(struct uwsgi_offload_request)) {
|
||||
uwsgi_error("read()");
|
||||
free(uor);
|
||||
continue;
|
||||
}
|
||||
// start monitoring socket for write
|
||||
if (uor->func(ut, uor, -1)) {
|
||||
uwsgi_offload_close(ut, uor);
|
||||
continue;
|
||||
}
|
||||
uwsgi_offload_append(ut, uor);
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the task from the interesting fd
|
||||
struct uwsgi_offload_request *uor = uwsgi_offload_get_by_fd(ut, interesting_fd);
|
||||
if (!uor)
|
||||
continue;
|
||||
// run the hook
|
||||
if (uor->func(ut, uor, interesting_fd)) {
|
||||
uwsgi_offload_close(ut, uor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_thread *uwsgi_offload_thread_start() {
|
||||
return uwsgi_thread_new(uwsgi_offload_loop);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
the offload task starts after having acquired the file fd
|
||||
|
||||
uor->len -> the size of the file
|
||||
uor->pos -> start writing from pos (default 0)
|
||||
|
||||
status: none
|
||||
|
||||
*/
|
||||
|
||||
static int uwsgi_offload_sendfile_transfer(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor, int fd) {
|
||||
|
||||
if (fd == -1) {
|
||||
if (event_queue_add_fd_write(ut->queue, uor->s)) return -1;
|
||||
return 0;
|
||||
}
|
||||
#if defined(__linux__) || defined(__sun__)
|
||||
ssize_t len = sendfile(uor->s, uor->fd, &uor->pos, 128 * 1024);
|
||||
if (len > 0) {
|
||||
uor->written += len;
|
||||
if (uor->written >= uor->len) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (len < 0) {
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("sendfile()");
|
||||
}
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
off_t sbytes = 0;
|
||||
int ret = sendfile(uor->fd, uor->s, uor->pos, 0, NULL, &sbytes, 0);
|
||||
// transfer finished
|
||||
if (ret == -1) {
|
||||
uor->pos += sbytes;
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("sendfile()");
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
off_t len = 0;
|
||||
int ret = sendfile(uor->fd, uor->s, uor->pos, &len, NULL, 0);
|
||||
// transfer finished
|
||||
if (ret == -1) {
|
||||
uor->pos += len;
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("sendfile()");
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
the offload task starts soon after the call to connect()
|
||||
|
||||
status:
|
||||
0 -> waiting for connection on fd
|
||||
1 -> sending request to fd (write event)
|
||||
2 -> start waiting for read on s and fd
|
||||
3 -> write to s
|
||||
4 -> write to fd
|
||||
*/
|
||||
static int uwsgi_offload_net_transfer(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor, int fd) {
|
||||
|
||||
ssize_t rlen;
|
||||
|
||||
// setup
|
||||
if (fd == -1) {
|
||||
event_queue_add_fd_write(ut->queue, uor->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(uor->status) {
|
||||
// waiting for connection
|
||||
case 0:
|
||||
if (fd == uor->fd) {
|
||||
uor->status = 1;
|
||||
// ok try to send the request right now...
|
||||
return uwsgi_offload_net_transfer(ut, uor, fd);
|
||||
}
|
||||
return -1;
|
||||
// write event (or just connected)
|
||||
case 1:
|
||||
if (fd == uor->fd) {
|
||||
rlen = write(uor->fd, uor->ubuf->buf + uor->written, uor->ubuf->pos-uor->written);
|
||||
if (rlen > 0) {
|
||||
uor->written += rlen;
|
||||
if (uor->written >= (size_t)uor->ubuf->pos) {
|
||||
uor->status = 2;
|
||||
if (event_queue_add_fd_read(ut->queue, uor->s)) return -1;
|
||||
if (event_queue_fd_write_to_read(ut->queue, uor->fd)) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (rlen < 0) {
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("uwsgi_offload_net_transfer() -> write()");
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
// read event from s or fd
|
||||
case 2:
|
||||
if (!uor->buf) {
|
||||
uor->buf = uwsgi_malloc(4096);
|
||||
}
|
||||
if (fd == uor->fd) {
|
||||
rlen = read(uor->fd, uor->buf, 4096);
|
||||
if (rlen > 0) {
|
||||
uor->to_write = rlen;
|
||||
uor->pos = 0;
|
||||
uwsgi_offload_0r_1w(uor->fd, uor->s)
|
||||
uor->status = 3;
|
||||
return 0;
|
||||
}
|
||||
if (rlen < 0) {
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("uwsgi_offload_net_transfer() -> read()/fd");
|
||||
}
|
||||
}
|
||||
else if (fd == uor->s) {
|
||||
rlen = read(uor->fd, uor->buf, 4096);
|
||||
if (rlen > 0) {
|
||||
uor->to_write = rlen;
|
||||
uor->pos = 0;
|
||||
uwsgi_offload_0r_1w(uor->s, uor->fd)
|
||||
uor->status = 4;
|
||||
return 0;
|
||||
}
|
||||
if (rlen < 0) {
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("uwsgi_offload_net_transfer() -> read()/s");
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
// write event on s
|
||||
case 3:
|
||||
rlen = write(uor->s, uor->buf + uor->pos, uor->to_write);
|
||||
if (rlen > 0) {
|
||||
uor->to_write -= rlen;
|
||||
uor->pos += rlen;
|
||||
if (uor->to_write == 0) {
|
||||
if (event_queue_fd_write_to_read(ut->queue, uor->s)) return -1;
|
||||
if (event_queue_add_fd_read(ut->queue, uor->fd)) return -1;
|
||||
uor->status = 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (rlen < 0) {
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("uwsgi_offload_net_transfer() -> write()/s");
|
||||
}
|
||||
return -1;
|
||||
// write event on fd
|
||||
case 4:
|
||||
rlen = write(uor->fd, uor->buf + uor->pos, uor->to_write);
|
||||
if (rlen > 0) {
|
||||
uor->to_write -= rlen;
|
||||
uor->pos += rlen;
|
||||
if (uor->to_write == 0) {
|
||||
if (event_queue_fd_write_to_read(ut->queue, uor->fd)) return -1;
|
||||
if (event_queue_add_fd_read(ut->queue, uor->s)) return -1;
|
||||
uor->status = 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (rlen < 0) {
|
||||
uwsgi_offload_retry
|
||||
uwsgi_error("uwsgi_offload_net_transfer() -> write()/fd");
|
||||
}
|
||||
return -1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
+60
-59
@@ -9,12 +9,12 @@ static void uwsgi_plugin_parse_section(char *filename) {
|
||||
if (buf) {
|
||||
char *ctx = NULL;
|
||||
char *p = strtok_r(buf, "\n", &ctx);
|
||||
while(p) {
|
||||
while (p) {
|
||||
char *equal = strchr(p, '=');
|
||||
if (equal) {
|
||||
*equal = 0;
|
||||
if (!strcmp(p, "requires")) {
|
||||
uwsgi_load_plugin(-1, equal+1, NULL);
|
||||
uwsgi_load_plugin(-1, equal + 1, NULL);
|
||||
}
|
||||
}
|
||||
p = strtok_r(NULL, "\n", &ctx);
|
||||
@@ -34,7 +34,7 @@ static int plugin_already_loaded(const char *plugin) {
|
||||
uwsgi_log("%s plugin already available\n", plugin);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->alias) {
|
||||
if (!strcmp(plugin, uwsgi.p[i]->alias)) {
|
||||
@@ -42,29 +42,29 @@ static int plugin_already_loaded(const char *plugin) {
|
||||
uwsgi_log("%s plugin already available\n", plugin);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.gp_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
|
||||
if (uwsgi.gp[i]->name) {
|
||||
if (!strcmp(plugin, uwsgi.gp[i]->name)) {
|
||||
if (!strcmp(plugin, uwsgi.gp[i]->name)) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s plugin already available\n", plugin);
|
||||
uwsgi_log("%s plugin already available\n", plugin);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (uwsgi.gp[i]->alias) {
|
||||
if (!strcmp(plugin, uwsgi.gp[i]->alias)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (uwsgi.gp[i]->alias) {
|
||||
if (!strcmp(plugin, uwsgi.gp[i]->alias)) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s plugin already available\n", plugin);
|
||||
uwsgi_log("%s plugin already available\n", plugin);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
modifier = atoi(plugin_name);
|
||||
plugin_name = colon+1;
|
||||
plugin_name = colon + 1;
|
||||
colon[0] = ':';
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!plugin_handle) {
|
||||
if (!has_option)
|
||||
uwsgi_log( "%s\n", dlerror());
|
||||
uwsgi_log("%s\n", dlerror());
|
||||
goto end;
|
||||
}
|
||||
plugin_symbol_name_start = uwsgi_get_last_char(plugin_name, '/');
|
||||
@@ -117,7 +117,7 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
|
||||
// step dir, check for user-supplied plugins directory
|
||||
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
|
||||
while(pdir) {
|
||||
while (pdir) {
|
||||
plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
|
||||
#ifdef UWSGI_ELF
|
||||
uwsgi_plugin_parse_section(plugin_filename);
|
||||
@@ -145,13 +145,13 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
}
|
||||
|
||||
success:
|
||||
if (!plugin_handle) {
|
||||
if (!plugin_handle) {
|
||||
if (!has_option)
|
||||
uwsgi_log( "!!! UNABLE to load uWSGI plugin: %s !!!\n", dlerror());
|
||||
}
|
||||
else {
|
||||
char *plugin_entry_symbol = uwsgi_concat2n(plugin_symbol_name_start, strlen(plugin_symbol_name_start)-3, "", 0);
|
||||
up = dlsym(plugin_handle, plugin_entry_symbol);
|
||||
uwsgi_log("!!! UNABLE to load uWSGI plugin: %s !!!\n", dlerror());
|
||||
}
|
||||
else {
|
||||
char *plugin_entry_symbol = uwsgi_concat2n(plugin_symbol_name_start, strlen(plugin_symbol_name_start) - 3, "", 0);
|
||||
up = dlsym(plugin_handle, plugin_entry_symbol);
|
||||
if (!up) {
|
||||
// is it a link ?
|
||||
memset(linkpath_buf, 0, 1024);
|
||||
@@ -159,7 +159,7 @@ success:
|
||||
if ((linkpath_size = readlink(plugin_abs_path, linkpath_buf, 1023)) > 0) {
|
||||
do {
|
||||
linkpath_buf[linkpath_size] = '\0';
|
||||
strncpy(linkpath, linkpath_buf, linkpath_size+1);
|
||||
strncpy(linkpath, linkpath_buf, linkpath_size + 1);
|
||||
} while ((linkpath_size = readlink(linkpath, linkpath_buf, 1023)) > 0);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s\n", linkpath);
|
||||
@@ -173,16 +173,16 @@ success:
|
||||
else {
|
||||
slash++;
|
||||
}
|
||||
plugin_entry_symbol = uwsgi_concat2n(slash, strlen(slash)-3, "",0);
|
||||
plugin_entry_symbol = uwsgi_concat2n(slash, strlen(slash) - 3, "", 0);
|
||||
up = dlsym(plugin_handle, plugin_entry_symbol);
|
||||
}
|
||||
}
|
||||
if (up) {
|
||||
if (up) {
|
||||
if (!up->name) {
|
||||
uwsgi_log("the loaded plugin (%s) has no .name attribute\n", plugin_name);
|
||||
if (dlclose(plugin_handle)) {
|
||||
uwsgi_error("dlclose()");
|
||||
}
|
||||
uwsgi_error("dlclose()");
|
||||
}
|
||||
if (need_free)
|
||||
free(plugin_name);
|
||||
if (plugin_filename)
|
||||
@@ -192,8 +192,8 @@ success:
|
||||
}
|
||||
if (plugin_already_loaded(up->name)) {
|
||||
if (dlclose(plugin_handle)) {
|
||||
uwsgi_error("dlclose()");
|
||||
}
|
||||
uwsgi_error("dlclose()");
|
||||
}
|
||||
if (need_free)
|
||||
free(plugin_name);
|
||||
if (plugin_filename)
|
||||
@@ -208,8 +208,8 @@ success:
|
||||
if (!strcmp(has_option, op->name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
op++;
|
||||
}
|
||||
op++;
|
||||
}
|
||||
if (!found) {
|
||||
if (dlclose(plugin_handle)) {
|
||||
@@ -222,14 +222,14 @@ success:
|
||||
free(plugin_entry_symbol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (modifier != -1) {
|
||||
fill_plugin_table(modifier, up);
|
||||
fill_plugin_table(modifier, up);
|
||||
up->modifier1 = modifier;
|
||||
}
|
||||
else {
|
||||
fill_plugin_table(up->modifier1, up);
|
||||
fill_plugin_table(up->modifier1, up);
|
||||
}
|
||||
if (need_free)
|
||||
free(plugin_name);
|
||||
@@ -240,10 +240,10 @@ success:
|
||||
if (up->on_load)
|
||||
up->on_load();
|
||||
return plugin_handle;
|
||||
}
|
||||
}
|
||||
if (!has_option)
|
||||
uwsgi_log( "%s\n", dlerror());
|
||||
}
|
||||
uwsgi_log("%s\n", dlerror());
|
||||
}
|
||||
|
||||
end:
|
||||
if (need_free)
|
||||
@@ -258,14 +258,14 @@ int uwsgi_try_autoload(char *option) {
|
||||
DIR *d;
|
||||
struct dirent *dp;
|
||||
// step dir, check for user-supplied plugins directory
|
||||
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
|
||||
while(pdir) {
|
||||
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
|
||||
while (pdir) {
|
||||
d = opendir(pdir->value);
|
||||
if (d) {
|
||||
while ((dp = readdir(d)) != NULL) {
|
||||
if (uwsgi_endswith(dp->d_name, "_plugin.so")) {
|
||||
char *filename = uwsgi_concat3(pdir->value, "/", dp->d_name);
|
||||
if (uwsgi_load_plugin(-1, filename, option)) {
|
||||
if (uwsgi_load_plugin(-1, filename, option)) {
|
||||
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
|
||||
free(filename);
|
||||
closedir(d);
|
||||
@@ -278,27 +278,28 @@ int uwsgi_try_autoload(char *option) {
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
pdir = pdir->next;
|
||||
}
|
||||
pdir = pdir->next;
|
||||
}
|
||||
|
||||
// last step: search in compile-time plugin_dir
|
||||
// last step: search in compile-time plugin_dir
|
||||
d = opendir(UWSGI_PLUGIN_DIR);
|
||||
if (!d) return 0;
|
||||
if (!d)
|
||||
return 0;
|
||||
|
||||
while((dp = readdir(d)) != NULL) {
|
||||
while ((dp = readdir(d)) != NULL) {
|
||||
if (uwsgi_endswith(dp->d_name, "_plugin.so")) {
|
||||
char *filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", dp->d_name);
|
||||
if (uwsgi_load_plugin(-1, filename, option)) {
|
||||
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
|
||||
free(filename);
|
||||
closedir(d);
|
||||
// add new options
|
||||
build_options();
|
||||
return 1;
|
||||
}
|
||||
char *filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", dp->d_name);
|
||||
if (uwsgi_load_plugin(-1, filename, option)) {
|
||||
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
|
||||
free(filename);
|
||||
closedir(d);
|
||||
// add new options
|
||||
build_options();
|
||||
return 1;
|
||||
}
|
||||
free(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
||||
|
||||
+683
-628
File diff suppressed because it is too large
Load Diff
+96
-89
@@ -4,132 +4,136 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
void uwsgi_init_queue() {
|
||||
if (!uwsgi.queue_blocksize)
|
||||
uwsgi.queue_blocksize = 8192;
|
||||
uwsgi.queue_blocksize = 8192;
|
||||
|
||||
if ((uwsgi.queue_blocksize * uwsgi.queue_size) % uwsgi.page_size != 0) {
|
||||
uwsgi_log("invalid queue size/blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) uwsgi.queue_blocksize, uwsgi.page_size);
|
||||
exit(1);
|
||||
}
|
||||
if ((uwsgi.queue_blocksize * uwsgi.queue_size) % uwsgi.page_size != 0) {
|
||||
uwsgi_log("invalid queue size/blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) uwsgi.queue_blocksize, uwsgi.page_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (uwsgi.queue_store) {
|
||||
uwsgi.queue_filesize = uwsgi.queue_blocksize * uwsgi.queue_size + 16;
|
||||
int queue_fd;
|
||||
struct stat qst;
|
||||
if (uwsgi.queue_store) {
|
||||
uwsgi.queue_filesize = uwsgi.queue_blocksize * uwsgi.queue_size + 16;
|
||||
int queue_fd;
|
||||
struct stat qst;
|
||||
|
||||
if (stat(uwsgi.queue_store, &qst)) {
|
||||
uwsgi_log("creating a new queue store file: %s\n", uwsgi.queue_store);
|
||||
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (queue_fd >= 0) {
|
||||
// fill the queue store
|
||||
if (ftruncate(queue_fd, uwsgi.queue_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((size_t) qst.st_size != uwsgi.queue_filesize || !S_ISREG(qst.st_mode)) {
|
||||
uwsgi_log("invalid queue store file. Please remove it or fix queue blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
uwsgi_log("recovered queue from backing store file: %s\n", uwsgi.queue_store);
|
||||
}
|
||||
if (stat(uwsgi.queue_store, &qst)) {
|
||||
uwsgi_log("creating a new queue store file: %s\n", uwsgi.queue_store);
|
||||
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (queue_fd >= 0) {
|
||||
// fill the queue store
|
||||
if (ftruncate(queue_fd, uwsgi.queue_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((size_t) qst.st_size != uwsgi.queue_filesize || !S_ISREG(qst.st_mode)) {
|
||||
uwsgi_log("invalid queue store file. Please remove it or fix queue blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
uwsgi_log("recovered queue from backing store file: %s\n", uwsgi.queue_store);
|
||||
}
|
||||
|
||||
if (queue_fd < 0) {
|
||||
uwsgi_error_open(uwsgi.queue_store);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.queue = mmap(NULL, uwsgi.queue_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, queue_fd, 0);
|
||||
if (queue_fd < 0) {
|
||||
uwsgi_error_open(uwsgi.queue_store);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.queue = mmap(NULL, uwsgi.queue_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, queue_fd, 0);
|
||||
|
||||
// fix header
|
||||
uwsgi.queue_header = uwsgi.queue;
|
||||
uwsgi.queue+=16;
|
||||
}
|
||||
else {
|
||||
uwsgi.queue = mmap(NULL, (uwsgi.queue_blocksize * uwsgi.queue_size)+16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
// fix header
|
||||
uwsgi.queue_header = uwsgi.queue;
|
||||
uwsgi.queue+=16;
|
||||
uwsgi.queue_header->pos = 0;
|
||||
uwsgi.queue_header->pull_pos = 0;
|
||||
}
|
||||
if (!uwsgi.queue) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
// fix header
|
||||
uwsgi.queue_header = uwsgi.queue;
|
||||
uwsgi.queue += 16;
|
||||
}
|
||||
else {
|
||||
uwsgi.queue = mmap(NULL, (uwsgi.queue_blocksize * uwsgi.queue_size) + 16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
// fix header
|
||||
uwsgi.queue_header = uwsgi.queue;
|
||||
uwsgi.queue += 16;
|
||||
uwsgi.queue_header->pos = 0;
|
||||
uwsgi.queue_header->pull_pos = 0;
|
||||
}
|
||||
if (!uwsgi.queue) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uwsgi.queue_lock = uwsgi_rwlock_init("queue");
|
||||
uwsgi.queue_lock = uwsgi_rwlock_init("queue");
|
||||
|
||||
uwsgi_log("*** Queue subsystem initialized: %dMB preallocated ***\n", (uwsgi.queue_blocksize * uwsgi.queue_size) / (1024 * 1024));
|
||||
uwsgi_log("*** Queue subsystem initialized: %dMB preallocated ***\n", (uwsgi.queue_blocksize * uwsgi.queue_size) / (1024 * 1024));
|
||||
}
|
||||
|
||||
char *uwsgi_queue_get(uint64_t index, uint64_t *size) {
|
||||
char *uwsgi_queue_get(uint64_t index, uint64_t * size) {
|
||||
|
||||
struct uwsgi_queue_item *uqi;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
|
||||
if (index >= uwsgi.queue_size) return NULL;
|
||||
if (index >= uwsgi.queue_size)
|
||||
return NULL;
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*index);
|
||||
ptr = ptr + (uwsgi.queue_blocksize * index);
|
||||
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
|
||||
*size = uqi->size;
|
||||
|
||||
return ptr + sizeof(struct uwsgi_queue_item);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_queue_pop(uint64_t *size) {
|
||||
char *uwsgi_queue_pop(uint64_t * size) {
|
||||
|
||||
struct uwsgi_queue_item *uqi;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
struct uwsgi_queue_item *uqi;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
|
||||
if (uwsgi.queue_header->pos == 0) {
|
||||
uwsgi.queue_header->pos = uwsgi.queue_size-1;
|
||||
uwsgi.queue_header->pos = uwsgi.queue_size - 1;
|
||||
}
|
||||
else {
|
||||
uwsgi.queue_header->pos--;
|
||||
}
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.queue_header->pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
ptr = ptr + (uwsgi.queue_blocksize * uwsgi.queue_header->pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
if (!uqi->size) return NULL;
|
||||
if (!uqi->size)
|
||||
return NULL;
|
||||
|
||||
*size = uqi->size;
|
||||
*size = uqi->size;
|
||||
// remove item
|
||||
uqi->size = 0;
|
||||
|
||||
return ptr + sizeof(struct uwsgi_queue_item);
|
||||
return ptr + sizeof(struct uwsgi_queue_item);
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_queue_pull(uint64_t *size) {
|
||||
char *uwsgi_queue_pull(uint64_t * size) {
|
||||
|
||||
struct uwsgi_queue_item *uqi;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.queue_header->pull_pos);
|
||||
ptr = ptr + (uwsgi.queue_blocksize * uwsgi.queue_header->pull_pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
if (!uqi->size) return NULL;
|
||||
if (!uqi->size)
|
||||
return NULL;
|
||||
|
||||
*size = uqi->size;
|
||||
|
||||
uwsgi.queue_header->pull_pos++;
|
||||
|
||||
if (uwsgi.queue_header->pull_pos >= uwsgi.queue_size) uwsgi.queue_header->pull_pos = 0;
|
||||
if (uwsgi.queue_header->pull_pos >= uwsgi.queue_size)
|
||||
uwsgi.queue_header->pull_pos = 0;
|
||||
|
||||
// remove item
|
||||
uqi->size = 0;
|
||||
|
||||
|
||||
return ptr + sizeof(struct uwsgi_queue_item);
|
||||
|
||||
}
|
||||
@@ -142,9 +146,10 @@ int uwsgi_queue_push(char *message, uint64_t size) {
|
||||
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
|
||||
return 0;
|
||||
|
||||
if (!size) return 0;
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.queue_header->pos);
|
||||
ptr = ptr + (uwsgi.queue_blocksize * uwsgi.queue_header->pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
ptr += sizeof(struct uwsgi_queue_item);
|
||||
@@ -154,33 +159,35 @@ int uwsgi_queue_push(char *message, uint64_t size) {
|
||||
memcpy(ptr, message, size);
|
||||
|
||||
uwsgi.queue_header->pos++;
|
||||
|
||||
if (uwsgi.queue_header->pos >= uwsgi.queue_size) uwsgi.queue_header->pos = 0;
|
||||
|
||||
if (uwsgi.queue_header->pos >= uwsgi.queue_size)
|
||||
uwsgi.queue_header->pos = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uwsgi_queue_set(uint64_t pos, char *message, uint64_t size) {
|
||||
|
||||
struct uwsgi_queue_item *uqi;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
struct uwsgi_queue_item *uqi;
|
||||
char *ptr = (char *) uwsgi.queue;
|
||||
|
||||
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
|
||||
return 0;
|
||||
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
|
||||
return 0;
|
||||
|
||||
if (!size) return 0;
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
if (pos >= uwsgi.queue_size) return 0;
|
||||
if (pos >= uwsgi.queue_size)
|
||||
return 0;
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
ptr = ptr + (uwsgi.queue_blocksize * pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
ptr += sizeof(struct uwsgi_queue_item);
|
||||
ptr += sizeof(struct uwsgi_queue_item);
|
||||
|
||||
uqi->size = size;
|
||||
uqi->ts = uwsgi_now();
|
||||
memcpy(ptr, message, size);
|
||||
uqi->size = size;
|
||||
uqi->ts = uwsgi_now();
|
||||
memcpy(ptr, message, size);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -23,9 +23,10 @@ struct uwsgi_rb_timer *uwsgi_min_rb_timer(struct rb_root *root) {
|
||||
|
||||
struct rb_node *node = root->rb_node;
|
||||
|
||||
if (node == NULL) return NULL;
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
while(node->rb_left != NULL) {
|
||||
while (node->rb_left != NULL) {
|
||||
node = node->rb_left;
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ struct uwsgi_rb_timer *uwsgi_add_rb_timer(struct rb_root *root, time_t key, void
|
||||
urbt->key = key;
|
||||
urbt->data = data;
|
||||
|
||||
while(*p) {
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
|
||||
current_rb_timer = (struct uwsgi_rb_timer *) parent;
|
||||
|
||||
+36
-22
@@ -1,46 +1,60 @@
|
||||
#ifdef UWSGI_PCRE
|
||||
#include "uwsgi.h"
|
||||
|
||||
int uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) {
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void uwsgi_opt_pcre_jit(char *opt, char *value, void *foobar) {
|
||||
#if defined(PCRE_STUDY_JIT_COMPILE) && defined(PCRE_CONFIG_JIT)
|
||||
int has_jit = 0, ret;
|
||||
ret = pcre_config(PCRE_CONFIG_JIT, &has_jit);
|
||||
if (ret != 0 || has_jit != 1)
|
||||
return;
|
||||
uwsgi.pcre_jit = PCRE_STUDY_JIT_COMPILE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int uwsgi_regexp_build(char *re, pcre ** pattern, pcre_extra ** pattern_extra) {
|
||||
|
||||
const char *errstr;
|
||||
int erroff;
|
||||
|
||||
*pattern = pcre_compile( (const char *)re, 0, &errstr, &erroff, NULL);
|
||||
if (!*pattern) {
|
||||
*pattern = pcre_compile((const char *) re, 0, &errstr, &erroff, NULL);
|
||||
if (!*pattern) {
|
||||
uwsgi_log("pcre error: %s at offset %d\n", errstr, erroff);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pattern_extra = (pcre_extra *) pcre_study((const pcre*)*pattern, 0, &errstr);
|
||||
if (*pattern_extra == NULL && errstr != NULL) {
|
||||
int opt = uwsgi.pcre_jit;
|
||||
|
||||
*pattern_extra = (pcre_extra *) pcre_study((const pcre *) *pattern, opt, &errstr);
|
||||
if (*pattern_extra == NULL && errstr != NULL) {
|
||||
pcre_free(*pattern);
|
||||
uwsgi_log("pcre (study) error: %s\n", errstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length) {
|
||||
int uwsgi_regexp_match(pcre * pattern, pcre_extra * pattern_extra, char *subject, int length) {
|
||||
|
||||
return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, NULL, 0 );
|
||||
return pcre_exec((const pcre *) pattern, (const pcre_extra *) pattern_extra, subject, length, 0, 0, NULL, 0);
|
||||
}
|
||||
|
||||
int uwsgi_regexp_match_ovec(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length, int *ovec, int n ) {
|
||||
int uwsgi_regexp_match_ovec(pcre * pattern, pcre_extra * pattern_extra, char *subject, int length, int *ovec, int n) {
|
||||
|
||||
if (n > 0) {
|
||||
return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, ovec, (n+1)*3 );
|
||||
return pcre_exec((const pcre *) pattern, (const pcre_extra *) pattern_extra, subject, length, 0, 0, ovec, (n + 1) * 3);
|
||||
}
|
||||
return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, NULL, 0 );
|
||||
return pcre_exec((const pcre *) pattern, (const pcre_extra *) pattern_extra, subject, length, 0, 0, NULL, 0);
|
||||
}
|
||||
|
||||
int uwsgi_regexp_ovector(pcre *pattern, pcre_extra *pattern_extra) {
|
||||
int uwsgi_regexp_ovector(pcre * pattern, pcre_extra * pattern_extra) {
|
||||
|
||||
int n;
|
||||
|
||||
if (pcre_fullinfo((const pcre*)pattern, (const pcre_extra *)pattern_extra, PCRE_INFO_CAPTURECOUNT, &n))
|
||||
if (pcre_fullinfo((const pcre *) pattern, (const pcre_extra *) pattern_extra, PCRE_INFO_CAPTURECOUNT, &n))
|
||||
return 0;
|
||||
|
||||
return n;
|
||||
@@ -51,35 +65,35 @@ char *uwsgi_regexp_apply_ovec(char *src, int src_n, char *dst, int dst_n, int *o
|
||||
int i;
|
||||
int dollar = 0;
|
||||
|
||||
char *res = uwsgi_malloc( dst_n + (src_n * n) + 1);
|
||||
char *res = uwsgi_malloc(dst_n + (src_n * n) + 1);
|
||||
char *ptr = res;
|
||||
|
||||
for(i=0;i<dst_n;i++) {
|
||||
for (i = 0; i < dst_n; i++) {
|
||||
if (dollar) {
|
||||
if (isdigit((int)dst[i])) {
|
||||
if (isdigit((int) dst[i])) {
|
||||
int pos = (dst[i] - 48);
|
||||
if (pos <= n) {
|
||||
pos = pos * 2;
|
||||
memcpy(ptr, src + ovector[pos], ovector[pos+1]-ovector[pos]);
|
||||
ptr+=ovector[pos+1]-ovector[pos];
|
||||
memcpy(ptr, src + ovector[pos], ovector[pos + 1] - ovector[pos]);
|
||||
ptr += ovector[pos + 1] - ovector[pos];
|
||||
}
|
||||
}
|
||||
else {
|
||||
*ptr++= dst[i];
|
||||
*ptr++ = dst[i];
|
||||
}
|
||||
dollar = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dst[i] == '$') {
|
||||
dollar = 1;
|
||||
}
|
||||
else {
|
||||
*ptr++= dst[i];
|
||||
*ptr++ = dst[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++= 0;
|
||||
*ptr++ = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
+30
-26
@@ -7,21 +7,23 @@ int uwsgi_apply_routes(struct wsgi_request *wsgi_req) {
|
||||
|
||||
struct uwsgi_route *routes = uwsgi.routes;
|
||||
|
||||
if (!routes) return UWSGI_ROUTE_CONTINUE;
|
||||
if (!routes)
|
||||
return UWSGI_ROUTE_CONTINUE;
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
while(routes) {
|
||||
char **subject = (char **) (((char *)(wsgi_req))+routes->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+routes->subject_len);
|
||||
while (routes) {
|
||||
char **subject = (char **) (((char *) (wsgi_req)) + routes->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *) (wsgi_req)) + routes->subject_len);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("route subject = %.*s\n", *subject_len, *subject);
|
||||
#endif
|
||||
int n = uwsgi_regexp_match_ovec(routes->pattern, routes->pattern_extra, *subject, *subject_len, routes->ovector, routes->ovn);
|
||||
if (n>= 0) {
|
||||
if (n >= 0) {
|
||||
int ret = routes->func(wsgi_req, routes);
|
||||
if (ret == UWSGI_ROUTE_BREAK) uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].routed_requests++;
|
||||
if (ret != UWSGI_ROUTE_NEXT) {
|
||||
return ret;
|
||||
}
|
||||
@@ -34,23 +36,25 @@ int uwsgi_apply_routes(struct wsgi_request *wsgi_req) {
|
||||
|
||||
int uwsgi_apply_routes_fast(struct wsgi_request *wsgi_req, char *uri, int len) {
|
||||
|
||||
struct uwsgi_route *routes = uwsgi.routes;
|
||||
struct uwsgi_route *routes = uwsgi.routes;
|
||||
|
||||
if (!routes) return UWSGI_ROUTE_CONTINUE;
|
||||
if (!routes)
|
||||
return UWSGI_ROUTE_CONTINUE;
|
||||
|
||||
while(routes) {
|
||||
int n = uwsgi_regexp_match_ovec(routes->pattern, routes->pattern_extra, uri, len, routes->ovector, routes->ovn);
|
||||
if (n>= 0) {
|
||||
while (routes) {
|
||||
int n = uwsgi_regexp_match_ovec(routes->pattern, routes->pattern_extra, uri, len, routes->ovector, routes->ovn);
|
||||
if (n >= 0) {
|
||||
int ret = routes->func(wsgi_req, routes);
|
||||
if (ret == UWSGI_ROUTE_BREAK) uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].routed_requests++;
|
||||
if (ret != UWSGI_ROUTE_NEXT) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
routes = routes->next;
|
||||
}
|
||||
routes = routes->next;
|
||||
}
|
||||
|
||||
return UWSGI_ROUTE_CONTINUE;
|
||||
return UWSGI_ROUTE_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,9 +76,9 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
ur = uwsgi.routes;
|
||||
}
|
||||
else {
|
||||
while(ur) {
|
||||
while (ur) {
|
||||
if (!ur->next) {
|
||||
ur->next = uwsgi_calloc(sizeof(struct uwsgi_route));
|
||||
ur->next = uwsgi_calloc(sizeof(struct uwsgi_route));
|
||||
ur = ur->next;
|
||||
break;
|
||||
}
|
||||
@@ -105,10 +109,10 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
|
||||
ur->ovn = uwsgi_regexp_ovector(ur->pattern, ur->pattern_extra);
|
||||
if (ur->ovn > 0) {
|
||||
ur->ovector = uwsgi_calloc(sizeof(int) * (3 * (ur->ovn + 1)) );
|
||||
ur->ovector = uwsgi_calloc(sizeof(int) * (3 * (ur->ovn + 1)));
|
||||
}
|
||||
|
||||
char *command = space+1;
|
||||
char *command = space + 1;
|
||||
|
||||
char *colon = strchr(command, ':');
|
||||
if (!colon) {
|
||||
@@ -119,17 +123,17 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
*colon = 0;
|
||||
|
||||
struct uwsgi_router *r = uwsgi.routers;
|
||||
while(r) {
|
||||
while (r) {
|
||||
if (!strcmp(r->name, command)) {
|
||||
if (r->func(ur, colon+1) == 0) {
|
||||
if (r->func(ur, colon + 1) == 0) {
|
||||
// apply is_last
|
||||
struct uwsgi_route *last_ur = ur;
|
||||
ur = uwsgi.routes;
|
||||
while(ur) {
|
||||
while (ur) {
|
||||
if (ur->func == last_ur->func) {
|
||||
ur->is_last = 0;
|
||||
}
|
||||
ur = ur->next;
|
||||
ur = ur->next;
|
||||
}
|
||||
last_ur->is_last = 1;
|
||||
return;
|
||||
@@ -142,7 +146,7 @@ void uwsgi_opt_add_route(char *opt, char *value, void *foobar) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct uwsgi_router *uwsgi_register_router(char *name, int (*func)(struct uwsgi_route *, char *)) {
|
||||
struct uwsgi_router *uwsgi_register_router(char *name, int (*func) (struct uwsgi_route *, char *)) {
|
||||
|
||||
struct uwsgi_router *ur = uwsgi.routers;
|
||||
if (!ur) {
|
||||
@@ -152,7 +156,7 @@ struct uwsgi_router *uwsgi_register_router(char *name, int (*func)(struct uwsgi_
|
||||
return uwsgi.routers;
|
||||
}
|
||||
|
||||
while(ur) {
|
||||
while (ur) {
|
||||
if (!ur->next) {
|
||||
ur->next = uwsgi_calloc(sizeof(struct uwsgi_router));
|
||||
ur->next->name = name;
|
||||
|
||||
+41
-40
@@ -16,7 +16,7 @@ int uwsgi_register_rpc(char *name, uint8_t modifier1, uint8_t args, void *func)
|
||||
|
||||
if (uwsgi.shared->rpc_count < MAX_RPC) {
|
||||
urpc = &uwsgi.shared->rpc_table[uwsgi.shared->rpc_count];
|
||||
|
||||
|
||||
memcpy(urpc->name, name, strlen(name));
|
||||
urpc->modifier1 = modifier1;
|
||||
urpc->args = args;
|
||||
@@ -39,7 +39,7 @@ uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], cha
|
||||
int i;
|
||||
uint16_t ret = 0;
|
||||
|
||||
for(i=0;i<uwsgi.shared->rpc_count;i++) {
|
||||
for (i = 0; i < uwsgi.shared->rpc_count; i++) {
|
||||
if (uwsgi.shared->rpc_table[i].name[0] != 0) {
|
||||
if (!strcmp(uwsgi.shared->rpc_table[i].name, name)) {
|
||||
urpc = &uwsgi.shared->rpc_table[i];
|
||||
@@ -58,71 +58,72 @@ uint16_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], cha
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t argvs[], uint16_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;
|
||||
struct uwsgi_header uh;
|
||||
char *buffer = NULL;
|
||||
|
||||
|
||||
*len = 0;
|
||||
|
||||
if (node == NULL || !strcmp(node, "")) {
|
||||
if (node == NULL || !strcmp(node, "")) {
|
||||
// allocate the whole buffer
|
||||
buffer = uwsgi_malloc(65536);
|
||||
*len = uwsgi_rpc(func, argc, argv, argvs, buffer);
|
||||
*len = uwsgi_rpc(func, argc, argv, argvs, buffer);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// connect to node
|
||||
int fd = uwsgi_connect(node, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
int fd = uwsgi_connect(node, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
|
||||
if (fd < 0) return NULL;
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
// prepare a uwsgi array
|
||||
// prepare a uwsgi array
|
||||
uint16_t buffer_size = 2 + strlen(func);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
buffer_size += 2 + argvs[i];
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
buffer_size += 2 + argvs[i];
|
||||
}
|
||||
|
||||
// allocate the whole buffer
|
||||
buffer = uwsgi_malloc(65536);
|
||||
|
||||
uh.modifier1 = 173;
|
||||
uh.pktsize = buffer_size;
|
||||
uh.modifier2 = 0;
|
||||
uh.modifier1 = 173;
|
||||
uh.pktsize = buffer_size;
|
||||
uh.modifier2 = 0;
|
||||
|
||||
// add func to the array
|
||||
char *bufptr = buffer;
|
||||
ulen = strlen(func);
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, func, ulen);
|
||||
bufptr += ulen;
|
||||
char *bufptr = buffer;
|
||||
ulen = strlen(func);
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, func, ulen);
|
||||
bufptr += ulen;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
ulen = argvs[i];
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, argv[i], ulen);
|
||||
bufptr += ulen;
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
ulen = argvs[i];
|
||||
*bufptr++ = (uint8_t) (ulen & 0xff);
|
||||
*bufptr++ = (uint8_t) ((ulen >> 8) & 0xff);
|
||||
memcpy(bufptr, argv[i], ulen);
|
||||
bufptr += ulen;
|
||||
}
|
||||
|
||||
if (write(fd, &uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
if (write(fd, &uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (write(fd, buffer, buffer_size) != buffer_size) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
if (write(fd, buffer, buffer_size) != buffer_size) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi_read_response(fd, &uh, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], &buffer) < 0) {
|
||||
close(fd);
|
||||
@@ -131,7 +132,7 @@ char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
|
||||
*len = uh.pktsize;
|
||||
if (*len == 0) {
|
||||
free(buffer);
|
||||
|
||||
+8
-201
@@ -2,201 +2,7 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
/*
|
||||
|
||||
enqueue a file transfer to the offload thread
|
||||
|
||||
*/
|
||||
|
||||
int uwsgi_offload_request_do(struct wsgi_request *wsgi_req, char *filename, size_t len) {
|
||||
|
||||
struct stat st;
|
||||
|
||||
// avoid closing the connection
|
||||
wsgi_req->fd_closed = 1;
|
||||
|
||||
// fill offload request
|
||||
struct uwsgi_offload_request uor;
|
||||
uor.fd = open(filename, O_RDONLY | O_NONBLOCK);
|
||||
if (uor.fd < 0) {
|
||||
uwsgi_error_open(filename);
|
||||
goto error;
|
||||
}
|
||||
uor.s = wsgi_req->poll.fd;
|
||||
// make a fstat to get the file size
|
||||
if (!len) {
|
||||
if (fstat(uor.fd, &st)) {
|
||||
uwsgi_error("fstat()");
|
||||
goto error2;
|
||||
}
|
||||
len = st.st_size;
|
||||
}
|
||||
uor.pos = 0;
|
||||
uor.len = len;
|
||||
uor.written = 0;
|
||||
uor.buf = NULL;
|
||||
uor.prev = NULL;
|
||||
uor.next = NULL;
|
||||
|
||||
// put socket in non-blocking mode
|
||||
uwsgi_socket_nb(uor.s);
|
||||
|
||||
if (write(uwsgi.offload_thread->pipe[0], &uor, sizeof(struct uwsgi_offload_request)) != sizeof(struct uwsgi_offload_request)) {
|
||||
goto error2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error2:
|
||||
close(uor.fd);
|
||||
error:
|
||||
wsgi_req->fd_closed = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void uwsgi_offload_close(struct uwsgi_offload_request *uor) {
|
||||
// close the socket and the file descriptor
|
||||
close(uor->s);
|
||||
close(uor->fd);
|
||||
// remove the structure from the linked list;
|
||||
struct uwsgi_offload_request *prev = uor->prev;
|
||||
struct uwsgi_offload_request *next = uor->next;
|
||||
|
||||
if (uor == uwsgi.offload_requests_head) {
|
||||
uwsgi.offload_requests_head = next;
|
||||
}
|
||||
|
||||
if (uor == uwsgi.offload_requests_tail) {
|
||||
uwsgi.offload_requests_tail = prev;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
if (uor->buf) {
|
||||
free(uor->buf);
|
||||
}
|
||||
|
||||
free(uor);
|
||||
}
|
||||
|
||||
static void uwsgi_offload_append(struct uwsgi_offload_request *uor) {
|
||||
|
||||
if (!uwsgi.offload_requests_head) {
|
||||
uwsgi.offload_requests_head = uor;
|
||||
}
|
||||
|
||||
if (uwsgi.offload_requests_tail) {
|
||||
uwsgi.offload_requests_tail->next = uor;
|
||||
uor->prev = uwsgi.offload_requests_tail;
|
||||
}
|
||||
|
||||
uwsgi.offload_requests_tail = uor;
|
||||
}
|
||||
|
||||
static struct uwsgi_offload_request *uwsgi_offload_get_by_socket(int s) {
|
||||
struct uwsgi_offload_request *uor = uwsgi.offload_requests_head;
|
||||
while(uor) {
|
||||
if (uor->s == s) {
|
||||
return uor;
|
||||
}
|
||||
uor = uor->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void uwsgi_offload_loop(struct uwsgi_thread *ut) {
|
||||
|
||||
int i;
|
||||
void *events = event_queue_alloc(uwsgi.static_offload_to_thread);
|
||||
|
||||
for(;;) {
|
||||
int nevents = event_queue_wait_multi(ut->queue, -1, events, uwsgi.static_offload_to_thread);
|
||||
for (i=0;i<nevents;i++) {
|
||||
int interesting_fd = event_queue_interesting_fd(events, i);
|
||||
if (interesting_fd == uwsgi.offload_thread->pipe[1]) {
|
||||
struct uwsgi_offload_request *uor = uwsgi_malloc(sizeof(struct uwsgi_offload_request));
|
||||
ssize_t len = read(uwsgi.offload_thread->pipe[1], uor, sizeof(struct uwsgi_offload_request));
|
||||
if (len != sizeof(struct uwsgi_offload_request)) {
|
||||
uwsgi_error("read()");
|
||||
free(uor);
|
||||
continue;
|
||||
}
|
||||
// start monitoring socket for write
|
||||
if (event_queue_add_fd_write(ut->queue, uor->s)) {
|
||||
free(uor);
|
||||
continue;
|
||||
}
|
||||
uwsgi_offload_append(uor);
|
||||
continue;
|
||||
}
|
||||
// ok check for socket writability
|
||||
struct uwsgi_offload_request *uor = uwsgi_offload_get_by_socket(interesting_fd);
|
||||
if (!uor) continue;
|
||||
// sendfile() in chunks (128k is a good size...)
|
||||
#if defined(__linux__)
|
||||
ssize_t len = sendfile(uor->s, uor->fd, &uor->pos, 128*1024);
|
||||
if (len > 0) {
|
||||
uor->written += len;
|
||||
if (uor->written >= uor->len) {
|
||||
uwsgi_offload_close(uor);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (len < 0) {
|
||||
if (errno == EAGAIN) continue;
|
||||
uwsgi_error("sendfile()");
|
||||
}
|
||||
#else
|
||||
if (!uor->buf) {
|
||||
uor->buf = uwsgi_malloc(32768);
|
||||
uor->to_write = 0;
|
||||
}
|
||||
if (uor->to_write == 0) {
|
||||
ssize_t len = read(uor->fd, uor->buf, 32768);
|
||||
if (len > 0) {
|
||||
uor->to_write = len;
|
||||
uor->buf_pos = 0;
|
||||
continue;
|
||||
}
|
||||
else if (len < 0) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
uwsgi_offload_close(uor);
|
||||
continue;
|
||||
}
|
||||
ssize_t len = write(uor->s, uor->buf + uor->buf_pos, uor->to_write);
|
||||
if (len > 0) {
|
||||
uor->written += len;
|
||||
uor->to_write -= len;
|
||||
uor->buf_pos += len;
|
||||
if (uor->written >= uor->len) {
|
||||
uwsgi_offload_close(uor);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (len < 0) {
|
||||
if (errno == EAGAIN) continue;
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
|
||||
#endif
|
||||
uwsgi_offload_close(uor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_thread *uwsgi_offload_thread_start() {
|
||||
return uwsgi_thread_new(uwsgi_offload_loop);
|
||||
}
|
||||
|
||||
ssize_t uwsgi_sendfile(struct wsgi_request *wsgi_req) {
|
||||
ssize_t uwsgi_sendfile(struct wsgi_request * wsgi_req) {
|
||||
|
||||
int fd = wsgi_req->sendfile_fd;
|
||||
int sockfd = wsgi_req->poll.fd;
|
||||
@@ -216,10 +22,11 @@ ssize_t uwsgi_sendfile(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (wsgi_req->sendfile_fd_size) {
|
||||
|
||||
if (!wsgi_req->sendfile_fd_chunk) wsgi_req->sendfile_fd_chunk = 4096;
|
||||
if (!wsgi_req->sendfile_fd_chunk)
|
||||
wsgi_req->sendfile_fd_chunk = 4096;
|
||||
|
||||
if (wsgi_req->socket->proto_sendfile) {
|
||||
sst = wsgi_req->socket->proto_sendfile(wsgi_req);
|
||||
sst = wsgi_req->socket->proto_sendfile(wsgi_req);
|
||||
}
|
||||
else {
|
||||
sst = uwsgi_do_sendfile(sockfd, wsgi_req->sendfile_fd, wsgi_req->sendfile_fd_size, wsgi_req->sendfile_fd_chunk, &wsgi_req->sendfile_fd_pos, uwsgi.async);
|
||||
@@ -231,7 +38,7 @@ end:
|
||||
return sst;
|
||||
}
|
||||
|
||||
ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk, off_t *pos, int async) {
|
||||
ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk, off_t * pos, int async) {
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
|
||||
@@ -292,8 +99,8 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
|
||||
return sf_ret;
|
||||
}
|
||||
|
||||
while(written < filesize) {
|
||||
sf_ret = sendfile(sockfd, filefd, pos, filesize-written);
|
||||
while (written < filesize) {
|
||||
sf_ret = sendfile(sockfd, filefd, pos, filesize - written);
|
||||
if (sf_ret < 0) {
|
||||
uwsgi_error("sendfile()");
|
||||
return 0;
|
||||
@@ -301,7 +108,7 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
|
||||
else if (sf_ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
written+= sf_ret;
|
||||
written += sf_ret;
|
||||
}
|
||||
return written;
|
||||
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@ int uwsgi_signal_handler(uint8_t sig) {
|
||||
|
||||
use = &uwsgi.shared->signal_table[sig];
|
||||
|
||||
if (!use->handler) return -1;
|
||||
if (!use->handler)
|
||||
return -1;
|
||||
|
||||
if (!uwsgi.p[use->modifier1]->signal_handler) {
|
||||
return -1;
|
||||
|
||||
+88
-88
@@ -249,7 +249,7 @@ static uint64_t get_uwsgi_snmp_value(uint64_t val, uint8_t * oid_t) {
|
||||
static uint64_t get_uwsgi_custom_snmp_value(uint64_t val, uint8_t * oid_t) {
|
||||
|
||||
val--;
|
||||
uwsgi_wlock(uwsgi.snmp_lock);
|
||||
uwsgi_wlock(uwsgi.snmp_lock);
|
||||
if (uwsgi.shared->snmp_value[val].type) {
|
||||
*oid_t = uwsgi.shared->snmp_value[val].type;
|
||||
uwsgi_rwunlock(uwsgi.snmp_lock);
|
||||
@@ -281,130 +281,130 @@ static int get_snmp_integer(uint8_t * ptr, uint64_t * val) {
|
||||
#ifdef __BIG_ENDIAN__
|
||||
for (i = 0; i < tlen; i++) {
|
||||
#else
|
||||
for (i = tlen - 1; i >= 0; i--) {
|
||||
for (i = tlen - 1; i >= 0; i--) {
|
||||
#endif
|
||||
cval[j] = ptr[1 + i];
|
||||
j++;
|
||||
}
|
||||
|
||||
return tlen + 1;
|
||||
cval[j] = ptr[1 + i];
|
||||
j++;
|
||||
}
|
||||
|
||||
static uint8_t snmp_int_to_snmp(uint64_t snmp_val, uint8_t oid_type, uint8_t * buffer) {
|
||||
uint8_t tlen;
|
||||
int i, j;
|
||||
uint8_t *ptr = (uint8_t *) &snmp_val;
|
||||
return tlen + 1;
|
||||
}
|
||||
|
||||
// check for counter, counter64 or gauge
|
||||
static uint8_t snmp_int_to_snmp(uint64_t snmp_val, uint8_t oid_type, uint8_t * buffer) {
|
||||
uint8_t tlen;
|
||||
int i, j;
|
||||
uint8_t *ptr = (uint8_t *) & snmp_val;
|
||||
|
||||
if (oid_type == SNMP_COUNTER64) {
|
||||
tlen = 8;
|
||||
}
|
||||
else if (oid_type == SNMP_NULL || oid_type == 0) {
|
||||
tlen = 0;
|
||||
}
|
||||
else {
|
||||
tlen = 4;
|
||||
}
|
||||
// check for counter, counter64 or gauge
|
||||
|
||||
buffer[0] = tlen;
|
||||
if (oid_type == SNMP_COUNTER64) {
|
||||
tlen = 8;
|
||||
}
|
||||
else if (oid_type == SNMP_NULL || oid_type == 0) {
|
||||
tlen = 0;
|
||||
}
|
||||
else {
|
||||
tlen = 4;
|
||||
}
|
||||
|
||||
j = 1;
|
||||
buffer[0] = tlen;
|
||||
|
||||
j = 1;
|
||||
#ifdef __BIG_ENDIAN__
|
||||
for (i = 0; i < tlen; i++) {
|
||||
for (i = 0; i < tlen; i++) {
|
||||
#else
|
||||
for (i = tlen - 1; i >= 0; i--) {
|
||||
for (i = tlen - 1; i >= 0; i--) {
|
||||
#endif
|
||||
buffer[j] = ptr[i];
|
||||
j++;
|
||||
}
|
||||
buffer[j] = ptr[i];
|
||||
j++;
|
||||
}
|
||||
|
||||
return tlen + 1;
|
||||
}
|
||||
return tlen + 1;
|
||||
}
|
||||
|
||||
static ssize_t build_snmp_response(uint8_t oid1, uint8_t oid2, uint8_t * buffer, int size, uint8_t * seq1, uint8_t * seq2, uint8_t * seq3) {
|
||||
uint64_t snmp_val;
|
||||
uint8_t oid_sz;
|
||||
uint8_t oid_type;
|
||||
static ssize_t build_snmp_response(uint8_t oid1, uint8_t oid2, uint8_t * buffer, int size, uint8_t * seq1, uint8_t * seq2, uint8_t * seq3) {
|
||||
uint64_t snmp_val;
|
||||
uint8_t oid_sz;
|
||||
uint8_t oid_type;
|
||||
|
||||
if (oid1 == 1) {
|
||||
snmp_val = get_uwsgi_snmp_value(oid2, &oid_type);
|
||||
}
|
||||
else if (oid1 == 2) {
|
||||
snmp_val = get_uwsgi_custom_snmp_value(oid2, &oid_type);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
if (oid1 == 1) {
|
||||
snmp_val = get_uwsgi_snmp_value(oid2, &oid_type);
|
||||
}
|
||||
else if (oid1 == 2) {
|
||||
snmp_val = get_uwsgi_custom_snmp_value(oid2, &oid_type);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer[size - 2] = oid_type;
|
||||
oid_sz = snmp_int_to_snmp(snmp_val, oid_type, buffer + (size - 1));
|
||||
buffer[size - 2] = oid_type;
|
||||
oid_sz = snmp_int_to_snmp(snmp_val, oid_type, buffer + (size - 1));
|
||||
|
||||
if (oid_sz < 1)
|
||||
return -1;
|
||||
if (oid_sz < 1)
|
||||
return -1;
|
||||
|
||||
oid_sz--;
|
||||
oid_sz--;
|
||||
|
||||
buffer[1] += oid_sz;
|
||||
*seq1 += oid_sz;
|
||||
*seq2 += oid_sz;
|
||||
*seq3 += oid_sz;
|
||||
buffer[1] += oid_sz;
|
||||
*seq1 += oid_sz;
|
||||
*seq2 += oid_sz;
|
||||
*seq3 += oid_sz;
|
||||
|
||||
return size + oid_sz;
|
||||
return size + oid_sz;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_opt_snmp(char *opt, char *value, void *foobar) {
|
||||
uwsgi.snmp = 1;
|
||||
if (value) {
|
||||
uwsgi.snmp_addr = value;
|
||||
uwsgi.master_process = 1;
|
||||
}
|
||||
if (value) {
|
||||
uwsgi.snmp_addr = value;
|
||||
uwsgi.master_process = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_opt_snmp_community(char *opt, char *value, void *foobar) {
|
||||
uwsgi.snmp = 1;
|
||||
uwsgi.snmp_community = value;
|
||||
uwsgi.snmp_community = value;
|
||||
}
|
||||
|
||||
int uwsgi_setup_snmp(void) {
|
||||
int snmp_fd = -1;
|
||||
int i;
|
||||
if (uwsgi.snmp) {
|
||||
if (uwsgi.snmp_community) {
|
||||
if (strlen(uwsgi.snmp_community) > 72) {
|
||||
uwsgi_log("*** warning the supplied SNMP community string will be truncated to 72 chars ***\n");
|
||||
memcpy(uwsgi.shared->snmp_community, uwsgi.snmp_community, 72);
|
||||
}
|
||||
else {
|
||||
memcpy(uwsgi.shared->snmp_community, uwsgi.snmp_community, strlen(uwsgi.snmp_community) + 1);
|
||||
}
|
||||
}
|
||||
if (uwsgi.snmp_community) {
|
||||
if (strlen(uwsgi.snmp_community) > 72) {
|
||||
uwsgi_log("*** warning the supplied SNMP community string will be truncated to 72 chars ***\n");
|
||||
memcpy(uwsgi.shared->snmp_community, uwsgi.snmp_community, 72);
|
||||
}
|
||||
else {
|
||||
memcpy(uwsgi.shared->snmp_community, uwsgi.snmp_community, strlen(uwsgi.snmp_community) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.shared->snmp_gvalue[0].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[0].val = &uwsgi.workers[0].requests;
|
||||
uwsgi.shared->snmp_gvalue[0].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[0].val = &uwsgi.workers[0].requests;
|
||||
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
uwsgi.shared->snmp_gvalue[30 + i].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[30 + i].val = &uwsgi.workers[i + 1].requests;
|
||||
}
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
uwsgi.shared->snmp_gvalue[30 + i].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[30 + i].val = &uwsgi.workers[i + 1].requests;
|
||||
}
|
||||
|
||||
if (uwsgi.snmp_addr) {
|
||||
snmp_fd = bind_to_udp(uwsgi.snmp_addr, 0, 0);
|
||||
if (snmp_fd < 0) {
|
||||
uwsgi_log("unable to bind to udp socket. SNMP service will be disabled.\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("SNMP server enabled on %s\n", uwsgi.snmp_addr);
|
||||
event_queue_add_fd_read(uwsgi.master_queue, snmp_fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("SNMP agent enabled.\n");
|
||||
}
|
||||
if (uwsgi.snmp_addr) {
|
||||
snmp_fd = bind_to_udp(uwsgi.snmp_addr, 0, 0);
|
||||
if (snmp_fd < 0) {
|
||||
uwsgi_log("unable to bind to udp socket. SNMP service will be disabled.\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("SNMP server enabled on %s\n", uwsgi.snmp_addr);
|
||||
event_queue_add_fd_read(uwsgi.master_queue, snmp_fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("SNMP agent enabled.\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return snmp_fd;
|
||||
}
|
||||
|
||||
+299
-288
@@ -233,8 +233,8 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) {
|
||||
}
|
||||
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
if (multicast) {
|
||||
@@ -271,8 +271,8 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) {
|
||||
}
|
||||
|
||||
if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_TTL, &uwsgi.multicast_ttl, sizeof(uwsgi.multicast_ttl))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -335,7 +335,7 @@ int connect_to_unix(char *socket_name, int timeout, int async) {
|
||||
}
|
||||
|
||||
#if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
|
||||
uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK, 0);
|
||||
uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
#else
|
||||
uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
#endif
|
||||
@@ -377,7 +377,7 @@ int connect_to_tcp(char *socket_name, int port, int timeout, int async) {
|
||||
socket_name[strlen(socket_name)] = ':';
|
||||
|
||||
#if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
|
||||
uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
|
||||
uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
#else
|
||||
uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
#endif
|
||||
@@ -564,14 +564,15 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef IP_FREEBIND
|
||||
#ifndef IP_FREEBIND
|
||||
#define IP_FREEBIND 15
|
||||
#endif
|
||||
if (uwsgi.freebind) {
|
||||
if (setsockopt(serverfd, SOL_IP, IP_FREEBIND, (const void *) &uwsgi.freebind, sizeof(int)) < 0) {
|
||||
uwsgi_error("IP_FREEBIND setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (uwsgi.reuse_port) {
|
||||
@@ -590,9 +591,9 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
tv.tv_sec = uwsgi.so_send_timeout;
|
||||
tv.tv_usec = 0;
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_SNDTIMEO, (const void *) &tv, sizeof(struct timeval)) < 0) {
|
||||
uwsgi_error("SO_SNDTIMEO setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
uwsgi_error("SO_SNDTIMEO setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
}
|
||||
|
||||
if (!uwsgi.no_defer_accept) {
|
||||
@@ -629,8 +630,8 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
long somaxconn = uwsgi_num_from_file("/proc/sys/net/core/somaxconn");
|
||||
if (somaxconn > 0 && uwsgi.listen_queue > somaxconn) {
|
||||
long somaxconn = uwsgi_num_from_file("/proc/sys/net/core/somaxconn");
|
||||
if (somaxconn > 0 && uwsgi.listen_queue > somaxconn) {
|
||||
uwsgi_log("Listen queue size is greater than the system max net.core.somaxconn (%i).\n", somaxconn);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
@@ -717,7 +718,7 @@ int timed_connect(struct pollfd *fdpoll, const struct sockaddr *addr, int addr_s
|
||||
|
||||
|
||||
#if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
|
||||
// hmm, nothing to do, as we are already non-blocking
|
||||
uwsgi_socket_b(fdpoll->fd);
|
||||
#else
|
||||
/* re-set blocking socket */
|
||||
arg &= (~O_NONBLOCK);
|
||||
@@ -1480,346 +1481,356 @@ socklen_t socket_to_in_addr6(char *socket_name, char *port, int portn, struct so
|
||||
void uwsgi_setup_shared_sockets() {
|
||||
int i;
|
||||
struct uwsgi_socket *shared_sock = uwsgi.shared_sockets;
|
||||
while (shared_sock) {
|
||||
if (!uwsgi.is_a_reload) {
|
||||
char *tcp_port = strrchr(shared_sock->name, ':');
|
||||
if (tcp_port == NULL) {
|
||||
shared_sock->fd = bind_to_unix(shared_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
shared_sock->family = AF_UNIX;
|
||||
uwsgi_log("uwsgi shared socket %d bound to UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
while (shared_sock) {
|
||||
if (!uwsgi.is_a_reload) {
|
||||
char *tcp_port = strrchr(shared_sock->name, ':');
|
||||
int current_defer_accept = uwsgi.no_defer_accept;
|
||||
if (shared_sock->no_defer) {
|
||||
uwsgi.no_defer_accept = 1;
|
||||
}
|
||||
else {
|
||||
if (tcp_port == NULL) {
|
||||
shared_sock->fd = bind_to_unix(shared_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
shared_sock->family = AF_UNIX;
|
||||
uwsgi_log("uwsgi shared socket %d bound to UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_IPV6
|
||||
if (shared_sock->name[0] == '[' && tcp_port[-1] == ']') {
|
||||
shared_sock->fd = bind_to_tcp6(shared_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
shared_sock->family = AF_INET6;
|
||||
// fix socket name
|
||||
shared_sock->name = uwsgi_getsockname(shared_sock->fd);
|
||||
uwsgi_log("uwsgi shared socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
}
|
||||
else {
|
||||
if (shared_sock->name[0] == '[' && tcp_port[-1] == ']') {
|
||||
shared_sock->fd = bind_to_tcp6(shared_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
shared_sock->family = AF_INET6;
|
||||
// fix socket name
|
||||
shared_sock->name = uwsgi_getsockname(shared_sock->fd);
|
||||
uwsgi_log("uwsgi shared socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
shared_sock->fd = bind_to_tcp(shared_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
shared_sock->family = AF_INET;
|
||||
// fix socket name
|
||||
shared_sock->name = uwsgi_getsockname(shared_sock->fd);
|
||||
uwsgi_log("uwsgi shared socket %d bound to TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
shared_sock->fd = bind_to_tcp(shared_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
shared_sock->family = AF_INET;
|
||||
// fix socket name
|
||||
shared_sock->name = uwsgi_getsockname(shared_sock->fd);
|
||||
uwsgi_log("uwsgi shared socket %d bound to TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
#ifdef UWSGI_IPV6
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (shared_sock->fd < 0) {
|
||||
uwsgi_log("unable to create shared socket on: %s\n", shared_sock->name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (shared_sock->no_defer) {
|
||||
uwsgi.no_defer_accept = current_defer_accept;
|
||||
}
|
||||
|
||||
if (shared_sock->fd < 0) {
|
||||
uwsgi_log("unable to create shared socket on: %s\n", shared_sock->name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 3; i < (int) uwsgi.max_fd; i++) {
|
||||
char *sock = uwsgi_getsockname(i);
|
||||
if (sock) {
|
||||
if (!strcmp(sock, shared_sock->name)) {
|
||||
if (strchr(sock, ':')) {
|
||||
uwsgi_log("uwsgi shared socket %d inherited TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
|
||||
shared_sock->family = AF_INET;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("uwsgi shared socket %d inherited UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
|
||||
shared_sock->family = AF_UNIX;
|
||||
}
|
||||
shared_sock->fd = i;
|
||||
}
|
||||
else {
|
||||
free(sock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shared_sock->bound = 1;
|
||||
shared_sock = shared_sock->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 3; i < (int) uwsgi.max_fd; i++) {
|
||||
char *sock = uwsgi_getsockname(i);
|
||||
if (sock) {
|
||||
if (!strcmp(sock, shared_sock->name)) {
|
||||
if (strchr(sock, ':')) {
|
||||
uwsgi_log("uwsgi shared socket %d inherited TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
|
||||
shared_sock->family = AF_INET;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("uwsgi shared socket %d inherited UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
|
||||
shared_sock->family = AF_UNIX;
|
||||
}
|
||||
shared_sock->fd = i;
|
||||
}
|
||||
else {
|
||||
free(sock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shared_sock->bound = 1;
|
||||
shared_sock = shared_sock->next;
|
||||
}
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
|
||||
if (uwsgi_sock->shared) {
|
||||
shared_sock = uwsgi_get_shared_socket_by_num(uwsgi_sock->from_shared);
|
||||
if (!shared_sock) {
|
||||
uwsgi_log("unable to find shared socket %d\n", uwsgi_sock->from_shared);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->fd = shared_sock->fd;
|
||||
uwsgi_sock->family = shared_sock->family;
|
||||
uwsgi_sock->name = shared_sock->name;
|
||||
uwsgi_log("uwsgi socket %d mapped to shared socket %d (%s) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
if (uwsgi_sock->shared) {
|
||||
shared_sock = uwsgi_get_shared_socket_by_num(uwsgi_sock->from_shared);
|
||||
if (!shared_sock) {
|
||||
uwsgi_log("unable to find shared socket %d\n", uwsgi_sock->from_shared);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->fd = shared_sock->fd;
|
||||
uwsgi_sock->family = shared_sock->family;
|
||||
uwsgi_sock->name = shared_sock->name;
|
||||
uwsgi_log("uwsgi socket %d mapped to shared socket %d (%s) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_map_sockets() {
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
struct uwsgi_string_list *usl = uwsgi.map_socket;
|
||||
int enabled = 1;
|
||||
while (usl) {
|
||||
while (uwsgi_sock) {
|
||||
struct uwsgi_string_list *usl = uwsgi.map_socket;
|
||||
int enabled = 1;
|
||||
while (usl) {
|
||||
|
||||
char *colon = strchr(usl->value, ':');
|
||||
char *colon = strchr(usl->value, ':');
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid socket mapping, must be socket:worker[,worker...]\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((int) uwsgi_str_num(usl->value, colon - usl->value) == uwsgi_get_socket_num(uwsgi_sock)) {
|
||||
enabled = 0;
|
||||
char *p = strtok(colon + 1, ",");
|
||||
while (p != NULL) {
|
||||
int w = atoi(p);
|
||||
if (w < 1 || w > uwsgi.numproc) {
|
||||
uwsgi_log("invalid worker num: %d\n", w);
|
||||
exit(1);
|
||||
}
|
||||
if (w == uwsgi.mywid) {
|
||||
enabled = 1;
|
||||
uwsgi_log("mapped socket %d (%s) to worker %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi.mywid);
|
||||
break;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
if ((int) uwsgi_str_num(usl->value, colon - usl->value) == uwsgi_get_socket_num(uwsgi_sock)) {
|
||||
enabled = 0;
|
||||
char *p = strtok(colon + 1, ",");
|
||||
while (p != NULL) {
|
||||
int w = atoi(p);
|
||||
if (w < 1 || w > uwsgi.numproc) {
|
||||
uwsgi_log("invalid worker num: %d\n", w);
|
||||
exit(1);
|
||||
}
|
||||
if (w == uwsgi.mywid) {
|
||||
enabled = 1;
|
||||
uwsgi_log("mapped socket %d (%s) to worker %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi.mywid);
|
||||
break;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
usl = usl->next;
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
close(uwsgi_sock->fd);
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != uwsgi_sock->fd) {
|
||||
if (dup2(fd, uwsgi_sock->fd)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
uwsgi_sock->disabled = 1;
|
||||
}
|
||||
if (!enabled) {
|
||||
close(uwsgi_sock->fd);
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != uwsgi_sock->fd) {
|
||||
if (dup2(fd, uwsgi_sock->fd)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
uwsgi_sock->disabled = 1;
|
||||
}
|
||||
|
||||
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->disabled) {
|
||||
uwsgi_sock = uwsgi_del_socket(uwsgi_sock);
|
||||
}
|
||||
else {
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
}
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->disabled) {
|
||||
uwsgi_sock = uwsgi_del_socket(uwsgi_sock);
|
||||
}
|
||||
else {
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_bind_sockets() {
|
||||
socklen_t socket_type_len;
|
||||
union uwsgi_sockaddr usa;
|
||||
union uwsgi_sockaddr_ptr gsa;
|
||||
union uwsgi_sockaddr_ptr gsa;
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (!uwsgi_sock->bound && !uwsgi_socket_is_already_bound(uwsgi_sock->name)) {
|
||||
char *tcp_port = strrchr(uwsgi_sock->name, ':');
|
||||
if (tcp_port == NULL) {
|
||||
uwsgi_sock->fd = bind_to_unix(uwsgi_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
if (uwsgi.chown_socket) {
|
||||
uwsgi_chown(uwsgi_sock->name, uwsgi.chown_socket);
|
||||
}
|
||||
uwsgi_log("uwsgi socket %d bound to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
else {
|
||||
while (uwsgi_sock) {
|
||||
if (!uwsgi_sock->bound && !uwsgi_socket_is_already_bound(uwsgi_sock->name)) {
|
||||
char *tcp_port = strrchr(uwsgi_sock->name, ':');
|
||||
if (tcp_port == NULL) {
|
||||
uwsgi_sock->fd = bind_to_unix(uwsgi_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
if (uwsgi.chown_socket) {
|
||||
uwsgi_chown(uwsgi_sock->name, uwsgi.chown_socket);
|
||||
}
|
||||
uwsgi_log("uwsgi socket %d bound to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_IPV6
|
||||
if (uwsgi_sock->name[0] == '[' && tcp_port[-1] == ']') {
|
||||
uwsgi_sock->fd = bind_to_tcp6(uwsgi_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi_log("uwsgi socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
uwsgi_sock->family = AF_INET6;
|
||||
}
|
||||
else {
|
||||
if (uwsgi_sock->name[0] == '[' && tcp_port[-1] == ']') {
|
||||
uwsgi_sock->fd = bind_to_tcp6(uwsgi_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi_log("uwsgi socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
uwsgi_sock->family = AF_INET6;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
uwsgi_sock->fd = bind_to_tcp(uwsgi_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi_log("uwsgi socket %d bound to TCP address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
uwsgi_sock->family = AF_INET;
|
||||
uwsgi_sock->fd = bind_to_tcp(uwsgi_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi_log("uwsgi socket %d bound to TCP address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
uwsgi_sock->family = AF_INET;
|
||||
#ifdef UWSGI_IPV6
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_sock->fd < 0 && !uwsgi_sock->per_core) {
|
||||
uwsgi_log("unable to create server socket on: %s\n", uwsgi_sock->name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
if (uwsgi_sock->fd < 0 && !uwsgi_sock->per_core) {
|
||||
uwsgi_log("unable to create server socket on: %s\n", uwsgi_sock->name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.chown_socket) {
|
||||
if (!uwsgi.master_as_root) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
}
|
||||
if (uwsgi.chown_socket) {
|
||||
if (!uwsgi.master_as_root) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
}
|
||||
|
||||
int zero_used = 0;
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->bound && uwsgi_sock->fd == 0) {
|
||||
zero_used = 1;
|
||||
break;
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->bound && uwsgi_sock->fd == 0) {
|
||||
zero_used = 1;
|
||||
break;
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
if (!zero_used) {
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = (struct sockaddr *) &usa;
|
||||
if (!uwsgi.skip_zero && !getsockname(0, gsa.sa, &socket_type_len)) {
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
uwsgi_sock = uwsgi_new_socket(usa.sa_un.sun_path);
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
uwsgi_sock->fd = 0;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_log("uwsgi socket %d inherited UNIX address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
else {
|
||||
uwsgi_sock = uwsgi_new_socket(uwsgi_concat2("::", ""));
|
||||
uwsgi_sock->family = AF_INET;
|
||||
uwsgi_sock->fd = 0;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
}
|
||||
else if (!uwsgi.honour_stdin) {
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != 0) {
|
||||
if (dup2(fd, 0)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
else if (uwsgi.honour_stdin) {
|
||||
if (!tcgetattr(0, &uwsgi.termios)) {
|
||||
uwsgi.restore_tc = 1;
|
||||
}
|
||||
}
|
||||
if (!zero_used) {
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = (struct sockaddr *) &usa;
|
||||
if (!uwsgi.skip_zero && !getsockname(0, gsa.sa, &socket_type_len)) {
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
uwsgi_sock = uwsgi_new_socket(usa.sa_un.sun_path);
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
uwsgi_sock->fd = 0;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_log("uwsgi socket %d inherited UNIX address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
else {
|
||||
uwsgi_sock = uwsgi_new_socket(uwsgi_concat2("::", ""));
|
||||
uwsgi_sock->family = AF_INET;
|
||||
uwsgi_sock->fd = 0;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
}
|
||||
else if (!uwsgi.honour_stdin) {
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != 0) {
|
||||
if (dup2(fd, 0)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
else if (uwsgi.honour_stdin) {
|
||||
if (!tcgetattr(0, &uwsgi.termios)) {
|
||||
uwsgi.restore_tc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// check for auto_port socket
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->auto_port) {
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->auto_port) {
|
||||
#ifdef UWSGI_IPV6
|
||||
if (uwsgi_sock->family == AF_INET6) {
|
||||
uwsgi_log("uwsgi socket %d bound to TCP6 address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
else {
|
||||
if (uwsgi_sock->family == AF_INET6) {
|
||||
uwsgi_log("uwsgi socket %d bound to TCP6 address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
uwsgi_log("uwsgi socket %d bound to TCP address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
uwsgi_log("uwsgi socket %d bound to TCP address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
#ifdef UWSGI_IPV6
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_set_sockets_protocols() {
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
char *requested_protocol = uwsgi_sock->proto_name;
|
||||
while (uwsgi_sock) {
|
||||
char *requested_protocol = uwsgi_sock->proto_name;
|
||||
|
||||
if (uwsgi_sock->lazy) goto setup_proto;
|
||||
if (!uwsgi_sock->bound || uwsgi_sock->fd == -1)
|
||||
goto nextsock;
|
||||
if (!uwsgi_sock->per_core) {
|
||||
uwsgi_sock->arg = fcntl(uwsgi_sock->fd, F_GETFL, NULL);
|
||||
if (uwsgi_sock->arg < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->arg |= O_NONBLOCK;
|
||||
if (fcntl(uwsgi_sock->fd, F_SETFL, uwsgi_sock->arg) < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (uwsgi_sock->lazy)
|
||||
goto setup_proto;
|
||||
if (!uwsgi_sock->bound || uwsgi_sock->fd == -1)
|
||||
goto nextsock;
|
||||
if (!uwsgi_sock->per_core) {
|
||||
uwsgi_sock->arg = fcntl(uwsgi_sock->fd, F_GETFL, NULL);
|
||||
if (uwsgi_sock->arg < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->arg |= O_NONBLOCK;
|
||||
if (fcntl(uwsgi_sock->fd, F_SETFL, uwsgi_sock->arg) < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
setup_proto:
|
||||
if (!requested_protocol) {
|
||||
requested_protocol = uwsgi.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_write = uwsgi_proto_uwsgi_write;
|
||||
uwsgi_sock->proto_writev = uwsgi_proto_uwsgi_writev;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_uwsgi_write_header;
|
||||
uwsgi_sock->proto_writev_header = uwsgi_proto_uwsgi_writev_header;
|
||||
uwsgi_sock->proto_sendfile = NULL;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_base_close;
|
||||
if (uwsgi.static_offload_to_thread)
|
||||
uwsgi_sock->can_offload = 1;
|
||||
}
|
||||
else if (requested_protocol && (!strcmp("fastcgi", requested_protocol) || !strcmp("fcgi", requested_protocol))) {
|
||||
if (uwsgi.protocol && (!strcmp(uwsgi.protocol, "fastcgi") || !strcmp(uwsgi.protocol, "fcgi"))) {
|
||||
uwsgi.shared->options[UWSGI_OPTION_CGI_MODE] = 1;
|
||||
}
|
||||
uwsgi_sock->proto = uwsgi_proto_fastcgi_parser;
|
||||
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
|
||||
uwsgi_sock->proto_write = uwsgi_proto_fastcgi_write;
|
||||
uwsgi_sock->proto_writev = uwsgi_proto_fastcgi_writev;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_fastcgi_write_header;
|
||||
uwsgi_sock->proto_writev_header = uwsgi_proto_fastcgi_writev_header;
|
||||
uwsgi_sock->proto_sendfile = uwsgi_proto_fastcgi_sendfile;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_fastcgi_close;
|
||||
}
|
||||
if (requested_protocol && !strcmp("http", requested_protocol)) {
|
||||
uwsgi_sock->proto = uwsgi_proto_http_parser;
|
||||
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
|
||||
uwsgi_sock->proto_write = uwsgi_proto_uwsgi_write;
|
||||
uwsgi_sock->proto_writev = uwsgi_proto_uwsgi_writev;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_uwsgi_write_header;
|
||||
uwsgi_sock->proto_writev_header = uwsgi_proto_uwsgi_writev_header;
|
||||
uwsgi_sock->proto_sendfile = NULL;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_base_close;
|
||||
if (uwsgi.offload_threads > 0)
|
||||
uwsgi_sock->can_offload = 1;
|
||||
}
|
||||
else if (requested_protocol && (!strcmp("fastcgi", requested_protocol) || !strcmp("fcgi", requested_protocol))) {
|
||||
if (uwsgi.protocol && (!strcmp(uwsgi.protocol, "fastcgi") || !strcmp(uwsgi.protocol, "fcgi"))) {
|
||||
uwsgi.shared->options[UWSGI_OPTION_CGI_MODE] = 1;
|
||||
}
|
||||
uwsgi_sock->proto = uwsgi_proto_fastcgi_parser;
|
||||
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
|
||||
uwsgi_sock->proto_write = uwsgi_proto_fastcgi_write;
|
||||
uwsgi_sock->proto_writev = uwsgi_proto_fastcgi_writev;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_fastcgi_write_header;
|
||||
uwsgi_sock->proto_writev_header = uwsgi_proto_fastcgi_writev_header;
|
||||
uwsgi_sock->proto_sendfile = uwsgi_proto_fastcgi_sendfile;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_fastcgi_close;
|
||||
}
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
else if (requested_protocol && !strcmp("zmq", requested_protocol)) {
|
||||
uwsgi.zeromq = 1;
|
||||
}
|
||||
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_write = uwsgi_proto_uwsgi_write;
|
||||
uwsgi_sock->proto_writev = uwsgi_proto_uwsgi_writev;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_uwsgi_write_header;
|
||||
uwsgi_sock->proto_writev_header = uwsgi_proto_uwsgi_writev_header;
|
||||
uwsgi_sock->proto_sendfile = NULL;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_base_close;
|
||||
if (uwsgi.static_offload_to_thread)
|
||||
uwsgi_sock->can_offload = 1;
|
||||
}
|
||||
else {
|
||||
uwsgi_sock->proto = uwsgi_proto_uwsgi_parser;
|
||||
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
|
||||
uwsgi_sock->proto_write = uwsgi_proto_uwsgi_write;
|
||||
uwsgi_sock->proto_writev = uwsgi_proto_uwsgi_writev;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_uwsgi_write_header;
|
||||
uwsgi_sock->proto_writev_header = uwsgi_proto_uwsgi_writev_header;
|
||||
uwsgi_sock->proto_sendfile = NULL;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_base_close;
|
||||
if (uwsgi.offload_threads > 0)
|
||||
uwsgi_sock->can_offload = 1;
|
||||
}
|
||||
nextsock:
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+94
-86
@@ -13,27 +13,31 @@ static void spooler_manage_task(struct uwsgi_spooler *, char *, char *);
|
||||
static uint64_t wakeup = 0;
|
||||
|
||||
// function to allow waking up the spooler if blocked in event_wait
|
||||
void spooler_wakeup() { wakeup++; }
|
||||
void spooler_wakeup() {
|
||||
wakeup++;
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_spooler(char *opt, char *directory, void *mode) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_spooler *us;
|
||||
|
||||
if (access(directory, R_OK | W_OK | X_OK)) {
|
||||
uwsgi_error("[spooler directory] access()");
|
||||
exit(1);
|
||||
}
|
||||
if (access(directory, R_OK | W_OK | X_OK)) {
|
||||
uwsgi_error("[spooler directory] access()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.spooler_numproc > 0) {
|
||||
for(i=0;i<uwsgi.spooler_numproc;i++) {
|
||||
for (i = 0; i < uwsgi.spooler_numproc; i++) {
|
||||
us = uwsgi_new_spooler(directory);
|
||||
if (mode) us->mode = (long) mode;
|
||||
if (mode)
|
||||
us->mode = (long) mode;
|
||||
}
|
||||
}
|
||||
else {
|
||||
us = uwsgi_new_spooler(directory);
|
||||
if (mode) us->mode = (long) mode;
|
||||
us = uwsgi_new_spooler(directory);
|
||||
if (mode)
|
||||
us->mode = (long) mode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,31 +45,31 @@ void uwsgi_opt_add_spooler(char *opt, char *directory, void *mode) {
|
||||
|
||||
struct uwsgi_spooler *uwsgi_new_spooler(char *dir) {
|
||||
|
||||
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
||||
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
||||
|
||||
if (!uspool) {
|
||||
uwsgi.spoolers = uwsgi_calloc_shared(sizeof(struct uwsgi_spooler));
|
||||
uspool = uwsgi.spoolers;
|
||||
}
|
||||
else {
|
||||
while(uspool) {
|
||||
if (uspool->next == NULL) {
|
||||
uspool->next = uwsgi_calloc_shared(sizeof(struct uwsgi_spooler));
|
||||
uspool = uspool->next;
|
||||
break;
|
||||
}
|
||||
uspool = uspool->next;
|
||||
}
|
||||
}
|
||||
if (!uspool) {
|
||||
uwsgi.spoolers = uwsgi_calloc_shared(sizeof(struct uwsgi_spooler));
|
||||
uspool = uwsgi.spoolers;
|
||||
}
|
||||
else {
|
||||
while (uspool) {
|
||||
if (uspool->next == NULL) {
|
||||
uspool->next = uwsgi_calloc_shared(sizeof(struct uwsgi_spooler));
|
||||
uspool = uspool->next;
|
||||
break;
|
||||
}
|
||||
uspool = uspool->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!realpath(dir, uspool->dir)) {
|
||||
uwsgi_error("[spooler] realpath()");
|
||||
exit(1);
|
||||
}
|
||||
if (!realpath(dir, uspool->dir)) {
|
||||
uwsgi_error("[spooler] realpath()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uspool->next = NULL;
|
||||
uspool->next = NULL;
|
||||
|
||||
return uspool;
|
||||
return uspool;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,18 +77,18 @@ struct uwsgi_spooler *uwsgi_get_spooler_by_name(char *name) {
|
||||
|
||||
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
||||
|
||||
while(uspool) {
|
||||
while (uspool) {
|
||||
if (!strcmp(uspool->dir, name)) {
|
||||
return uspool;
|
||||
}
|
||||
uspool = uspool->next;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pid_t spooler_start(struct uwsgi_spooler *uspool) {
|
||||
|
||||
pid_t spooler_start(struct uwsgi_spooler * uspool) {
|
||||
|
||||
int i;
|
||||
|
||||
pid_t pid = uwsgi_fork("uWSGI spooler");
|
||||
@@ -105,24 +109,24 @@ pid_t spooler_start(struct uwsgi_spooler *uspool) {
|
||||
uwsgi_close_all_sockets();
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->post_fork) {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->post_fork) {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1];
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->spooler_init) {
|
||||
uwsgi.p[i]->spooler_init();
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->spooler_init) {
|
||||
uwsgi.p[i]->spooler_init();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->spooler_init) {
|
||||
uwsgi.gp[i]->spooler_init();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->spooler_init) {
|
||||
uwsgi.gp[i]->spooler_init();
|
||||
}
|
||||
}
|
||||
|
||||
spooler(uspool);
|
||||
}
|
||||
@@ -137,14 +141,14 @@ void destroy_spool(char *dir, char *file) {
|
||||
|
||||
if (chdir(dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
uwsgi_log("[spooler] something horrible happened to the spooler. Better to kill it.\n");
|
||||
uwsgi_log("[spooler] something horrible happened to the spooler. Better to kill it.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (unlink(file)) {
|
||||
uwsgi_error("unlink()");
|
||||
uwsgi_log("[spooler] something horrible happened to the spooler. Better to kill it.\n");
|
||||
exit(1);
|
||||
uwsgi_error("unlink()");
|
||||
uwsgi_log("[spooler] something horrible happened to the spooler. Better to kill it.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -194,7 +198,7 @@ int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core
|
||||
|
||||
// now lock the file, it will no be runnable, until the lock is not removed
|
||||
// a race could come if the spooler take the file before fcntl is called
|
||||
// in such case the spooler will detect a zeroed file and will retry later
|
||||
// in such case the spooler will detect a zeroed file and will retry later
|
||||
if (uwsgi_fcntl_lock(fd)) {
|
||||
close(fd);
|
||||
uwsgi_unlock(uspool->lock);
|
||||
@@ -217,8 +221,8 @@ int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core
|
||||
}
|
||||
|
||||
if (body && body_len > 0) {
|
||||
if ((size_t)write(fd, body, body_len) != body_len) {
|
||||
goto clear;
|
||||
if ((size_t) write(fd, body, body_len) != body_len) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +246,7 @@ int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core
|
||||
|
||||
if (!uwsgi.spooler_quiet)
|
||||
uwsgi_log("[spooler] written %d bytes to file %s\n", size + body_len + 4, filename);
|
||||
|
||||
|
||||
// and here waiting threads can continue
|
||||
uwsgi_unlock(uspool->lock);
|
||||
|
||||
@@ -252,7 +256,7 @@ int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core
|
||||
*/
|
||||
|
||||
struct uwsgi_spooler *spoolers = uwsgi.spoolers;
|
||||
while(spoolers) {
|
||||
while (spoolers) {
|
||||
if (!strcmp(spoolers->dir, uspool->dir)) {
|
||||
if (spoolers->pid > 0 && spoolers->running == 0) {
|
||||
(void) kill(spoolers->pid, SIGUSR1);
|
||||
@@ -264,7 +268,7 @@ int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core
|
||||
return 1;
|
||||
|
||||
|
||||
clear:
|
||||
clear:
|
||||
uwsgi_unlock(uspool->lock);
|
||||
uwsgi_error("write()");
|
||||
if (unlink(filename)) {
|
||||
@@ -364,17 +368,18 @@ static void spooler_scandir(struct uwsgi_spooler *uspool, char *dir) {
|
||||
struct dirent **tasklist;
|
||||
int n;
|
||||
|
||||
if (!dir) dir = uspool->dir;
|
||||
if (!dir)
|
||||
dir = uspool->dir;
|
||||
|
||||
n = scandir(dir, &tasklist, 0, versionsort);
|
||||
if (n < 0) {
|
||||
uwsgi_error("scandir()");
|
||||
return;
|
||||
}
|
||||
|
||||
while(n--) {
|
||||
|
||||
while (n--) {
|
||||
spooler_manage_task(uspool, dir, tasklist[n]->d_name);
|
||||
free(tasklist[n]);
|
||||
free(tasklist[n]);
|
||||
}
|
||||
|
||||
free(tasklist);
|
||||
@@ -387,7 +392,8 @@ static void spooler_readdir(struct uwsgi_spooler *uspool, char *dir) {
|
||||
DIR *sdir;
|
||||
struct dirent *dp;
|
||||
|
||||
if (!dir) dir = uspool->dir;
|
||||
if (!dir)
|
||||
dir = uspool->dir;
|
||||
|
||||
sdir = opendir(dir);
|
||||
if (sdir) {
|
||||
@@ -412,7 +418,8 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
|
||||
|
||||
int spool_fd;
|
||||
|
||||
if (!dir) dir = uspool->dir;
|
||||
if (!dir)
|
||||
dir = uspool->dir;
|
||||
|
||||
if (!strncmp("uwsgi_spoolfile_on_", task, 19) || (uwsgi.spooler_ordered && is_a_number(task))) {
|
||||
struct stat sf_lstat;
|
||||
@@ -481,16 +488,16 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
|
||||
|
||||
if (uwsgi_protected_read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
|
||||
uwsgi_error("read()");
|
||||
destroy_spool(dir, task);
|
||||
destroy_spool(dir, task);
|
||||
uwsgi_protected_close(spool_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// body available ?
|
||||
if (sf_lstat.st_size > (uh.pktsize+4)) {
|
||||
body_len = sf_lstat.st_size - (uh.pktsize+4);
|
||||
if (sf_lstat.st_size > (uh.pktsize + 4)) {
|
||||
body_len = sf_lstat.st_size - (uh.pktsize + 4);
|
||||
body = uwsgi_malloc(body_len);
|
||||
if ((size_t)uwsgi_protected_read(spool_fd, body, body_len) != body_len) {
|
||||
if ((size_t) uwsgi_protected_read(spool_fd, body, body_len) != body_len) {
|
||||
uwsgi_error("read()");
|
||||
destroy_spool(dir, task);
|
||||
uwsgi_protected_close(spool_fd);
|
||||
@@ -514,27 +521,28 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
|
||||
}
|
||||
|
||||
int callable_found = 0;
|
||||
for(i=0;i<256;i++) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->spooler) {
|
||||
time_t now = uwsgi_now();
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
|
||||
}
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
|
||||
}
|
||||
ret = uwsgi.p[i]->spooler(task, spool_buf, uh.pktsize, body, body_len);
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(0);
|
||||
}
|
||||
if (ret == 0) continue;
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(0);
|
||||
}
|
||||
if (ret == 0)
|
||||
continue;
|
||||
callable_found = 1;
|
||||
// increase task counter
|
||||
uspool->tasks++;
|
||||
if (ret == -2) {
|
||||
if (!uwsgi.spooler_quiet)
|
||||
uwsgi_log("[spooler %s pid: %d] done with task %s after %d seconds\n", uspool->dir, (int) uwsgi.mypid, task, uwsgi_now()-now);
|
||||
destroy_spool(dir, task);
|
||||
uwsgi_log("[spooler %s pid: %d] done with task %s after %d seconds\n", uspool->dir, (int) uwsgi.mypid, task, uwsgi_now() - now);
|
||||
destroy_spool(dir, task);
|
||||
}
|
||||
// re-spool it
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,15 +555,15 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
|
||||
|
||||
|
||||
// need to recycle ?
|
||||
if (uwsgi.spooler_max_tasks > 0 && uspool->tasks >= (uint64_t)uwsgi.spooler_max_tasks) {
|
||||
uwsgi_log("[spooler %s pid: %d] maximum number of tasks reached (%d) recycling ...\n", uspool->dir, (int) uwsgi.mypid, uwsgi.spooler_max_tasks);
|
||||
end_me(0);
|
||||
}
|
||||
if (uwsgi.spooler_max_tasks > 0 && uspool->tasks >= (uint64_t) uwsgi.spooler_max_tasks) {
|
||||
uwsgi_log("[spooler %s pid: %d] maximum number of tasks reached (%d) recycling ...\n", uspool->dir, (int) uwsgi.mypid, uwsgi.spooler_max_tasks);
|
||||
end_me(0);
|
||||
}
|
||||
|
||||
|
||||
if (chdir(dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
uwsgi_log("[spooler] something horrible happened to the spooler. Better to kill it.\n");
|
||||
uwsgi_error("chdir()");
|
||||
uwsgi_log("[spooler] something horrible happened to the spooler. Better to kill it.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@ static int uwsgi_sqlite3_config_callback(void *magic_table, int field_count, cha
|
||||
if (field_count >= 2) {
|
||||
int value_len = strlen(fields[1]) + 1;
|
||||
char *value = magic_sub(fields[1], value_len, &value_len, (char **) magic_table);
|
||||
add_exported_option( uwsgi_strncopy(fields[0], strlen(fields[0])), value, 0);
|
||||
add_exported_option(uwsgi_strncopy(fields[0], strlen(fields[0])), value, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -20,7 +20,7 @@ static int uwsgi_sqlite3_config_callback(void *magic_table, int field_count, cha
|
||||
void uwsgi_sqlite3_config(char *file, char *magic_table[]) {
|
||||
|
||||
sqlite3 *db;
|
||||
char *err = NULL;
|
||||
char *err = NULL;
|
||||
char *query = "SELECT * FROM uwsgi";
|
||||
|
||||
char *colon = uwsgi_get_last_char(file, ':');
|
||||
@@ -28,7 +28,7 @@ void uwsgi_sqlite3_config(char *file, char *magic_table[]) {
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
if (colon[1] != 0) {
|
||||
query = colon+1;
|
||||
query = colon + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+211
-172
@@ -25,9 +25,10 @@ int uwsgi_stats_symbol(struct uwsgi_stats *us, char sym) {
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
|
||||
if (ptr+1 > watermark) {
|
||||
if (ptr + 1 > watermark) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
@@ -42,7 +43,8 @@ int uwsgi_stats_symbol_nl(struct uwsgi_stats *us, char sym) {
|
||||
if (uwsgi_stats_symbol(us, sym)) {
|
||||
return -1;
|
||||
}
|
||||
if (us->minified) return 0;
|
||||
if (us->minified)
|
||||
return 0;
|
||||
return uwsgi_stats_symbol(us, '\n');
|
||||
}
|
||||
|
||||
@@ -52,26 +54,32 @@ int uwsgi_stats_comma(struct uwsgi_stats *us) {
|
||||
}
|
||||
|
||||
int uwsgi_stats_apply_tabs(struct uwsgi_stats *us) {
|
||||
if (us->minified) return 0;
|
||||
if (us->minified)
|
||||
return 0;
|
||||
size_t i;
|
||||
for(i=0;i<us->tabs;i++) {
|
||||
if (uwsgi_stats_symbol(us, '\t')) return -1;
|
||||
for (i = 0; i < us->tabs; i++) {
|
||||
if (uwsgi_stats_symbol(us, '\t'))
|
||||
return -1;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_stats_object_open(struct uwsgi_stats *us) {
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (!us->minified) us->tabs++;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
if (!us->minified)
|
||||
us->tabs++;
|
||||
return uwsgi_stats_symbol_nl(us, '{');
|
||||
}
|
||||
|
||||
int uwsgi_stats_object_close(struct uwsgi_stats *us) {
|
||||
if (!us->minified) {
|
||||
if (uwsgi_stats_symbol(us, '\n')) return -1;
|
||||
if (uwsgi_stats_symbol(us, '\n'))
|
||||
return -1;
|
||||
us->tabs--;
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
}
|
||||
return uwsgi_stats_symbol(us, '}');
|
||||
}
|
||||
@@ -83,162 +91,186 @@ int uwsgi_stats_list_open(struct uwsgi_stats *us) {
|
||||
|
||||
int uwsgi_stats_list_close(struct uwsgi_stats *us) {
|
||||
if (!us->minified) {
|
||||
if (uwsgi_stats_symbol(us, '\n')) return -1;
|
||||
if (uwsgi_stats_symbol(us, '\n'))
|
||||
return -1;
|
||||
us->tabs--;
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
}
|
||||
return uwsgi_stats_symbol(us, ']');
|
||||
}
|
||||
|
||||
int uwsgi_stats_keyval(struct uwsgi_stats *us, char *key, char *value) {
|
||||
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr ;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\":\"%s\"", key, value);
|
||||
if (ret < 0) return -1;
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr ;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\":\"%s\"", key, value);
|
||||
if (ret < 0) return -1;
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_stats_keyval_comma(struct uwsgi_stats *us, char *key, char *value) {
|
||||
int ret = uwsgi_stats_keyval(us, key, value);
|
||||
if (ret) return -1;
|
||||
if (ret)
|
||||
return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
}
|
||||
|
||||
int uwsgi_stats_keyvalnum(struct uwsgi_stats *us, char *key, char *value, unsigned long long num) {
|
||||
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr ;
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\":\"%s%llu\"", key, value, num);
|
||||
if (ret < 0) return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
int ret = snprintf(ptr, available, "\"%s\":\"%s%llu\"", key, value, num);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr ;
|
||||
ret = snprintf(ptr, available, "\"%s\":\"%s%llu\"", key, value, num);
|
||||
if (ret < 0) return -1;
|
||||
}
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\":\"%s%llu\"", key, value, num);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_stats_keyvalnum_comma(struct uwsgi_stats *us, char *key, char *value, unsigned long long num) {
|
||||
int ret = uwsgi_stats_keyvalnum(us, key, value, num);
|
||||
if (ret) return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
int ret = uwsgi_stats_keyvalnum(us, key, value, num);
|
||||
if (ret)
|
||||
return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_stats_keyvaln(struct uwsgi_stats *us, char *key, char *value, int vallen) {
|
||||
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr ;
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\":\"%.*s\"", key, vallen, value);
|
||||
if (ret < 0) return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
int ret = snprintf(ptr, available, "\"%s\":\"%.*s\"", key, vallen, value);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr ;
|
||||
ret = snprintf(ptr, available, "\"%s\":\"%.*s\"", key, vallen, value);
|
||||
if (ret < 0) return -1;
|
||||
}
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\":\"%.*s\"", key, vallen, value);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_stats_keyvaln_comma(struct uwsgi_stats *us, char *key, char *value, int vallen) {
|
||||
int ret = uwsgi_stats_keyvaln(us, key, value, vallen);
|
||||
if (ret) return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
int ret = uwsgi_stats_keyvaln(us, key, value, vallen);
|
||||
if (ret)
|
||||
return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_stats_key(struct uwsgi_stats *us, char *key) {
|
||||
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr ;
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\":", key);
|
||||
if (ret < 0) return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
int ret = snprintf(ptr, available, "\"%s\":", key);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr ;
|
||||
ret = snprintf(ptr, available, "\"%s\":", key);
|
||||
if (ret < 0) return -1;
|
||||
}
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\":", key);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_stats_str(struct uwsgi_stats *us, char *str) {
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr ;
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\"", str);
|
||||
if (ret < 0) return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
int ret = snprintf(ptr, available, "\"%s\"", str);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr ;
|
||||
ret = snprintf(ptr, available, "\"%s\"", str);
|
||||
if (ret < 0) return -1;
|
||||
}
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\"", str);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -246,87 +278,93 @@ int uwsgi_stats_str(struct uwsgi_stats *us, char *str) {
|
||||
|
||||
int uwsgi_stats_keylong(struct uwsgi_stats *us, char *key, unsigned long long num) {
|
||||
|
||||
if (uwsgi_stats_apply_tabs(us)) return -1;
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr ;
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\":%llu", key, num);
|
||||
if (ret < 0) return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base) return -1;
|
||||
int ret = snprintf(ptr, available, "\"%s\":%llu", key, num);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr ;
|
||||
ret = snprintf(ptr, available, "\"%s\":%llu", key, num);
|
||||
if (ret < 0) return -1;
|
||||
}
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\":%llu", key, num);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_stats_keylong_comma(struct uwsgi_stats *us, char *key, unsigned long long num) {
|
||||
int ret = uwsgi_stats_keylong(us, key, num);
|
||||
if (ret) return -1;
|
||||
if (ret)
|
||||
return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
}
|
||||
|
||||
void uwsgi_send_stats(int fd, struct uwsgi_stats * (*func)(void)) {
|
||||
void uwsgi_send_stats(int fd, struct uwsgi_stats *(*func) (void)) {
|
||||
|
||||
struct sockaddr_un client_src;
|
||||
socklen_t client_src_len = 0;
|
||||
struct sockaddr_un client_src;
|
||||
socklen_t client_src_len = 0;
|
||||
|
||||
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("accept()");
|
||||
return;
|
||||
}
|
||||
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("accept()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (uwsgi.stats_http) {
|
||||
if (uwsgi_send_http_stats(client_fd)) {
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (uwsgi.stats_http) {
|
||||
if (uwsgi_send_http_stats(client_fd)) {
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_stats *us = func();
|
||||
if (!us) goto end;
|
||||
struct uwsgi_stats *us = func();
|
||||
if (!us)
|
||||
goto end;
|
||||
|
||||
size_t remains = us->pos;
|
||||
off_t pos = 0;
|
||||
while (remains > 0) {
|
||||
int ret = uwsgi_waitfd_write(client_fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (ret <= 0) {
|
||||
goto end0;
|
||||
}
|
||||
ssize_t res = write(client_fd, us->base + pos, remains);
|
||||
if (res <= 0) {
|
||||
if (res < 0) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
goto end0;
|
||||
}
|
||||
pos += res;
|
||||
remains -= res;
|
||||
}
|
||||
size_t remains = us->pos;
|
||||
off_t pos = 0;
|
||||
while (remains > 0) {
|
||||
int ret = uwsgi_waitfd_write(client_fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (ret <= 0) {
|
||||
goto end0;
|
||||
}
|
||||
ssize_t res = write(client_fd, us->base + pos, remains);
|
||||
if (res <= 0) {
|
||||
if (res < 0) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
goto end0;
|
||||
}
|
||||
pos += res;
|
||||
remains -= res;
|
||||
}
|
||||
|
||||
end0:
|
||||
free(us->base);
|
||||
free(us);
|
||||
|
||||
end:
|
||||
close(client_fd);
|
||||
close(client_fd);
|
||||
}
|
||||
|
||||
struct uwsgi_stats_pusher *uwsgi_stats_pusher_get(char *name) {
|
||||
struct uwsgi_stats_pusher *usp = uwsgi.stats_pushers;
|
||||
while(usp) {
|
||||
while (usp) {
|
||||
if (!strcmp(usp->name, name)) {
|
||||
return usp;
|
||||
}
|
||||
@@ -337,7 +375,7 @@ struct uwsgi_stats_pusher *uwsgi_stats_pusher_get(char *name) {
|
||||
|
||||
void uwsgi_stats_pusher_add(struct uwsgi_stats_pusher *pusher, char *arg) {
|
||||
struct uwsgi_stats_pusher_instance *old_uspi = NULL, *uspi = uwsgi.stats_pusher_instances;
|
||||
while(uspi) {
|
||||
while (uspi) {
|
||||
old_uspi = uspi;
|
||||
uspi = uspi->next;
|
||||
}
|
||||
@@ -355,8 +393,8 @@ void uwsgi_stats_pusher_add(struct uwsgi_stats_pusher *pusher, char *arg) {
|
||||
|
||||
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);
|
||||
for (;;) {
|
||||
int nevents = event_queue_wait_multi(ut->queue, 1, events, 1);
|
||||
if (nevents > 0) {
|
||||
int interesting_fd = event_queue_interesting_fd(events, 0);
|
||||
char buf[4096];
|
||||
@@ -372,13 +410,14 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
|
||||
time_t now = uwsgi_now();
|
||||
struct uwsgi_stats_pusher_instance *uspi = uwsgi.stats_pusher_instances;
|
||||
struct uwsgi_stats *us = NULL;
|
||||
while(uspi) {
|
||||
int delta = uspi->freq ? uspi->freq : uwsgi.stats_pusher_default_freq;
|
||||
if ( (uspi->last_run + delta) <= now) {
|
||||
while (uspi) {
|
||||
int delta = uspi->freq ? uspi->freq : uwsgi.stats_pusher_default_freq;
|
||||
if ((uspi->last_run + delta) <= now) {
|
||||
if (!us) {
|
||||
us = uwsgi_master_generate_stats();
|
||||
if (!us) goto next;
|
||||
}
|
||||
if (!us)
|
||||
goto next;
|
||||
}
|
||||
uspi->pusher->func(uspi, us->base, us->pos);
|
||||
uspi->last_run = now;
|
||||
}
|
||||
@@ -395,7 +434,7 @@ next:
|
||||
|
||||
void uwsgi_stats_pusher_setup() {
|
||||
struct uwsgi_string_list *usl = uwsgi.requested_stats_pushers;
|
||||
while(usl) {
|
||||
while (usl) {
|
||||
char *ssp = uwsgi_str(usl->value);
|
||||
struct uwsgi_stats_pusher *pusher = NULL;
|
||||
char *colon = strchr(ssp, ':');
|
||||
@@ -409,7 +448,7 @@ void uwsgi_stats_pusher_setup() {
|
||||
}
|
||||
char *arg = NULL;
|
||||
if (colon) {
|
||||
arg = colon+1;
|
||||
arg = colon + 1;
|
||||
*colon = ':';
|
||||
}
|
||||
uwsgi_stats_pusher_add(pusher, arg);
|
||||
@@ -417,11 +456,11 @@ void uwsgi_stats_pusher_setup() {
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_register_stats_pusher(char *name, void(*func) (struct uwsgi_stats_pusher_instance *, char *, size_t)) {
|
||||
void uwsgi_register_stats_pusher(char *name, void (*func) (struct uwsgi_stats_pusher_instance *, char *, size_t)) {
|
||||
|
||||
struct uwsgi_stats_pusher *pusher = uwsgi.stats_pushers, *old_pusher = NULL;
|
||||
struct uwsgi_stats_pusher *pusher = uwsgi.stats_pushers, *old_pusher = NULL;
|
||||
|
||||
while(pusher) {
|
||||
while (pusher) {
|
||||
old_pusher = pusher;
|
||||
pusher = pusher->next;
|
||||
}
|
||||
@@ -449,17 +488,17 @@ void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, char *jso
|
||||
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 (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);
|
||||
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;
|
||||
}
|
||||
@@ -475,7 +514,7 @@ void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, char *jso
|
||||
}
|
||||
|
||||
rlen = write(fd, uspic->separator, strlen(uspic->separator));
|
||||
if (rlen != (ssize_t ) strlen(uspic->separator)) {
|
||||
if (rlen != (ssize_t) strlen(uspic->separator)) {
|
||||
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
|
||||
}
|
||||
|
||||
|
||||
+237
-220
@@ -22,17 +22,18 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen) {
|
||||
|
||||
if (keylen > 0xff) return NULL;
|
||||
|
||||
if (keylen > 0xff)
|
||||
return NULL;
|
||||
|
||||
uint32_t hash = djb33x_hash(key, keylen);
|
||||
int hash_key = hash % 0xffff;
|
||||
|
||||
struct uwsgi_subscribe_slot *current_slot = slot[hash_key];
|
||||
|
||||
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("****************************\n");
|
||||
while(current_slot) {
|
||||
while (current_slot) {
|
||||
uwsgi_log("slot %.*s %d\n", current_slot->keylen, current_slot->key, current_slot->hits);
|
||||
current_slot = current_slot->next;
|
||||
}
|
||||
@@ -40,15 +41,15 @@ struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slo
|
||||
current_slot = slot[hash_key];
|
||||
#endif
|
||||
|
||||
while(current_slot) {
|
||||
while (current_slot) {
|
||||
if (!uwsgi_strncmp(key, keylen, current_slot->key, current_slot->keylen)) {
|
||||
// auto optimization
|
||||
if (current_slot->prev) {
|
||||
if (current_slot->hits > current_slot->prev->hits) {
|
||||
struct uwsgi_subscribe_slot *slot_parent = current_slot->prev->prev, *slot_prev = current_slot->prev;
|
||||
if (slot_parent) {
|
||||
slot_parent->next = current_slot;
|
||||
}
|
||||
// auto optimization
|
||||
if (current_slot->prev) {
|
||||
if (current_slot->hits > current_slot->prev->hits) {
|
||||
struct uwsgi_subscribe_slot *slot_parent = current_slot->prev->prev, *slot_prev = current_slot->prev;
|
||||
if (slot_parent) {
|
||||
slot_parent->next = current_slot;
|
||||
}
|
||||
else {
|
||||
slot[hash_key] = current_slot;
|
||||
}
|
||||
@@ -57,33 +58,35 @@ struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slo
|
||||
current_slot->next->prev = slot_prev;
|
||||
}
|
||||
|
||||
slot_prev->prev = current_slot;
|
||||
slot_prev->next = current_slot->next;
|
||||
slot_prev->prev = current_slot;
|
||||
slot_prev->next = current_slot->next;
|
||||
|
||||
current_slot->next = slot_prev;
|
||||
current_slot->next = slot_prev;
|
||||
current_slot->prev = slot_parent;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return current_slot;
|
||||
}
|
||||
current_slot = current_slot->next;
|
||||
// check for loopy optimization
|
||||
if (current_slot == slot[hash_key]) break;
|
||||
if (current_slot == slot[hash_key])
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// least reference count
|
||||
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_lrc(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node) {
|
||||
// if node is NULL we are in the second step (in lrc mode we do not use the first step)
|
||||
if (node) return NULL;
|
||||
if (node)
|
||||
return NULL;
|
||||
|
||||
struct uwsgi_subscribe_node *choosen_node = NULL;
|
||||
node = current_slot->nodes;
|
||||
uint64_t min_rc = 0;
|
||||
while(node) {
|
||||
while (node) {
|
||||
if (!node->death_mark) {
|
||||
if (min_rc == 0 || node->reference < min_rc) {
|
||||
min_rc = node->reference;
|
||||
@@ -105,12 +108,13 @@ static struct uwsgi_subscribe_node *uwsgi_subscription_algo_lrc(struct uwsgi_sub
|
||||
// weighted least reference count
|
||||
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_wlrc(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node) {
|
||||
// if node is NULL we are in the second step (in wlrc mode we do not use the first step)
|
||||
if (node) return NULL;
|
||||
if (node)
|
||||
return NULL;
|
||||
|
||||
struct uwsgi_subscribe_node *choosen_node = NULL;
|
||||
node = current_slot->nodes;
|
||||
double min_rc = 0;
|
||||
while(node) {
|
||||
while (node) {
|
||||
if (!node->death_mark) {
|
||||
// node->weight is always >= 1, we can safely use it as divider
|
||||
double ref = (double) node->reference / (double) node->weight;
|
||||
@@ -140,55 +144,57 @@ static struct uwsgi_subscribe_node *uwsgi_subscription_algo_wrr(struct uwsgi_sub
|
||||
// if node is NULL we are in the second step
|
||||
if (node) {
|
||||
if (node->death_mark == 0 && node->wrr > 0) {
|
||||
node->wrr--;
|
||||
node->reference++;
|
||||
return node;
|
||||
}
|
||||
node->wrr--;
|
||||
node->reference++;
|
||||
return node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// no wrr > 0 node found, reset them
|
||||
node = current_slot->nodes;
|
||||
uint64_t min_weight = 0;
|
||||
while(node) {
|
||||
if (!node->death_mark) {
|
||||
if (min_weight == 0 || node->weight < min_weight) min_weight = node->weight;
|
||||
}
|
||||
node = node->next;
|
||||
node = current_slot->nodes;
|
||||
uint64_t min_weight = 0;
|
||||
while (node) {
|
||||
if (!node->death_mark) {
|
||||
if (min_weight == 0 || node->weight < min_weight)
|
||||
min_weight = node->weight;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
// now set wrr
|
||||
node = current_slot->nodes;
|
||||
struct uwsgi_subscribe_node *choosen_node = NULL;
|
||||
while(node) {
|
||||
if (!node->death_mark) {
|
||||
node->wrr = node->weight/min_weight;
|
||||
choosen_node = node;
|
||||
}
|
||||
node = node->next;
|
||||
// now set wrr
|
||||
node = current_slot->nodes;
|
||||
struct uwsgi_subscribe_node *choosen_node = NULL;
|
||||
while (node) {
|
||||
if (!node->death_mark) {
|
||||
node->wrr = node->weight / min_weight;
|
||||
choosen_node = node;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
if (choosen_node) {
|
||||
choosen_node->wrr--;
|
||||
choosen_node->reference++;
|
||||
if (choosen_node) {
|
||||
choosen_node->wrr--;
|
||||
choosen_node->reference++;
|
||||
}
|
||||
return choosen_node;
|
||||
return choosen_node;
|
||||
}
|
||||
|
||||
void uwsgi_subscription_set_algo(char *algo) {
|
||||
|
||||
if (!algo) goto wrr;
|
||||
if (!algo)
|
||||
goto wrr;
|
||||
|
||||
if (!strcmp(algo,"wrr")) {
|
||||
if (!strcmp(algo, "wrr")) {
|
||||
uwsgi.subscription_algo = uwsgi_subscription_algo_wrr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(algo,"lrc")) {
|
||||
if (!strcmp(algo, "lrc")) {
|
||||
uwsgi.subscription_algo = uwsgi_subscription_algo_lrc;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(algo,"wlrc")) {
|
||||
if (!strcmp(algo, "wlrc")) {
|
||||
uwsgi.subscription_algo = uwsgi_subscription_algo_wlrc;
|
||||
return;
|
||||
}
|
||||
@@ -199,16 +205,18 @@ wrr:
|
||||
|
||||
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen) {
|
||||
|
||||
if (keylen > 0xff) return NULL;
|
||||
if (keylen > 0xff)
|
||||
return NULL;
|
||||
|
||||
struct uwsgi_subscribe_slot *current_slot = uwsgi_get_subscribe_slot(slot, key, keylen);
|
||||
if (!current_slot) return NULL;
|
||||
if (!current_slot)
|
||||
return NULL;
|
||||
|
||||
// slot found, move up in the list increasing hits
|
||||
current_slot->hits++;
|
||||
time_t now = uwsgi_now();
|
||||
struct uwsgi_subscribe_node *node = current_slot->nodes;
|
||||
while(node) {
|
||||
while (node) {
|
||||
// is the node alive ?
|
||||
if (now - node->last_check > uwsgi.subscription_tolerance) {
|
||||
if (node->death_mark == 0)
|
||||
@@ -229,7 +237,8 @@ struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slo
|
||||
}
|
||||
|
||||
struct uwsgi_subscribe_node *choosen_node = uwsgi.subscription_algo(current_slot, node);
|
||||
if (choosen_node) return choosen_node;
|
||||
if (choosen_node)
|
||||
return choosen_node;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
@@ -239,14 +248,15 @@ struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slo
|
||||
|
||||
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node_by_name(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen, char *val, uint16_t vallen) {
|
||||
|
||||
if (keylen > 0xff) return NULL;
|
||||
if (keylen > 0xff)
|
||||
return NULL;
|
||||
struct uwsgi_subscribe_slot *current_slot = uwsgi_get_subscribe_slot(slot, key, keylen);
|
||||
if (current_slot) {
|
||||
struct uwsgi_subscribe_node *node = current_slot->nodes;
|
||||
while(node) {
|
||||
while (node) {
|
||||
if (!uwsgi_strncmp(val, vallen, node->name, node->len)) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
@@ -273,7 +283,7 @@ int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi
|
||||
}
|
||||
else {
|
||||
a_node = node_slot->nodes;
|
||||
while(a_node) {
|
||||
while (a_node) {
|
||||
if (a_node->next == node) {
|
||||
a_node->next = node->next;
|
||||
break;
|
||||
@@ -291,10 +301,10 @@ int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi
|
||||
// first check if i am the only node
|
||||
if ((!prev_slot && !next_slot) || next_slot == node_slot) {
|
||||
#ifdef UWSGI_SSL
|
||||
if (uwsgi.subscriptions_sign_check_dir) {
|
||||
EVP_PKEY_free(node_slot->sign_public_key);
|
||||
EVP_MD_CTX_destroy(node_slot->sign_ctx);
|
||||
}
|
||||
if (uwsgi.subscriptions_sign_check_dir) {
|
||||
EVP_PKEY_free(node_slot->sign_public_key);
|
||||
EVP_MD_CTX_destroy(node_slot->sign_ctx);
|
||||
}
|
||||
#endif
|
||||
free(node_slot);
|
||||
slot[hash_key] = NULL;
|
||||
@@ -305,9 +315,9 @@ int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi
|
||||
if (node_slot == slot[hash_key]) {
|
||||
slot[hash_key] = next_slot;
|
||||
}
|
||||
|
||||
if (prev_slot) {
|
||||
prev_slot->next = next_slot;
|
||||
|
||||
if (prev_slot) {
|
||||
prev_slot->next = next_slot;
|
||||
}
|
||||
if (next_slot) {
|
||||
next_slot->prev = prev_slot;
|
||||
@@ -316,7 +326,7 @@ int uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi
|
||||
#ifdef UWSGI_SSL
|
||||
if (uwsgi.subscriptions_sign_check_dir) {
|
||||
EVP_PKEY_free(node_slot->sign_public_key);
|
||||
EVP_MD_CTX_destroy(node_slot->sign_ctx);
|
||||
EVP_MD_CTX_destroy(node_slot->sign_ctx);
|
||||
}
|
||||
#endif
|
||||
free(node_slot);
|
||||
@@ -332,46 +342,49 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
struct uwsgi_subscribe_slot *current_slot = uwsgi_get_subscribe_slot(slot, usr->key, usr->keylen), *old_slot = NULL, *a_slot;
|
||||
struct uwsgi_subscribe_node *node, *old_node = NULL;
|
||||
|
||||
if (usr->address_len > 0xff || usr->address_len == 0) return NULL;
|
||||
if (usr->address_len > 0xff || usr->address_len == 0)
|
||||
return NULL;
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
if (uwsgi.subscriptions_sign_check_dir) {
|
||||
if (usr->sign_len == 0 || usr->base_len == 0) return NULL;
|
||||
if (usr->sign_len == 0 || usr->base_len == 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (current_slot) {
|
||||
if (current_slot) {
|
||||
#ifdef UWSGI_SSL
|
||||
if (uwsgi.subscriptions_sign_check_dir && !uwsgi_subscription_sign_check(current_slot, usr)) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
node = current_slot->nodes;
|
||||
while(node) {
|
||||
if (!uwsgi_strncmp(node->name, node->len, usr->address, usr->address_len)) {
|
||||
while (node) {
|
||||
if (!uwsgi_strncmp(node->name, node->len, usr->address, usr->address_len)) {
|
||||
#ifdef UWSGI_SSL
|
||||
// this should avoid sending sniffed packets...
|
||||
if (uwsgi.subscriptions_sign_check_dir && usr->unix_check <= node->unix_check) {
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] invalid (sniffed ?) packet sent for slot: %.*s node: %.*s unix_check: %lu\n",(int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, (unsigned long) usr->unix_check);
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] invalid (sniffed ?) packet sent for slot: %.*s node: %.*s unix_check: %lu\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, (unsigned long) usr->unix_check);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
// remove death mark and update cores and load
|
||||
node->death_mark = 0;
|
||||
node->last_check = uwsgi_now();
|
||||
node->last_check = uwsgi_now();
|
||||
node->cores = usr->cores;
|
||||
node->load = usr->load;
|
||||
node->weight = usr->weight;
|
||||
if (!node->weight) node->weight = 1;
|
||||
return node;
|
||||
}
|
||||
if (!node->weight)
|
||||
node->weight = 1;
|
||||
return node;
|
||||
}
|
||||
old_node = node;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
if (uwsgi.subscriptions_sign_check_dir && usr->unix_check < (uwsgi_now()-(time_t)uwsgi.subscriptions_sign_check_tolerance)) {
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] invalid (sniffed ?) packet sent for slot: %.*s node: %.*s unix_check: %lu\n",(int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, (unsigned long) usr->unix_check);
|
||||
if (uwsgi.subscriptions_sign_check_dir && usr->unix_check < (uwsgi_now() - (time_t) uwsgi.subscriptions_sign_check_tolerance)) {
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] invalid (sniffed ?) packet sent for slot: %.*s node: %.*s unix_check: %lu\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, (unsigned long) usr->unix_check);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -389,36 +402,38 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
node->load = usr->load;
|
||||
node->weight = usr->weight;
|
||||
node->unix_check = usr->unix_check;
|
||||
if (!node->weight) node->weight = 1;
|
||||
if (!node->weight)
|
||||
node->weight = 1;
|
||||
node->wrr = 0;
|
||||
node->last_check = uwsgi_now();
|
||||
node->slot = current_slot;
|
||||
memcpy(node->name, usr->address, usr->address_len);
|
||||
memcpy(node->name, usr->address, usr->address_len);
|
||||
if (old_node) {
|
||||
old_node->next = node;
|
||||
}
|
||||
node->next = NULL;
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s\n",(int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address);
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address);
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_SSL
|
||||
FILE *kf = NULL;
|
||||
if (uwsgi.subscriptions_sign_check_dir) {
|
||||
if (usr->unix_check < (uwsgi_now()-(time_t)uwsgi.subscriptions_sign_check_tolerance)) {
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] invalid (sniffed ?) packet sent for slot: %.*s node: %.*s unix_check: %lu\n",(int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, (unsigned long) usr->unix_check);
|
||||
if (usr->unix_check < (uwsgi_now() - (time_t) uwsgi.subscriptions_sign_check_tolerance)) {
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] invalid (sniffed ?) packet sent for slot: %.*s node: %.*s unix_check: %lu\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, (unsigned long) usr->unix_check);
|
||||
return NULL;
|
||||
}
|
||||
char *keyfile = uwsgi_sanitize_cert_filename(uwsgi.subscriptions_sign_check_dir, usr->key, usr->keylen);
|
||||
kf = fopen(keyfile, "r");
|
||||
free(keyfile);
|
||||
if (!kf) return NULL;
|
||||
|
||||
if (!kf)
|
||||
return NULL;
|
||||
|
||||
}
|
||||
#endif
|
||||
current_slot = uwsgi_malloc(sizeof(struct uwsgi_subscribe_slot));
|
||||
uint32_t hash = djb33x_hash(usr->key, usr->keylen);
|
||||
int hash_key = hash % 0xffff;
|
||||
int hash_key = hash % 0xffff;
|
||||
current_slot->hash = hash_key;
|
||||
#ifdef UWSGI_SSL
|
||||
if (uwsgi.subscriptions_sign_check_dir) {
|
||||
@@ -464,7 +479,8 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
current_slot->nodes->load = usr->load;
|
||||
current_slot->nodes->weight = usr->weight;
|
||||
current_slot->nodes->unix_check = usr->unix_check;
|
||||
if (!current_slot->nodes->weight) current_slot->nodes->weight = 1;
|
||||
if (!current_slot->nodes->weight)
|
||||
current_slot->nodes->weight = 1;
|
||||
current_slot->nodes->wrr = 0;
|
||||
memcpy(current_slot->nodes->name, usr->address, usr->address_len);
|
||||
current_slot->nodes->last_check = uwsgi_now();
|
||||
@@ -472,7 +488,7 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
current_slot->nodes->next = NULL;
|
||||
|
||||
a_slot = slot[hash_key];
|
||||
while(a_slot) {
|
||||
while (a_slot) {
|
||||
old_slot = a_slot;
|
||||
a_slot = a_slot->next;
|
||||
}
|
||||
@@ -490,10 +506,10 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
slot[hash_key] = current_slot;
|
||||
}
|
||||
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] new pool: %.*s (hash key: %d)\n",(int) uwsgi.mypid, usr->keylen, usr->key, current_slot->hash);
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s\n",(int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address);
|
||||
return current_slot->nodes;
|
||||
}
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] new pool: %.*s (hash key: %d)\n", (int) uwsgi.mypid, usr->keylen, usr->key, current_slot->hash);
|
||||
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address);
|
||||
return current_slot->nodes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -501,18 +517,18 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
// TODO rewrite it using uwsgi buffers
|
||||
void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, uint8_t modifier1, uint8_t modifier2, uint8_t cmd, char *socket_name, char *sign) {
|
||||
|
||||
char value_cores[sizeof(UMAX64_STR)+1];
|
||||
char value_load[sizeof(UMAX64_STR)+1];
|
||||
char value_weight[sizeof(UMAX64_STR)+1];
|
||||
char value_cores[sizeof(UMAX64_STR) + 1];
|
||||
char value_load[sizeof(UMAX64_STR) + 1];
|
||||
char value_weight[sizeof(UMAX64_STR) + 1];
|
||||
|
||||
|
||||
int value_cores_size = uwsgi_long2str2n(uwsgi.numproc*uwsgi.cores, value_cores, sizeof(UMAX64_STR));
|
||||
int value_cores_size = uwsgi_long2str2n(uwsgi.numproc * uwsgi.cores, value_cores, sizeof(UMAX64_STR));
|
||||
int value_load_size = uwsgi_long2str2n(uwsgi.shared->load, value_load, sizeof(UMAX64_STR));
|
||||
|
||||
int value_weight_size = 0;
|
||||
|
||||
|
||||
if (uwsgi.auto_weight) {
|
||||
value_weight_size = uwsgi_long2str2n(uwsgi.numproc*uwsgi.cores, value_weight, sizeof(UMAX64_STR));
|
||||
value_weight_size = uwsgi_long2str2n(uwsgi.numproc * uwsgi.cores, value_weight, sizeof(UMAX64_STR));
|
||||
}
|
||||
else {
|
||||
value_weight_size = uwsgi_long2str2n(uwsgi.weight, value_weight, sizeof(UMAX64_STR));
|
||||
@@ -523,149 +539,149 @@ void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, uint8
|
||||
int value_modifier1_size = uwsgi_long2str2n(modifier1, value_modifier1, 3);
|
||||
int value_modifier2_size = uwsgi_long2str2n(modifier2, value_modifier2, 3);
|
||||
|
||||
if (socket_name == NULL && !uwsgi.sockets) return;
|
||||
if (socket_name == NULL && !uwsgi.sockets)
|
||||
return;
|
||||
|
||||
if (!socket_name) {
|
||||
socket_name = uwsgi.sockets->name;
|
||||
}
|
||||
|
||||
size_t ssb_size = 4 + (2 + 3) + (2 + keysize) + (2 + 7) + (2 + strlen(socket_name)) + (2+9 + 2+value_modifier1_size) +
|
||||
(2+9 + 2+value_modifier2_size) + (2+5 + 2+value_cores_size) + (2+4 + 2+value_load_size) + (2+6 + 2+value_weight_size);
|
||||
size_t ssb_size = 4 + (2 + 3) + (2 + keysize) + (2 + 7) + (2 + strlen(socket_name)) + (2 + 9 + 2 + value_modifier1_size) + (2 + 9 + 2 + value_modifier2_size) + (2 + 5 + 2 + value_cores_size) + (2 + 4 + 2 + value_load_size) + (2 + 6 + 2 + value_weight_size);
|
||||
|
||||
char *subscrbuf = uwsgi_malloc(ssb_size);
|
||||
char *subscrbuf = uwsgi_malloc(ssb_size);
|
||||
// leave space for uwsgi header
|
||||
char *ssb = subscrbuf+4;
|
||||
char *ssb = subscrbuf + 4;
|
||||
|
||||
// key = "domain"
|
||||
uint16_t ustrlen = 3;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "key", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
uint16_t ustrlen = 3;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "key", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = keysize;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, key, ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = keysize;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, key, ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
// address = "first uwsgi socket"
|
||||
ustrlen = 7;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "address", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 7;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "address", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = strlen(socket_name);
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, socket_name, ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = strlen(socket_name);
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, socket_name, ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
// modifier1 = "modifier1"
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "modifier1", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "modifier1", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = value_modifier1_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_modifier1, value_modifier1_size);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = value_modifier1_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, value_modifier1, value_modifier1_size);
|
||||
ssb += ustrlen;
|
||||
|
||||
// modifier2 = "modifier2"
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "modifier2", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "modifier2", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = value_modifier2_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_modifier2, value_modifier2_size);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = value_modifier2_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, value_modifier2, value_modifier2_size);
|
||||
ssb += ustrlen;
|
||||
|
||||
// cores = uwsgi.numproc * uwsgi.cores
|
||||
ustrlen = 5;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "cores", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 5;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "cores", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = value_cores_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_cores, value_cores_size);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = value_cores_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, value_cores, value_cores_size);
|
||||
ssb += ustrlen;
|
||||
|
||||
// load
|
||||
ustrlen = 4;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "load", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 4;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "load", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = value_load_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_load, value_load_size);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = value_load_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, value_load, value_load_size);
|
||||
ssb += ustrlen;
|
||||
|
||||
// weight
|
||||
ustrlen = 6;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "weight", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = 6;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "weight", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = value_weight_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, value_weight, value_weight_size);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = value_weight_size;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, value_weight, value_weight_size);
|
||||
ssb += ustrlen;
|
||||
|
||||
#ifdef UWSGI_SSL
|
||||
if (sign) {
|
||||
// add space for "unix" item
|
||||
char unix_dst[sizeof(UMAX64_STR)+1];
|
||||
if (snprintf(unix_dst, sizeof(UMAX64_STR)+1, "%lu", (unsigned long) (uwsgi_now() + (time_t)cmd)) < 1) {
|
||||
uwsgi_error("unable to generate unix time for subscription !!!\n");
|
||||
free(subscrbuf);
|
||||
return;
|
||||
}
|
||||
ssb_size += 2 + 4 + 2 + strlen(unix_dst);
|
||||
char unix_dst[sizeof(UMAX64_STR) + 1];
|
||||
if (snprintf(unix_dst, sizeof(UMAX64_STR) + 1, "%lu", (unsigned long) (uwsgi_now() + (time_t) cmd)) < 1) {
|
||||
uwsgi_error("unable to generate unix time for subscription !!!\n");
|
||||
free(subscrbuf);
|
||||
return;
|
||||
}
|
||||
ssb_size += 2 + 4 + 2 + strlen(unix_dst);
|
||||
char *new_buf = realloc(subscrbuf, ssb_size);
|
||||
if (!new_buf) {
|
||||
uwsgi_error("realloc()");
|
||||
free(subscrbuf);
|
||||
return;
|
||||
}
|
||||
uwsgi_error("realloc()");
|
||||
free(subscrbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
// fix ssb (new_buf base could be changed)
|
||||
ssb = (new_buf + (ssb-subscrbuf));
|
||||
ssb = (new_buf + (ssb - subscrbuf));
|
||||
subscrbuf = new_buf;
|
||||
|
||||
ustrlen = 4;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "unix", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "unix", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = strlen(unix_dst);
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, unix_dst, strlen(unix_dst));
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = strlen(unix_dst);
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, unix_dst, strlen(unix_dst));
|
||||
ssb+=ustrlen;
|
||||
|
||||
unsigned int signature_len = 0;
|
||||
char *signature = uwsgi_rsa_sign(sign, subscrbuf+4, ssb_size-4, &signature_len);
|
||||
char *signature = uwsgi_rsa_sign(sign, subscrbuf + 4, ssb_size - 4, &signature_len);
|
||||
if (signature && signature_len > 0) {
|
||||
// add space for "sign" item
|
||||
ssb_size += 2 + 4 + 2 + signature_len;
|
||||
char *new_buf = realloc(subscrbuf, ssb_size);
|
||||
char *new_buf = realloc(subscrbuf, ssb_size);
|
||||
if (!new_buf) {
|
||||
uwsgi_error("realloc()");
|
||||
free(signature);
|
||||
@@ -674,28 +690,28 @@ void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, uint8
|
||||
}
|
||||
|
||||
// fix ssb (new_buf base could be changed)
|
||||
ssb = (new_buf + (ssb-subscrbuf));
|
||||
ssb = (new_buf + (ssb - subscrbuf));
|
||||
subscrbuf = new_buf;
|
||||
|
||||
ustrlen = 4;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "sign", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, "sign", ustrlen);
|
||||
ssb += ustrlen;
|
||||
|
||||
ustrlen = signature_len;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, signature, signature_len);
|
||||
ssb+=ustrlen;
|
||||
ustrlen = signature_len;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ssb, signature, signature_len);
|
||||
ssb += ustrlen;
|
||||
|
||||
free(signature);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
send_udp_message(224, cmd, udp_address, subscrbuf, ssb_size-4);
|
||||
|
||||
send_udp_message(224, cmd, udp_address, subscrbuf, ssb_size - 4);
|
||||
free(subscrbuf);
|
||||
}
|
||||
|
||||
@@ -704,18 +720,18 @@ void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, uint8
|
||||
int uwsgi_subscription_sign_check(struct uwsgi_subscribe_slot *slot, struct uwsgi_subscribe_req *usr) {
|
||||
|
||||
if (EVP_VerifyInit_ex(slot->sign_ctx, uwsgi.subscriptions_sign_check_md, NULL) == 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_VerifyUpdate(slot->sign_ctx, usr->base, usr->base_len) == 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_VerifyFinal(slot->sign_ctx, (unsigned char *)usr->sign, usr->sign_len, slot->sign_public_key) != 1) {
|
||||
if (EVP_VerifyFinal(slot->sign_ctx, (unsigned char *) usr->sign, usr->sign_len, slot->sign_public_key) != 1) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
ERR_print_errors_fp(stderr);
|
||||
ERR_print_errors_fp(stderr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -727,8 +743,9 @@ int uwsgi_subscription_sign_check(struct uwsgi_subscribe_slot *slot, struct uwsg
|
||||
|
||||
int uwsgi_no_subscriptions(struct uwsgi_subscribe_slot **slot) {
|
||||
int i;
|
||||
for(i=0;i<UMAX16;i++) {
|
||||
if (slot[i]) return 0;
|
||||
for (i = 0; i < UMAX16; i++) {
|
||||
if (slot[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
+385
-278
File diff suppressed because it is too large
Load Diff
+195
-140
@@ -42,6 +42,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"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},
|
||||
{"undeferred-shared-socket", required_argument, 0, "create a shared sacket for advanced jailing or ipc (undeferred mode)", uwsgi_opt_add_shared_socket, NULL, 0},
|
||||
{"processes", required_argument, 'p', "spawn the specified number of workers/processes", uwsgi_opt_set_int, &uwsgi.numproc, 0},
|
||||
{"workers", required_argument, 'p', "spawn the specified number of workers/processes", uwsgi_opt_set_int, &uwsgi.numproc, 0},
|
||||
{"harakiri", required_argument, 't', "set harakiri timeout", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_HARAKIRI, 0},
|
||||
@@ -124,6 +125,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"map-socket", required_argument, 0, "map sockets to specific workers", uwsgi_opt_add_string_list, &uwsgi.map_socket, 0},
|
||||
#ifdef UWSGI_THREADING
|
||||
{"enable-threads", no_argument, 'T', "enable threads", uwsgi_opt_true, &uwsgi.has_threads, 0},
|
||||
{"no-threads-wait", no_argument, 0, "do not wait for threads cancellation on quit/reload", uwsgi_opt_true, &uwsgi.no_threads_wait, 0},
|
||||
#endif
|
||||
|
||||
{"auto-procname", no_argument, 0, "automatically set processes name to something meaningful", uwsgi_opt_true, &uwsgi.auto_procname, 0},
|
||||
@@ -279,6 +281,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
#ifdef MADV_MERGEABLE
|
||||
{"ksm", optional_argument, 0, "enable Linux KSM", uwsgi_opt_set_int, &uwsgi.linux_ksm, 0},
|
||||
#endif
|
||||
#endif
|
||||
#ifdef UWSGI_PCRE
|
||||
{"pcre-jit", no_argument, 0, "enable pcre jit (if available)", uwsgi_opt_pcre_jit, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
#endif
|
||||
{"never-swap", no_argument, 0, "lock all memory pages avoiding swapping", uwsgi_opt_true, &uwsgi.never_swap, 0},
|
||||
{"touch-reload", required_argument, 0, "reload uWSGI if the specified file is modified/touched", uwsgi_opt_add_string_list, &uwsgi.touch_reload, UWSGI_OPT_MASTER},
|
||||
@@ -465,7 +470,8 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"static-expires-path-info-mtime", required_argument, 0, "set the Expires header based on PATH_INFO regexp and file mtime", uwsgi_opt_add_regexp_dyn_dict, &uwsgi.static_expires_path_info_mtime, UWSGI_OPT_MIME},
|
||||
#endif
|
||||
|
||||
{"static-offload-to-thread", required_argument, 0, "offload static file serving to a thread (upto the specified number of threads)", uwsgi_opt_set_int, &uwsgi.static_offload_to_thread, UWSGI_OPT_MIME},
|
||||
{"offload-threads", required_argument, 0, "set the number of offload threads to spawn (per-worker, default 0)", uwsgi_opt_set_int, &uwsgi.offload_threads, 0},
|
||||
{"offload-thread", required_argument, 0, "set the number of offload threads to spawn (per-worker, default 0)", uwsgi_opt_set_int, &uwsgi.offload_threads, 0},
|
||||
|
||||
{"file-serve-mode", required_argument, 0, "set static file serving mode", uwsgi_opt_fileserve_mode, NULL, UWSGI_OPT_MIME},
|
||||
{"fileserve-mode", required_argument, 0, "set static file serving mode", uwsgi_opt_fileserve_mode, NULL, UWSGI_OPT_MIME},
|
||||
@@ -510,6 +516,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"remap-modifier", required_argument, 0, "remap request modifier from one id to another", uwsgi_opt_set_str, &uwsgi.remap_modifier, 0},
|
||||
|
||||
{"app", required_argument, 0, "*** deprecated ***", uwsgi_opt_deprecated, (void *) "use the more advanced \"mount\" option", 0},
|
||||
{"static-offload-to-thread", required_argument, 0, "*** deprecated ***", uwsgi_opt_deprecated, (void *) "use the more advanced \"offload-threads\" option", 0},
|
||||
|
||||
{"dump-options", no_argument, 0, "dump the full list of available options", uwsgi_opt_true, &uwsgi.dump_options, 0},
|
||||
{"show-config", no_argument, 0, "show the current config reformatted as ini", uwsgi_opt_true, &uwsgi.show_config, 0},
|
||||
@@ -669,13 +676,31 @@ restart:
|
||||
void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
|
||||
char *tmp = NULL;
|
||||
char *fullname = filename;
|
||||
|
||||
char *fullname = uwsgi_expand_path(filename, strlen(filename), NULL);
|
||||
if (!fullname) {
|
||||
fullname = filename;
|
||||
magic_table['o'] = filename;
|
||||
|
||||
if (uwsgi_check_scheme(filename) || !strcmp(filename, "-")) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *section = uwsgi_get_last_char(filename, ':');
|
||||
if (section) {
|
||||
*section = 0;
|
||||
}
|
||||
|
||||
// we have a special case for symlinks
|
||||
if (uwsgi_is_link(filename)) {
|
||||
if (filename[0] != '/') {
|
||||
fullname = uwsgi_concat3(uwsgi.cwd, "/", filename);
|
||||
}
|
||||
}
|
||||
// free unused memory
|
||||
else {
|
||||
|
||||
fullname = uwsgi_expand_path(filename, strlen(filename), NULL);
|
||||
if (!fullname) {
|
||||
exit(1);
|
||||
}
|
||||
char *minimal_name = uwsgi_malloc(strlen(fullname) + 1);
|
||||
memcpy(minimal_name, fullname, strlen(fullname));
|
||||
minimal_name[strlen(fullname)] = 0;
|
||||
@@ -683,7 +708,6 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
fullname = minimal_name;
|
||||
}
|
||||
|
||||
magic_table['o'] = filename;
|
||||
magic_table['p'] = fullname;
|
||||
magic_table['s'] = uwsgi_get_last_char(fullname, '/') + 1;
|
||||
magic_table['d'] = uwsgi_concat2n(magic_table['p'], magic_table['s'] - magic_table['p'], "", 0);
|
||||
@@ -703,8 +727,8 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
|
||||
int base = '0';
|
||||
char *to_split = uwsgi_str(magic_table['d']);
|
||||
char *p = strtok(to_split,"/");
|
||||
while(p && base <= '9') {
|
||||
char *p = strtok(to_split, "/");
|
||||
while (p && base <= '9') {
|
||||
magic_table[base] = p;
|
||||
base++;
|
||||
p = strtok(NULL, "/");
|
||||
@@ -717,6 +741,11 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
magic_table['e'] = uwsgi_get_last_char(filename, '.') + 1;
|
||||
if (uwsgi_get_last_char(magic_table['s'], '.'))
|
||||
magic_table['n'] = uwsgi_concat2n(magic_table['s'], uwsgi_get_last_char(magic_table['s'], '.') - magic_table['s'], "", 0);
|
||||
|
||||
if (section) {
|
||||
magic_table['x'] = section+1;
|
||||
*section = ':';
|
||||
}
|
||||
}
|
||||
|
||||
int find_worker_id(pid_t pid) {
|
||||
@@ -746,6 +775,9 @@ void warn_pipe() {
|
||||
void wait_for_threads() {
|
||||
int i, ret;
|
||||
|
||||
// on some platform thread cancellation is REALLY flaky
|
||||
if (uwsgi.no_threads_wait) return;
|
||||
|
||||
int sudden_death = 0;
|
||||
|
||||
pthread_mutex_lock(&uwsgi.six_feet_under_lock);
|
||||
@@ -853,13 +885,13 @@ void kill_them_all(int signum) {
|
||||
return;
|
||||
|
||||
// count the number of active workers
|
||||
int active_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
uwsgi.marked_workers = active_workers;
|
||||
int active_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
uwsgi.marked_workers = active_workers;
|
||||
|
||||
uwsgi.to_hell = 1;
|
||||
|
||||
@@ -919,13 +951,13 @@ void grace_them_all(int signum) {
|
||||
return;
|
||||
|
||||
// count the number of active workers
|
||||
int active_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
uwsgi.marked_workers = active_workers;
|
||||
int active_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
uwsgi.marked_workers = active_workers;
|
||||
|
||||
if (!uwsgi.lazy)
|
||||
uwsgi.to_heaven = 1;
|
||||
@@ -1031,14 +1063,17 @@ void reap_them_all(int signum) {
|
||||
if (uwsgi.to_outworld == 1 || uwsgi.lazy_respawned > 0)
|
||||
return;
|
||||
|
||||
|
||||
if (!uwsgi.workers) return;
|
||||
|
||||
// count the number of active workers
|
||||
int active_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
uwsgi.marked_workers = active_workers;
|
||||
int active_workers = 0;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
uwsgi.marked_workers = active_workers;
|
||||
|
||||
if (!uwsgi.lazy)
|
||||
uwsgi.to_heaven = 1;
|
||||
@@ -1482,7 +1517,7 @@ void uwsgi_flush_logs() {
|
||||
check:
|
||||
// this buffer could not be initialized !!!
|
||||
if (uwsgi.log_master) {
|
||||
uwsgi.log_master_buf = uwsgi_malloc(uwsgi.log_master_bufsize);
|
||||
uwsgi.log_master_buf = uwsgi_malloc(uwsgi.log_master_bufsize);
|
||||
}
|
||||
|
||||
// check for data in logpipe
|
||||
@@ -1501,13 +1536,14 @@ check:
|
||||
static void plugins_list(void) {
|
||||
int i;
|
||||
uwsgi_log("\n*** uWSGI loaded generic plugins ***\n");
|
||||
for(i=0;i<uwsgi.gp_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
uwsgi_log("%s\n", uwsgi.gp[i]->name);
|
||||
}
|
||||
|
||||
uwsgi_log("\n*** uWSGI loaded request plugins ***\n");
|
||||
for(i=0;i<256;i++) {
|
||||
if (uwsgi.p[i] == &unconfigured_plugin) continue;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i] == &unconfigured_plugin)
|
||||
continue;
|
||||
uwsgi_log("%d: %s\n", i, uwsgi.p[i]->name);
|
||||
}
|
||||
|
||||
@@ -1517,39 +1553,39 @@ static void plugins_list(void) {
|
||||
static void loggers_list(void) {
|
||||
struct uwsgi_logger *ul = uwsgi.loggers;
|
||||
uwsgi_log("\n*** uWSGI loaded loggers ***\n");
|
||||
while(ul) {
|
||||
while (ul) {
|
||||
uwsgi_log("%s\n", ul->name);
|
||||
ul = ul->next;
|
||||
}
|
||||
}
|
||||
uwsgi_log("--- end of loggers list ---\n\n");
|
||||
}
|
||||
|
||||
static void cheaper_algo_list(void) {
|
||||
struct uwsgi_cheaper_algo *uca = uwsgi.cheaper_algos;
|
||||
uwsgi_log("\n*** uWSGI loaded cheaper algorithms ***\n");
|
||||
while(uca) {
|
||||
while (uca) {
|
||||
uwsgi_log("%s\n", uca->name);
|
||||
uca = uca->next;
|
||||
}
|
||||
}
|
||||
uwsgi_log("--- end of cheaper algorithms list ---\n\n");
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ROUTING
|
||||
static void router_list(void) {
|
||||
struct uwsgi_router *ur = uwsgi.routers;
|
||||
uwsgi_log("\n*** uWSGI loaded routers ***\n");
|
||||
while(ur) {
|
||||
uwsgi_log("%s\n", ur->name);
|
||||
ur = ur->next;
|
||||
}
|
||||
uwsgi_log("--- end of routers list ---\n\n");
|
||||
struct uwsgi_router *ur = uwsgi.routers;
|
||||
uwsgi_log("\n*** uWSGI loaded routers ***\n");
|
||||
while (ur) {
|
||||
uwsgi_log("%s\n", ur->name);
|
||||
ur = ur->next;
|
||||
}
|
||||
uwsgi_log("--- end of routers list ---\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void loop_list(void) {
|
||||
struct uwsgi_loop *loop = uwsgi.loops;
|
||||
uwsgi_log("\n*** uWSGI loaded loop engines ***\n");
|
||||
while(loop) {
|
||||
while (loop) {
|
||||
uwsgi_log("%s\n", loop->name);
|
||||
loop = loop->next;
|
||||
}
|
||||
@@ -1559,9 +1595,9 @@ static void loop_list(void) {
|
||||
static void imperial_monitor_list(void) {
|
||||
struct uwsgi_imperial_monitor *uim = uwsgi.emperor_monitors;
|
||||
uwsgi_log("\n*** uWSGI loaded imperial monitors ***\n");
|
||||
while(uim) {
|
||||
while (uim) {
|
||||
uwsgi_log("%s\n", uim->scheme);
|
||||
uim = uim->next;
|
||||
uim = uim->next;
|
||||
}
|
||||
uwsgi_log("--- end of imperial monitors list ---\n\n");
|
||||
}
|
||||
@@ -1569,7 +1605,7 @@ static void imperial_monitor_list(void) {
|
||||
static void clocks_list(void) {
|
||||
struct uwsgi_clock *clocks = uwsgi.clocks;
|
||||
uwsgi_log("\n*** uWSGI loaded clocks ***\n");
|
||||
while(clocks) {
|
||||
while (clocks) {
|
||||
uwsgi_log("%s\n", clocks->name);
|
||||
clocks = clocks->next;
|
||||
}
|
||||
@@ -1578,13 +1614,13 @@ static void clocks_list(void) {
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
static void alarms_list(void) {
|
||||
struct uwsgi_alarm *alarms = uwsgi.alarms;
|
||||
uwsgi_log("\n*** uWSGI loaded alarms ***\n");
|
||||
while(alarms) {
|
||||
uwsgi_log("%s\n", alarms->name);
|
||||
alarms = alarms->next;
|
||||
}
|
||||
uwsgi_log("--- end of alarms list ---\n\n");
|
||||
struct uwsgi_alarm *alarms = uwsgi.alarms;
|
||||
uwsgi_log("\n*** uWSGI loaded alarms ***\n");
|
||||
while (alarms) {
|
||||
uwsgi_log("%s\n", alarms->name);
|
||||
alarms = alarms->next;
|
||||
}
|
||||
uwsgi_log("--- end of alarms list ---\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1595,7 +1631,7 @@ static time_t uwsgi_unix_seconds() {
|
||||
static uint64_t uwsgi_unix_microseconds() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return ((uint64_t)tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
return ((uint64_t) tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
}
|
||||
|
||||
static struct uwsgi_clock uwsgi_unix_clock = {
|
||||
@@ -1706,7 +1742,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// count/set the current reload status
|
||||
uwsgi_setup_reload();
|
||||
|
||||
@@ -1728,11 +1764,10 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
//initialize embedded plugins
|
||||
UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
|
||||
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
|
||||
// try to automatically load a plugin
|
||||
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
|
||||
// try to automatically load a plugin
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("executable name: %s\n", uwsgi.binary_path);
|
||||
uwsgi_log("executable name: %s\n", uwsgi.binary_path);
|
||||
#endif
|
||||
uwsgi_autoload_plugins_by_name(argv[0]);
|
||||
|
||||
@@ -1796,16 +1831,16 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
// setup main loops
|
||||
uwsgi_register_loop("simple", simple_loop);
|
||||
#ifdef UWSGI_ASYNC
|
||||
uwsgi_register_loop("async", async_loop);
|
||||
uwsgi_register_loop("async", async_loop);
|
||||
#endif
|
||||
|
||||
// setup cheaper algos
|
||||
uwsgi_register_cheaper_algo("spare", uwsgi_cheaper_algo_spare);
|
||||
uwsgi_register_cheaper_algo("backlog", uwsgi_cheaper_algo_backlog);
|
||||
uwsgi_register_cheaper_algo("spare", uwsgi_cheaper_algo_spare);
|
||||
uwsgi_register_cheaper_algo("backlog", uwsgi_cheaper_algo_backlog);
|
||||
|
||||
// setup imperial monitors
|
||||
uwsgi_register_imperial_monitor("dir", uwsgi_imperial_monitor_directory_init, uwsgi_imperial_monitor_directory);
|
||||
uwsgi_register_imperial_monitor("glob", uwsgi_imperial_monitor_glob_init, uwsgi_imperial_monitor_glob);
|
||||
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);
|
||||
@@ -1884,19 +1919,27 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi_log_initial("compiled with version: %s on %s\n", __VERSION__, UWSGI_BUILD_DATE);
|
||||
|
||||
#ifdef __sun__
|
||||
if (uname(&uuts) < 0) {
|
||||
if (uname(&uuts) < 0) {
|
||||
#else
|
||||
if (uname(&uuts)) {
|
||||
if (uname(&uuts)) {
|
||||
#endif
|
||||
uwsgi_error("uname()");
|
||||
}
|
||||
else {
|
||||
uwsgi_log_initial("os: %s-%s %s\n", uuts.sysname, uuts.release, uuts.version);
|
||||
uwsgi_log_initial("nodename: %s\n", uuts.nodename);
|
||||
uwsgi_log_initial("machine: %s\n", uuts.machine);
|
||||
}
|
||||
uwsgi_error("uname()");
|
||||
}
|
||||
else {
|
||||
uwsgi_log_initial("os: %s-%s %s\n", uuts.sysname, uuts.release, uuts.version);
|
||||
uwsgi_log_initial("nodename: %s\n", uuts.nodename);
|
||||
uwsgi_log_initial("machine: %s\n", uuts.machine);
|
||||
}
|
||||
|
||||
uwsgi_log_initial("clock source: %s\n", uwsgi.clock->name);
|
||||
#ifdef UWSGI_PCRE
|
||||
if (uwsgi.pcre_jit) {
|
||||
uwsgi_log_initial("pcre jit enabled\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log_initial("pcre jit disabled\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi_log_initial("*** big endian arch detected ***\n");
|
||||
@@ -1951,16 +1994,16 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
|
||||
// we could now patch the binary
|
||||
if (uwsgi.privileged_binary_patch) {
|
||||
uwsgi.argv[0] = uwsgi.privileged_binary_patch;
|
||||
execvp(uwsgi.privileged_binary_patch, uwsgi.argv);
|
||||
uwsgi_error("execvp()");
|
||||
exit(1);
|
||||
}
|
||||
if (uwsgi.privileged_binary_patch) {
|
||||
uwsgi.argv[0] = uwsgi.privileged_binary_patch;
|
||||
execvp(uwsgi.privileged_binary_patch, uwsgi.argv);
|
||||
uwsgi_error("execvp()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.privileged_binary_patch_arg) {
|
||||
if (uwsgi.privileged_binary_patch_arg) {
|
||||
uwsgi_exec_command_with_args(uwsgi.privileged_binary_patch_arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// call jail systems
|
||||
@@ -2029,17 +2072,17 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
if (uwsgi.rl_nproc.rlim_max > 0) {
|
||||
uwsgi.rl_nproc.rlim_cur = uwsgi.rl_nproc.rlim_max;
|
||||
uwsgi_log_initial("limiting number of processes to %d...\n", (int) uwsgi.rl_nproc.rlim_max);
|
||||
if (setrlimit(RLIMIT_NPROC, &uwsgi.rl_nproc)) {
|
||||
uwsgi_error("setrlimit()");
|
||||
}
|
||||
}
|
||||
uwsgi.rl_nproc.rlim_cur = uwsgi.rl_nproc.rlim_max;
|
||||
uwsgi_log_initial("limiting number of processes to %d...\n", (int) uwsgi.rl_nproc.rlim_max);
|
||||
if (setrlimit(RLIMIT_NPROC, &uwsgi.rl_nproc)) {
|
||||
uwsgi_error("setrlimit()");
|
||||
}
|
||||
}
|
||||
|
||||
if (!getrlimit(RLIMIT_NPROC, &uwsgi.rl_nproc)) {
|
||||
if (uwsgi.rl_nproc.rlim_cur != RLIM_INFINITY) {
|
||||
uwsgi_log_initial("your processes number limit is %d\n", (int) uwsgi.rl_nproc.rlim_cur);
|
||||
if ((int)uwsgi.rl_nproc.rlim_cur < uwsgi.numproc+uwsgi.master_process) {
|
||||
if ((int) uwsgi.rl_nproc.rlim_cur < uwsgi.numproc + uwsgi.master_process) {
|
||||
uwsgi.numproc = uwsgi.rl_nproc.rlim_cur - 1;
|
||||
uwsgi_log_initial("!!! number of workers adjusted to %d due to system limits !!!\n", uwsgi.numproc);
|
||||
}
|
||||
@@ -2130,15 +2173,15 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi.rl.rlim_cur = uwsgi.async;
|
||||
uwsgi.rl.rlim_max = uwsgi.async;
|
||||
if (!setrlimit(RLIMIT_NOFILE, &uwsgi.rl)) {
|
||||
uwsgi_log("max open files limit raised to %lu\n", (unsigned long) uwsgi.rl.rlim_cur);
|
||||
uwsgi.async = uwsgi.rl.rlim_cur;
|
||||
uwsgi_log("max open files limit raised to %lu\n", (unsigned long) uwsgi.rl.rlim_cur);
|
||||
uwsgi.async = uwsgi.rl.rlim_cur;
|
||||
uwsgi.max_fd = uwsgi.rl.rlim_cur;
|
||||
}
|
||||
else {
|
||||
uwsgi.async = (int) uwsgi.max_fd;
|
||||
}
|
||||
}
|
||||
uwsgi_log("- async cores set to %d - fd table size: %d\n", uwsgi.async, (int) uwsgi.max_fd);
|
||||
}
|
||||
else {
|
||||
uwsgi.async = (int) uwsgi.max_fd;
|
||||
}
|
||||
}
|
||||
uwsgi_log("- async cores set to %d - fd table size: %d\n", uwsgi.async, (int) uwsgi.max_fd);
|
||||
uwsgi.async_waiting_fd_table = malloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
|
||||
if (!uwsgi.async_waiting_fd_table) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -2279,7 +2322,8 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
// users of the --loop option should know what they are doing... really...
|
||||
#ifndef UWSGI_DEBUG
|
||||
if (uwsgi.loop) goto unsafe;
|
||||
if (uwsgi.loop)
|
||||
goto unsafe;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
@@ -2414,25 +2458,26 @@ unsafe:
|
||||
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);
|
||||
uwsgi.logvectors[j][uwsgi.logformat_vectors-1].iov_base = "\n";
|
||||
uwsgi.logvectors[j][uwsgi.logformat_vectors-1].iov_len = 1;
|
||||
uwsgi.logvectors[j][uwsgi.logformat_vectors - 1].iov_base = "\n";
|
||||
uwsgi.logvectors[j][uwsgi.logformat_vectors - 1].iov_len = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
// initialize locks and socket as soon as possibile, as the master could enqueue tasks
|
||||
if (uwsgi.spoolers != NULL && (uwsgi.sockets || uwsgi.loop)) {
|
||||
create_signal_pipe(uwsgi.shared->spooler_signal_pipe);
|
||||
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
||||
while (uspool) {
|
||||
// lock is required even in EXTERNAL mode
|
||||
uspool->lock = uwsgi_lock_init(uwsgi_concat2("spooler on ", uspool->dir));
|
||||
if (uspool->mode == UWSGI_SPOOLER_EXTERNAL) goto next;
|
||||
create_signal_pipe(uspool->signal_pipe);
|
||||
if (uwsgi.spoolers != NULL && (uwsgi.sockets || uwsgi.loop)) {
|
||||
create_signal_pipe(uwsgi.shared->spooler_signal_pipe);
|
||||
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
||||
while (uspool) {
|
||||
// lock is required even in EXTERNAL mode
|
||||
uspool->lock = uwsgi_lock_init(uwsgi_concat2("spooler on ", uspool->dir));
|
||||
if (uspool->mode == UWSGI_SPOOLER_EXTERNAL)
|
||||
goto next;
|
||||
create_signal_pipe(uspool->signal_pipe);
|
||||
next:
|
||||
uspool = uspool->next;
|
||||
}
|
||||
}
|
||||
uspool = uspool->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2455,17 +2500,17 @@ next:
|
||||
}
|
||||
|
||||
// postinit apps (setup specific features after app initialization)
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->postinit_apps) {
|
||||
uwsgi.p[i]->postinit_apps();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (uwsgi.p[i]->postinit_apps) {
|
||||
uwsgi.p[i]->postinit_apps();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->postinit_apps) {
|
||||
uwsgi.gp[i]->postinit_apps();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->postinit_apps) {
|
||||
uwsgi.gp[i]->postinit_apps();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.daemonize2) {
|
||||
@@ -2550,7 +2595,8 @@ next:
|
||||
if (uwsgi.spoolers != NULL && (uwsgi.sockets || uwsgi.loop)) {
|
||||
struct uwsgi_spooler *uspool = uwsgi.spoolers;
|
||||
while (uspool) {
|
||||
if (uspool->mode == UWSGI_SPOOLER_EXTERNAL) goto next2;
|
||||
if (uspool->mode == UWSGI_SPOOLER_EXTERNAL)
|
||||
goto next2;
|
||||
uspool->pid = spooler_start(uspool);
|
||||
next2:
|
||||
uspool = uspool->next;
|
||||
@@ -2587,7 +2633,8 @@ next2:
|
||||
if (!uwsgi.cheap) {
|
||||
if (uwsgi.cheaper && uwsgi.cheaper_count) {
|
||||
int nproc = uwsgi.cheaper_initial;
|
||||
if (!nproc) nproc = uwsgi.cheaper_count;
|
||||
if (!nproc)
|
||||
nproc = uwsgi.cheaper_count;
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (i <= nproc) {
|
||||
if (uwsgi_respawn_worker(i))
|
||||
@@ -2656,16 +2703,21 @@ next2:
|
||||
if (uwsgi.master_as_root) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
|
||||
|
||||
// set default wsgi_req (for loading apps);
|
||||
uwsgi.wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[0].req;
|
||||
|
||||
if (uwsgi.static_offload_to_thread) {
|
||||
uwsgi.offload_thread = uwsgi_offload_thread_start();
|
||||
if (!uwsgi.offload_thread) {
|
||||
uwsgi_log("unable to offload static file serving !!!\n");
|
||||
uwsgi.static_offload_to_thread = 0;
|
||||
if (uwsgi.offload_threads > 0) {
|
||||
uwsgi.offload_thread = uwsgi_malloc(sizeof(struct uwsgi_thread *) * uwsgi.offload_threads);
|
||||
for(i=0;i<uwsgi.offload_threads;i++) {
|
||||
uwsgi.offload_thread[i] = uwsgi_offload_thread_start();
|
||||
if (!uwsgi.offload_thread[i]) {
|
||||
uwsgi_log("unable to start offload thread %d for worker %d !!!\n", i, uwsgi.mywid);
|
||||
uwsgi.offload_threads = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
uwsgi_log("spawned %d offload threads for uWSGI worker %d\n", uwsgi.offload_threads, uwsgi.mywid);
|
||||
}
|
||||
|
||||
// must be run before running apps
|
||||
@@ -2801,10 +2853,10 @@ wait_for_call_of_duty:
|
||||
#ifdef UWSGI_THREADING
|
||||
// create a pthread key, storing per-thread wsgi_request structure
|
||||
if (uwsgi.threads > 1) {
|
||||
if (pthread_key_create(&uwsgi.tur_key, NULL)) {
|
||||
uwsgi_error("pthread_key_create()");
|
||||
exit(1);
|
||||
}
|
||||
if (pthread_key_create(&uwsgi.tur_key, NULL)) {
|
||||
uwsgi_error("pthread_key_create()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3065,7 +3117,7 @@ void uwsgi_init_all_apps() {
|
||||
}
|
||||
|
||||
struct uwsgi_string_list *app_mps = uwsgi.mounts;
|
||||
while(app_mps) {
|
||||
while (app_mps) {
|
||||
char *what = strchr(app_mps->value, '=');
|
||||
if (what) {
|
||||
what[0] = 0;
|
||||
@@ -3254,14 +3306,17 @@ void uwsgi_opt_add_regexp_custom_list(char *opt, char *value, void *list) {
|
||||
uwsgi_log("invalid custom regexp syntax: must be <custom> <regexp>\n");
|
||||
exit(1);
|
||||
}
|
||||
char *custom = uwsgi_concat2n(value, space-value, "", 0);
|
||||
char *custom = uwsgi_concat2n(value, space - value, "", 0);
|
||||
struct uwsgi_regexp_list **ptr = (struct uwsgi_regexp_list **) list;
|
||||
uwsgi_regexp_custom_new_list(ptr, space+1, custom);
|
||||
uwsgi_regexp_custom_new_list(ptr, space + 1, custom);
|
||||
}
|
||||
#endif
|
||||
|
||||
void uwsgi_opt_add_shared_socket(char *opt, char *value, void *protocol) {
|
||||
uwsgi_new_shared_socket(generate_socket_name(value));
|
||||
struct uwsgi_socket *us = uwsgi_new_shared_socket(generate_socket_name(value));
|
||||
if (!strcmp(opt, "undeferred-shared-socket")) {
|
||||
us->no_defer = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_socket(char *opt, char *value, void *protocol) {
|
||||
@@ -3271,8 +3326,8 @@ void uwsgi_opt_add_socket(char *opt, char *value, void *protocol) {
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_lazy_socket(char *opt, char *value, void *protocol) {
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi_new_socket(generate_socket_name(value));
|
||||
uwsgi_sock->proto_name = protocol;
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi_new_socket(generate_socket_name(value));
|
||||
uwsgi_sock->proto_name = protocol;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_sock->lazy = 1;
|
||||
}
|
||||
@@ -3400,7 +3455,7 @@ void uwsgi_opt_pidfile_signal(char *opt, char *pidfile, void *sig) {
|
||||
|
||||
void uwsgi_opt_load_dl(char *opt, char *value, void *none) {
|
||||
if (!dlopen(value, RTLD_NOW | RTLD_GLOBAL)) {
|
||||
uwsgi_log( "%s\n", dlerror());
|
||||
uwsgi_log("%s\n", dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+115
-107
@@ -36,22 +36,22 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, char *magic
|
||||
uwsgi_log("invalid xml id\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log( "[uWSGI] using xml uwsgi id: %s\n", colon);
|
||||
uwsgi_log("[uWSGI] using xml uwsgi id: %s\n", colon);
|
||||
}
|
||||
|
||||
xml_content = uwsgi_open_and_read(filename, &xml_size, 0, magic_table);
|
||||
|
||||
doc = xmlReadMemory(xml_content, xml_size, filename, NULL, 0);
|
||||
if (doc == NULL) {
|
||||
uwsgi_log( "[uWSGI] could not parse file %s.\n", filename);
|
||||
uwsgi_log("[uWSGI] could not parse file %s.\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log( "[uWSGI] parsing config file %s\n", filename);
|
||||
uwsgi_log("[uWSGI] parsing config file %s\n", filename);
|
||||
|
||||
element = xmlDocGetRootElement(doc);
|
||||
if (element == NULL) {
|
||||
uwsgi_log( "[uWSGI] invalid xml config file.\n");
|
||||
uwsgi_log("[uWSGI] invalid xml config file.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (strcmp((char *) element->name, "uwsgi")) {
|
||||
@@ -62,7 +62,7 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, char *magic
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
|
||||
if (colon && xml_id) {
|
||||
if ( strcmp(colon, xml_id) ) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -73,82 +73,82 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, char *magic
|
||||
}
|
||||
|
||||
if (!element) {
|
||||
uwsgi_log( "[uWSGI] invalid xml root element, <uwsgi> expected.\n");
|
||||
uwsgi_log("[uWSGI] invalid xml root element, <uwsgi> expected.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// first check for options
|
||||
for (node = element->children; node; node = node->next) {
|
||||
// first check for options
|
||||
for (node = element->children; node; node = node->next) {
|
||||
|
||||
node_mode = xmlGetProp(node, (const xmlChar *) "mode");
|
||||
if (uwsgi.mode && node_mode) {
|
||||
if (strcmp(uwsgi.mode, (char *) node_mode)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
if (colon && xml_id) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (node->type == XML_CDATA_SECTION_NODE) {
|
||||
if (node->content) {
|
||||
add_exported_option((char *) "eval", strdup((char *) node->content), 0);
|
||||
}
|
||||
}
|
||||
else if (node->type == XML_ELEMENT_NODE) {
|
||||
|
||||
if (!strcmp((char *) node->name, (char *) "app")) {
|
||||
|
||||
char *mountpoint = (char *) xmlGetProp(node, (const xmlChar *) "mountpoint");
|
||||
char *domain = (char *) xmlGetProp(node, (const xmlChar *) "domain");
|
||||
|
||||
if (!node->children) {
|
||||
add_exported_option("app", strdup(""), 0);
|
||||
}
|
||||
else if (node->children && node->children->content && !node->children->next) {
|
||||
char *opt_value = strdup((char *) node->children->content);
|
||||
|
||||
if (mountpoint) {
|
||||
opt_value = uwsgi_concat3(mountpoint,"=", opt_value);
|
||||
}
|
||||
else if (domain) {
|
||||
opt_value = uwsgi_concat3(domain,"|=", opt_value);
|
||||
}
|
||||
add_exported_option("mount", opt_value, 0);
|
||||
add_exported_option("app", strdup(""), 0);
|
||||
}
|
||||
else if (node->children && node->children->next && node->children->next->children && node->children->next->children->content) {
|
||||
|
||||
char *opt_value = strdup((char *) node->children->next->children->content);
|
||||
|
||||
if (mountpoint) {
|
||||
opt_value = uwsgi_concat3(mountpoint,"=", opt_value);
|
||||
}
|
||||
else if (domain) {
|
||||
opt_value = uwsgi_concat3(domain,"|=", opt_value);
|
||||
}
|
||||
|
||||
add_exported_option("mount", opt_value, 0);
|
||||
add_exported_option("app", strdup(""), 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (node->children) {
|
||||
add_exported_option(strdup((char *) node->name), strdup((char *) node->children->content), 0);
|
||||
}
|
||||
else {
|
||||
add_exported_option(strdup((char *) node->name), strdup("1"), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
node_mode = xmlGetProp(node, (const xmlChar *) "mode");
|
||||
if (uwsgi.mode && node_mode) {
|
||||
if (strcmp(uwsgi.mode, (char *) node_mode)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
if (colon && xml_id) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (node->type == XML_CDATA_SECTION_NODE) {
|
||||
if (node->content) {
|
||||
add_exported_option((char *) "eval", strdup((char *) node->content), 0);
|
||||
}
|
||||
}
|
||||
else if (node->type == XML_ELEMENT_NODE) {
|
||||
|
||||
if (!strcmp((char *) node->name, (char *) "app")) {
|
||||
|
||||
char *mountpoint = (char *) xmlGetProp(node, (const xmlChar *) "mountpoint");
|
||||
char *domain = (char *) xmlGetProp(node, (const xmlChar *) "domain");
|
||||
|
||||
if (!node->children) {
|
||||
add_exported_option("app", strdup(""), 0);
|
||||
}
|
||||
else if (node->children && node->children->content && !node->children->next) {
|
||||
char *opt_value = strdup((char *) node->children->content);
|
||||
|
||||
if (mountpoint) {
|
||||
opt_value = uwsgi_concat3(mountpoint, "=", opt_value);
|
||||
}
|
||||
else if (domain) {
|
||||
opt_value = uwsgi_concat3(domain, "|=", opt_value);
|
||||
}
|
||||
add_exported_option("mount", opt_value, 0);
|
||||
add_exported_option("app", strdup(""), 0);
|
||||
}
|
||||
else if (node->children && node->children->next && node->children->next->children && node->children->next->children->content) {
|
||||
|
||||
char *opt_value = strdup((char *) node->children->next->children->content);
|
||||
|
||||
if (mountpoint) {
|
||||
opt_value = uwsgi_concat3(mountpoint, "=", opt_value);
|
||||
}
|
||||
else if (domain) {
|
||||
opt_value = uwsgi_concat3(domain, "|=", opt_value);
|
||||
}
|
||||
|
||||
add_exported_option("mount", opt_value, 0);
|
||||
add_exported_option("app", strdup(""), 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (node->children) {
|
||||
add_exported_option(strdup((char *) node->name), strdup((char *) node->children->content), 0);
|
||||
}
|
||||
else {
|
||||
add_exported_option(strdup((char *) node->name), strdup("1"), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We can safely free resources */
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
@@ -166,17 +166,22 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, char *magic
|
||||
int uwsgi_xml_found_stanza = 0;
|
||||
char *uwsgi_xml_found_opt_key = NULL;
|
||||
|
||||
static void startElement(void *xml_id, const XML_Char *name, const XML_Char **attrs) {
|
||||
static void startElement(void *xml_id, const XML_Char * name, const XML_Char ** attrs) {
|
||||
|
||||
|
||||
if (!uwsgi_xml_found_stanza) {
|
||||
if (xml_id) {
|
||||
if (!attrs[0]) return;
|
||||
if (!attrs[1]) return;
|
||||
if (strcmp("id", attrs[0])) return;
|
||||
if (strcmp((char *)xml_id, attrs[1])) return;
|
||||
if (!attrs[0])
|
||||
return;
|
||||
if (!attrs[1])
|
||||
return;
|
||||
if (strcmp("id", attrs[0]))
|
||||
return;
|
||||
if (strcmp((char *) xml_id, attrs[1]))
|
||||
return;
|
||||
}
|
||||
if (!strcmp("uwsgi", name)) uwsgi_xml_found_stanza = 1;
|
||||
if (!strcmp("uwsgi", name))
|
||||
uwsgi_xml_found_stanza = 1;
|
||||
}
|
||||
else {
|
||||
uwsgi_xml_found_opt_key = (char *) name;
|
||||
@@ -186,23 +191,26 @@ static void startElement(void *xml_id, const XML_Char *name, const XML_Char **at
|
||||
|
||||
static void textElement(void *xml_id, const char *s, int len) {
|
||||
|
||||
if (!uwsgi_xml_found_stanza) return ;
|
||||
if (!uwsgi_xml_found_stanza)
|
||||
return;
|
||||
if (uwsgi_xml_found_opt_key) {
|
||||
add_exported_option(strdup(uwsgi_xml_found_opt_key), uwsgi_concat2n((char *)s, len, (char *)"", 0), 0);
|
||||
add_exported_option(strdup(uwsgi_xml_found_opt_key), uwsgi_concat2n((char *) s, len, (char *) "", 0), 0);
|
||||
uwsgi_xml_found_opt_key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void endElement(void *xml_id, const XML_Char *name) {
|
||||
static void endElement(void *xml_id, const XML_Char * name) {
|
||||
|
||||
if (!uwsgi_xml_found_stanza) return ;
|
||||
if (!uwsgi_xml_found_stanza)
|
||||
return;
|
||||
|
||||
if (!strcmp(name, "uwsgi")) {
|
||||
uwsgi_xml_found_stanza = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uwsgi_xml_found_opt_key) return;
|
||||
if (!uwsgi_xml_found_opt_key)
|
||||
return;
|
||||
|
||||
add_exported_option(strdup(uwsgi_xml_found_opt_key), strdup("1"), 0);
|
||||
uwsgi_xml_found_opt_key = NULL;
|
||||
@@ -212,30 +220,30 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, char *magic
|
||||
|
||||
char *colon;
|
||||
|
||||
char *xml_content;
|
||||
int xml_size = 0;
|
||||
char *xml_content;
|
||||
int xml_size = 0;
|
||||
int done = 0;
|
||||
|
||||
if (uwsgi_check_scheme(filename)) {
|
||||
colon = uwsgi_get_last_char(filename, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(filename, ':');
|
||||
}
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
colon++;
|
||||
if (*colon == 0) {
|
||||
uwsgi_log("invalid xml id\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log( "[uWSGI] using xml uwsgi id: %s\n", colon);
|
||||
}
|
||||
if (uwsgi_check_scheme(filename)) {
|
||||
colon = uwsgi_get_last_char(filename, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(filename, ':');
|
||||
}
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
colon++;
|
||||
if (*colon == 0) {
|
||||
uwsgi_log("invalid xml id\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("[uWSGI] using xml uwsgi id: %s\n", colon);
|
||||
}
|
||||
|
||||
xml_content = uwsgi_open_and_read(filename, &xml_size, 0, magic_table);
|
||||
xml_content = uwsgi_open_and_read(filename, &xml_size, 0, magic_table);
|
||||
|
||||
uwsgi_log( "[uWSGI] parsing config file %s\n", filename);
|
||||
uwsgi_log("[uWSGI] parsing config file %s\n", filename);
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
XML_SetUserData(parser, NULL);
|
||||
@@ -257,9 +265,9 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, char *magic
|
||||
}
|
||||
}
|
||||
|
||||
} while(!done);
|
||||
} while (!done);
|
||||
|
||||
|
||||
|
||||
// we can safely free, as we have a copy of datas
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
|
||||
+98
-92
@@ -15,7 +15,7 @@ void yaml_rstrip(char *line) {
|
||||
|
||||
off_t i;
|
||||
|
||||
for(i = strlen(line)-1;i>=0; i--) {
|
||||
for (i = strlen(line) - 1; i >= 0; i--) {
|
||||
if (line[i] == ' ' || line[i] == '\t') {
|
||||
line[i] = 0;
|
||||
continue;
|
||||
@@ -26,18 +26,18 @@ void yaml_rstrip(char *line) {
|
||||
|
||||
char *yaml_lstrip(char *line) {
|
||||
|
||||
off_t i;
|
||||
char *ptr = line;
|
||||
off_t i;
|
||||
char *ptr = line;
|
||||
|
||||
for(i=0;i< (int) strlen(line);i++) {
|
||||
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < (int) strlen(line); i++) {
|
||||
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,13 +46,13 @@ int yaml_get_depth(char *line) {
|
||||
off_t i;
|
||||
int depth = 0;
|
||||
|
||||
for(i=0;i< (int) strlen(line);i++) {
|
||||
for (i = 0; i < (int) strlen(line); i++) {
|
||||
if (line[i] == ' ') {
|
||||
depth++;
|
||||
continue;
|
||||
}
|
||||
else if (line[i] == '\t' || line[i] == '\r') {
|
||||
depth+=8;
|
||||
depth += 8;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -67,11 +67,11 @@ char *yaml_get_line(char *yaml, off_t size) {
|
||||
char *ptr = yaml;
|
||||
int comment = 0;
|
||||
|
||||
for(i=0;i<size;i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
ptr++;
|
||||
if (yaml[i] == '#') {
|
||||
yaml[i] = 0;
|
||||
comment = 1;
|
||||
comment = 1;
|
||||
}
|
||||
else if (yaml[i] == '\n') {
|
||||
yaml[i] = 0;
|
||||
@@ -108,17 +108,17 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
char *colon;
|
||||
|
||||
if (uwsgi_check_scheme(file)) {
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(file, ':');
|
||||
}
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
else {
|
||||
colon = uwsgi_get_last_char(file, ':');
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
if (colon[1] != 0) {
|
||||
section_asked = colon+1;
|
||||
section_asked = colon + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,81 +128,81 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
|
||||
#ifdef UWSGI_LIBYAML
|
||||
yaml_parser_t parser;
|
||||
yaml_token_t token;
|
||||
yaml_token_t token;
|
||||
int status = 0;
|
||||
int parsing = 1;
|
||||
|
||||
if(!yaml_parser_initialize(&parser)) {
|
||||
if (!yaml_parser_initialize(&parser)) {
|
||||
uwsgi_log("unable to initialize YAML parser (libyaml)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
yaml_parser_set_input_string(&parser, (const unsigned char *)yaml, (size_t) len-1);
|
||||
yaml_parser_set_input_string(&parser, (const unsigned char *) yaml, (size_t) len - 1);
|
||||
|
||||
while(parsing) {
|
||||
while (parsing) {
|
||||
if (!yaml_parser_scan(&parser, &token)) {
|
||||
uwsgi_log("error parsing YAML file: %s (%c)\n", parser.problem, yaml[parser.problem_offset]);
|
||||
exit(1);
|
||||
}
|
||||
switch(token.type) {
|
||||
case YAML_STREAM_END_TOKEN:
|
||||
switch (token.type) {
|
||||
case YAML_STREAM_END_TOKEN:
|
||||
parsing = 0;
|
||||
break;
|
||||
case YAML_KEY_TOKEN:
|
||||
status = 1;
|
||||
break;
|
||||
case YAML_VALUE_TOKEN:
|
||||
status = 2;
|
||||
break;
|
||||
case YAML_FLOW_SEQUENCE_START_TOKEN:
|
||||
case YAML_BLOCK_SEQUENCE_START_TOKEN:
|
||||
status = 3;
|
||||
break;
|
||||
case YAML_BLOCK_MAPPING_START_TOKEN:
|
||||
if (!in_uwsgi_section) {
|
||||
if (key) {
|
||||
if (!strcmp(section_asked, key)) {
|
||||
in_uwsgi_section = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case YAML_BLOCK_END_TOKEN:
|
||||
if (in_uwsgi_section) {
|
||||
parsing = 0;
|
||||
break;
|
||||
case YAML_KEY_TOKEN:
|
||||
status = 1;
|
||||
break;
|
||||
case YAML_VALUE_TOKEN:
|
||||
status = 2;
|
||||
break;
|
||||
case YAML_FLOW_SEQUENCE_START_TOKEN:
|
||||
case YAML_BLOCK_SEQUENCE_START_TOKEN:
|
||||
status = 3;
|
||||
break;
|
||||
case YAML_BLOCK_MAPPING_START_TOKEN:
|
||||
if (!in_uwsgi_section) {
|
||||
if (key) {
|
||||
if (!strcmp(section_asked, key)) {
|
||||
in_uwsgi_section = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case YAML_BLOCK_END_TOKEN:
|
||||
if (in_uwsgi_section) {
|
||||
parsing = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case YAML_SCALAR_TOKEN:
|
||||
case YAML_FLOW_ENTRY_TOKEN:
|
||||
case YAML_BLOCK_ENTRY_TOKEN:
|
||||
if (status == 1) {
|
||||
key = (char *) token.data.scalar.value;
|
||||
}
|
||||
else if (status == 2) {
|
||||
val = (char *) token.data.scalar.value;
|
||||
if (key && val && in_uwsgi_section) {
|
||||
add_exported_option(key, val, 0);
|
||||
}
|
||||
break;
|
||||
case YAML_SCALAR_TOKEN:
|
||||
case YAML_FLOW_ENTRY_TOKEN:
|
||||
case YAML_BLOCK_ENTRY_TOKEN:
|
||||
if (status == 1) {
|
||||
key = (char *) token.data.scalar.value;
|
||||
}
|
||||
else if (status == 2) {
|
||||
val = (char *) token.data.scalar.value;
|
||||
if (key && val && in_uwsgi_section) {
|
||||
add_exported_option(key, val, 0);
|
||||
}
|
||||
status = 0;
|
||||
}
|
||||
else if (status == 3) {
|
||||
val = (char *) token.data.scalar.value;
|
||||
if (key && val && in_uwsgi_section) {
|
||||
add_exported_option(key, val, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unsupported YAML token in %s block\n", section_asked);
|
||||
parsing = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
}
|
||||
else if (status == 3) {
|
||||
val = (char *) token.data.scalar.value;
|
||||
if (key && val && in_uwsgi_section) {
|
||||
add_exported_option(key, val, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unsupported YAML token in %s block\n", section_asked);
|
||||
parsing = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
int depth;
|
||||
int current_depth = 0;
|
||||
@@ -211,7 +211,7 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
char *section = "";
|
||||
|
||||
|
||||
while(len) {
|
||||
while (len) {
|
||||
yaml_line = yaml_get_line(yaml, len);
|
||||
if (yaml_line == NULL) {
|
||||
break;
|
||||
@@ -219,12 +219,14 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
lines++;
|
||||
|
||||
// skip empty line
|
||||
if (yaml[0] == 0) goto next;
|
||||
if (yaml[0] == 0)
|
||||
goto next;
|
||||
depth = yaml_get_depth(yaml);
|
||||
if (depth <= current_depth) {
|
||||
current_depth = depth;
|
||||
// end the parsing cycle
|
||||
if (in_uwsgi_section) return;
|
||||
if (in_uwsgi_section)
|
||||
return;
|
||||
}
|
||||
else if (depth > current_depth && !in_uwsgi_section) {
|
||||
goto next;
|
||||
@@ -232,40 +234,44 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
|
||||
key = yaml_lstrip(yaml);
|
||||
// skip empty line
|
||||
if (key[0] == 0) goto next;
|
||||
if (key[0] == 0)
|
||||
goto next;
|
||||
|
||||
// skip list and {} defined dict
|
||||
if (key[0] == '-' || key[0] == '[' || key[0] == '{') {
|
||||
if (in_uwsgi_section) return;
|
||||
if (in_uwsgi_section)
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
||||
if (!in_uwsgi_section) {
|
||||
section = strchr(key,':');
|
||||
if (!section) goto next;
|
||||
section = strchr(key, ':');
|
||||
if (!section)
|
||||
goto next;
|
||||
section[0] = 0;
|
||||
if (!strcmp(key, section_asked)) {
|
||||
in_uwsgi_section = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// get dict value
|
||||
// get dict value
|
||||
val = strstr(key, ": ");
|
||||
if (!val) {
|
||||
val = strstr(key, ":\t");
|
||||
}
|
||||
if (!val) return;
|
||||
if (!val)
|
||||
return;
|
||||
// get the right key
|
||||
val[0] = 0;
|
||||
// yeah overengeneering....
|
||||
yaml_rstrip(key);
|
||||
|
||||
val = yaml_lstrip(val+2);
|
||||
val = yaml_lstrip(val + 2);
|
||||
yaml_rstrip(val);
|
||||
|
||||
|
||||
//uwsgi_log("YAML: %s = %s\n", key, val);
|
||||
|
||||
add_exported_option((char *)key, val, 0);
|
||||
add_exported_option((char *) key, val, 0);
|
||||
}
|
||||
next:
|
||||
len -= (yaml_line - yaml);
|
||||
|
||||
@@ -82,7 +82,7 @@ void carbon_post_init() {
|
||||
// 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",
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -838,9 +838,15 @@ clear2:
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
|
||||
|
||||
if (setenv("PATH_TRANSLATED", uwsgi_concat3n(docroot, docroot_len, path_info, pi_len, "", 0) , 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
if (wsgi_req->document_root_len > 0) {
|
||||
if (setenv("PATH_TRANSLATED", uwsgi_concat3n(wsgi_req->document_root, wsgi_req->document_root_len, path_info, pi_len, "", 0) , 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (setenv("PATH_TRANSLATED", uwsgi_concat3n(docroot, docroot_len, path_info, pi_len, "", 0) , 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ void set_next_cheap_time(void) {
|
||||
// to have quicker recovery from big but short load spikes
|
||||
// otherwise we might wait a lot before cheaping all emergency workers
|
||||
if (uwsgi_cheaper_busyness_global.verbose)
|
||||
uwsgi_log("[busyness] %d emergency worker(s) running, using %d seconds cheaper timer\n",
|
||||
uwsgi_log("[busyness] %d emergency worker(s) running, using %llu seconds cheaper timer\n",
|
||||
uwsgi_cheaper_busyness_global.emergency_workers, uwsgi.cheaper_overload*uwsgi_cheaper_busyness_global.backlog_multi);
|
||||
uwsgi_cheaper_busyness_global.next_cheap = now + uwsgi.cheaper_overload*uwsgi_cheaper_busyness_global.backlog_multi*1000000;
|
||||
} else {
|
||||
@@ -95,7 +95,7 @@ void decrease_multi(void) {
|
||||
// will decrease multiplier but only down to initial value
|
||||
if (uwsgi_cheaper_busyness_global.cheap_multi > uwsgi_cheaper_busyness_global.min_multi) {
|
||||
uwsgi_cheaper_busyness_global.cheap_multi--;
|
||||
uwsgi_log("[busyness] decreasing cheaper multiplier to %d\n", uwsgi_cheaper_busyness_global.cheap_multi);
|
||||
uwsgi_log("[busyness] decreasing cheaper multiplier to %llu\n", uwsgi_cheaper_busyness_global.cheap_multi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ int cheaper_busyness_algo(void) {
|
||||
// store initial multiplier so we don't loose its initial value
|
||||
uwsgi_cheaper_busyness_global.min_multi = uwsgi_cheaper_busyness_global.cheap_multi;
|
||||
// since this is first run we will print current values
|
||||
uwsgi_log("[busyness] settings: min=%d%%, max=%d%%, overload=%d, multiplier=%d, respawn penalty=%d\n",
|
||||
uwsgi_log("[busyness] settings: min=%llu%%, max=%llu%%, overload=%llu, multiplier=%llu, respawn penalty=%llu\n",
|
||||
uwsgi_cheaper_busyness_global.busyness_min, uwsgi_cheaper_busyness_global.busyness_max,
|
||||
uwsgi.cheaper_overload, uwsgi_cheaper_busyness_global.cheap_multi, uwsgi_cheaper_busyness_global.penalty);
|
||||
#ifdef __linux__
|
||||
@@ -171,7 +171,7 @@ int cheaper_busyness_algo(void) {
|
||||
|
||||
if (uwsgi_cheaper_busyness_global.next_cheap == 0) set_next_cheap_time();
|
||||
|
||||
int64_t active_workers = 0;
|
||||
int active_workers = 0;
|
||||
uint64_t total_busyness = 0;
|
||||
uint64_t avg_busyness = 0;
|
||||
|
||||
@@ -195,7 +195,7 @@ int cheaper_busyness_algo(void) {
|
||||
if (percent > 100) percent = 100;
|
||||
total_busyness += percent;
|
||||
if (uwsgi_cheaper_busyness_global.verbose && active_workers > 1)
|
||||
uwsgi_log("[busyness] worker nr %d %ds average busyness is at %d%%\n",
|
||||
uwsgi_log("[busyness] worker nr %d %llus average busyness is at %llu%%\n",
|
||||
i+1, uwsgi.cheaper_overload, percent);
|
||||
}
|
||||
uwsgi_cheaper_busyness_global.last_values[i] = uwsgi.workers[i+1].running_time;
|
||||
@@ -204,7 +204,7 @@ int cheaper_busyness_algo(void) {
|
||||
avg_busyness = (active_workers ? total_busyness / active_workers : 0);
|
||||
if (uwsgi_cheaper_busyness_global.verbose)
|
||||
uwsgi_log("[busyness] %ds average busyness of %d worker(s) is at %d%%\n",
|
||||
uwsgi.cheaper_overload, active_workers, avg_busyness);
|
||||
(int) uwsgi.cheaper_overload, (int) active_workers, (int) avg_busyness);
|
||||
|
||||
if (avg_busyness > uwsgi_cheaper_busyness_global.busyness_max) {
|
||||
|
||||
@@ -229,7 +229,7 @@ int cheaper_busyness_algo(void) {
|
||||
// worker was cheaped and then spawned back in less than current multiplier*cheaper_overload seconds
|
||||
// we will increase the multiplier so that next time worker will need to wait longer before being cheaped
|
||||
uwsgi_cheaper_busyness_global.cheap_multi += uwsgi_cheaper_busyness_global.penalty;
|
||||
uwsgi_log("[busyness] worker(s) respawned to fast, increasing chpeaper multiplier to %d (+%d)\n",
|
||||
uwsgi_log("[busyness] worker(s) respawned to fast, increasing chpeaper multiplier to %llu (+%llu)\n",
|
||||
uwsgi_cheaper_busyness_global.cheap_multi, uwsgi_cheaper_busyness_global.penalty);
|
||||
} else {
|
||||
decrease_multi();
|
||||
@@ -237,10 +237,10 @@ int cheaper_busyness_algo(void) {
|
||||
|
||||
set_next_cheap_time();
|
||||
|
||||
uwsgi_log("[busyness] %ds average busyness is at %d%%, will spawn %d new worker(s)\n",
|
||||
uwsgi_log("[busyness] %llus average busyness is at %llu%%, will spawn %d new worker(s)\n",
|
||||
uwsgi.cheaper_overload, avg_busyness, decheaped);
|
||||
} else {
|
||||
uwsgi_log("[busyness] %ds average busyness is at %d%% but we already started maximum number of workers (%d)\n",
|
||||
uwsgi_log("[busyness] %llus average busyness is at %llu%% but we already started maximum number of workers (%d)\n",
|
||||
uwsgi.cheaper_overload, avg_busyness, uwsgi.numproc);
|
||||
}
|
||||
|
||||
@@ -267,8 +267,8 @@ int cheaper_busyness_algo(void) {
|
||||
if (uwsgi_cheaper_busyness_global.last_action == 2) decrease_multi();
|
||||
set_next_cheap_time();
|
||||
|
||||
uwsgi_log("[busyness] %ds average busyness is at %d%%, cheap one of %d running workers\n",
|
||||
uwsgi.cheaper_overload, avg_busyness, active_workers);
|
||||
uwsgi_log("[busyness] %llus average busyness is at %llu%%, cheap one of %d running workers\n",
|
||||
uwsgi.cheaper_overload, avg_busyness, (int) active_workers);
|
||||
// store timestamp
|
||||
uwsgi_cheaper_busyness_global.last_cheaped = uwsgi_micros();
|
||||
|
||||
@@ -280,7 +280,7 @@ int cheaper_busyness_algo(void) {
|
||||
|
||||
return -1;
|
||||
} else if (uwsgi_cheaper_busyness_global.verbose)
|
||||
uwsgi_log("[busyness] need to wait %d more second(s) to cheap worker\n", (uwsgi_cheaper_busyness_global.next_cheap - now)/1000000);
|
||||
uwsgi_log("[busyness] need to wait %llu more second(s) to cheap worker\n", (uwsgi_cheaper_busyness_global.next_cheap - now)/1000000);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -301,14 +301,14 @@ int cheaper_busyness_algo(void) {
|
||||
// time needed to cheap them, than a lot min<busy<max when we do not reset timer
|
||||
// and then another idle cycle than would trigger cheaping
|
||||
if (uwsgi_cheaper_busyness_global.verbose)
|
||||
uwsgi_log("[busyness] %ds average busyness is at %d%%, %d non-idle cycle(s), reseting cheaper timer\n",
|
||||
uwsgi_log("[busyness] %llus average busyness is at %llu%%, %llu non-idle cycle(s), reseting cheaper timer\n",
|
||||
uwsgi.cheaper_overload, avg_busyness, uwsgi_cheaper_busyness_global.tolerance_counter);
|
||||
set_next_cheap_time();
|
||||
} else {
|
||||
// we had < 3 idle cycles in a row so we won't reset idle timer yet since this might be just short load spike
|
||||
// but we need to add cheaper-overload seconds to the cheaper timer so this cycle isn't counted as idle
|
||||
if (uwsgi_cheaper_busyness_global.verbose)
|
||||
uwsgi_log("[busyness] %ds average busyness is at %d%%, %d non-idle cycle(s), adjusting cheaper timer\n",
|
||||
uwsgi_log("[busyness] %llus average busyness is at %llu%%, %llu non-idle cycle(s), adjusting cheaper timer\n",
|
||||
uwsgi.cheaper_overload, avg_busyness, uwsgi_cheaper_busyness_global.tolerance_counter);
|
||||
uwsgi_cheaper_busyness_global.next_cheap += uwsgi.cheaper_overload*1000000;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@ void uwsgi_opt_corerouter(char *opt, char *value, void *cr) {
|
||||
ucr->has_sockets++;
|
||||
}
|
||||
|
||||
void uwsgi_opt_undeferred_corerouter(char *opt, char *value, void *cr) {
|
||||
struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr;
|
||||
struct uwsgi_gateway_socket *ugs = uwsgi_new_gateway_socket(value, ucr->name);
|
||||
ugs->no_defer = 1;
|
||||
ucr->has_sockets++;
|
||||
}
|
||||
|
||||
void uwsgi_opt_corerouter_use_socket(char *opt, char *value, void *cr) {
|
||||
struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr;
|
||||
ucr->use_socket = 1;
|
||||
@@ -195,19 +202,14 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
|
||||
if (cr_session->soopt) {
|
||||
if (!ucr->quiet)
|
||||
uwsgi_log("unable to connect() to uwsgi instance \"%.*s\": %s\n", (int) cr_session->instance_address_len, cr_session->instance_address, strerror(cr_session->soopt));
|
||||
uwsgi_log("[uwsgi-%s] unable to connect() to node \"%.*s\": %s\n", ucr->short_name, (int) cr_session->instance_address_len, cr_session->instance_address, strerror(cr_session->soopt));
|
||||
}
|
||||
else if (cr_session->timed_out) {
|
||||
if (cr_session->instance_address_len > 0) {
|
||||
/*
|
||||
if (cr_session->status == COREROUTER_STATUS_CONNECTING) {
|
||||
if (cr_session->connecting) {
|
||||
if (!ucr->quiet)
|
||||
uwsgi_log("unable to connect() to uwsgi instance \"%.*s\": timeout\n", (int) cr_session->instance_address_len, cr_session->instance_address);
|
||||
uwsgi_log("[uwsgi-%s] unable to connect() to node \"%.*s\": timeout\n", ucr->short_name, (int) cr_session->instance_address_len, cr_session->instance_address);
|
||||
}
|
||||
else if (cr_session->status == COREROUTER_STATUS_RESPONSE) {
|
||||
uwsgi_log("timeout waiting for instance \"%.*s\"\n", (int) cr_session->instance_address_len, cr_session->instance_address);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +241,29 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
cr_session->tmp_socket_name = NULL;
|
||||
}
|
||||
|
||||
if (!cr_session->retry) goto end;
|
||||
// check for max retries
|
||||
if (cr_session->retries >= (size_t) ucr->max_retries) goto end;
|
||||
|
||||
cr_session->retries++;
|
||||
|
||||
// reset error and timeout
|
||||
cr_session->instance_failed = 0;
|
||||
cr_session->timeout = corerouter_reset_timeout(ucr, cr_session);
|
||||
cr_session->timed_out = 0;
|
||||
cr_session->soopt = 0;
|
||||
|
||||
// reset nodes
|
||||
cr_session->un = NULL;
|
||||
cr_session->static_node = NULL;
|
||||
cr_session->instance_fd = -1;
|
||||
|
||||
// reset hooks (safe as fd is closed)
|
||||
cr_session->event_hook_read = NULL;
|
||||
cr_session->event_hook_write = NULL;
|
||||
cr_session->event_hook_instance_read = NULL;
|
||||
cr_session->event_hook_instance_write = NULL;
|
||||
|
||||
if (ucr->fallback) {
|
||||
// ok let's try with the fallback nodes
|
||||
if (!cr_session->fallback) {
|
||||
@@ -252,35 +277,18 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
cr_session->instance_address = cr_session->fallback->value;
|
||||
cr_session->instance_address_len = cr_session->fallback->len;
|
||||
|
||||
// reset error and timeout
|
||||
cr_session->timeout = corerouter_reset_timeout(ucr, cr_session);
|
||||
cr_session->timed_out = 0;
|
||||
cr_session->soopt = 0;
|
||||
|
||||
// reset nodes
|
||||
cr_session->un = NULL;
|
||||
cr_session->static_node = NULL;
|
||||
|
||||
cr_session->pass_fd = is_unix(cr_session->instance_address, cr_session->instance_address_len);
|
||||
|
||||
|
||||
cr_session->instance_fd = uwsgi_connectn(cr_session->instance_address, cr_session->instance_address_len, 0, 1);
|
||||
|
||||
if (cr_session->instance_fd < 0) {
|
||||
cr_session->instance_failed = 1;
|
||||
cr_session->soopt = errno;
|
||||
corerouter_close_session(ucr, cr_session);
|
||||
return;
|
||||
if (cr_session->retry(ucr, cr_session)) {
|
||||
if (!cr_session->instance_failed) goto end;
|
||||
}
|
||||
|
||||
ucr->cr_table[cr_session->instance_fd] = cr_session;
|
||||
|
||||
//cr_session->status = COREROUTER_STATUS_CONNECTING;
|
||||
ucr->cr_table[cr_session->instance_fd] = cr_session;
|
||||
event_queue_add_fd_write(ucr->queue, cr_session->instance_fd);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
cr_session->instance_address = NULL;
|
||||
cr_session->instance_address_len = 0;
|
||||
if (cr_session->retry(ucr, cr_session)) {
|
||||
if (!cr_session->instance_failed) goto end;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -331,23 +339,10 @@ static void corerouter_expire_timeouts(struct uwsgi_corerouter *ucr) {
|
||||
if (urbt->key <= current) {
|
||||
cr_session = (struct corerouter_session *) urbt->data;
|
||||
cr_session->timed_out = 1;
|
||||
if (cr_session->retry) {
|
||||
cr_session->retry = 0;
|
||||
/*
|
||||
TODO allows retry
|
||||
ucr->switch_events(ucr, cr_session, -1);
|
||||
*/
|
||||
if (cr_session->retry) {
|
||||
cr_del_timeout(ucr, cr_session);
|
||||
cr_session->timeout = cr_add_fake_timeout(ucr, cr_session);
|
||||
}
|
||||
else {
|
||||
cr_session->timeout = corerouter_reset_timeout(ucr, cr_session);
|
||||
}
|
||||
}
|
||||
else {
|
||||
corerouter_close_session(ucr, cr_session);
|
||||
if (cr_session->connecting) {
|
||||
cr_session->instance_failed = 1;
|
||||
}
|
||||
corerouter_close_session(ucr, cr_session);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -572,7 +567,7 @@ struct corerouter_session *corerouter_alloc_session(struct uwsgi_corerouter *ucr
|
||||
ucr->cr_table[new_connection]->fd = new_connection;
|
||||
ucr->cr_table[new_connection]->instance_fd = -1;
|
||||
|
||||
// map courerouter and socket
|
||||
// map corerouter and socket
|
||||
ucr->cr_table[new_connection]->corerouter = ucr;
|
||||
ucr->cr_table[new_connection]->ugs = ugs;
|
||||
|
||||
@@ -771,7 +766,11 @@ void uwsgi_corerouter_loop(int id, void *data) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
corerouter_alloc_session(ucr, ugs, new_connection, (struct sockaddr *) &cr_addr, cr_addr_len);
|
||||
struct corerouter_session *cr = corerouter_alloc_session(ucr, ugs, new_connection, (struct sockaddr *) &cr_addr, cr_addr_len);
|
||||
//something wrong in the allocation
|
||||
if (cr->instance_failed) {
|
||||
corerouter_close_session(ucr, cr);
|
||||
}
|
||||
}
|
||||
else if (ugs->subscription) {
|
||||
uwsgi_corerouter_manage_subscription(ucr, id, ugs);
|
||||
@@ -860,7 +859,7 @@ void uwsgi_corerouter_loop(int id, void *data) {
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_courerouter_has_has_backends(struct uwsgi_corerouter *ucr) {
|
||||
int uwsgi_corerouter_has_backends(struct uwsgi_corerouter *ucr) {
|
||||
|
||||
if (ucr->has_backends) return 1;
|
||||
|
||||
@@ -896,8 +895,11 @@ int uwsgi_corerouter_init(struct uwsgi_corerouter *ucr) {
|
||||
if (!ucr->nevents)
|
||||
ucr->nevents = 64;
|
||||
|
||||
if (!ucr->max_retries)
|
||||
ucr->max_retries = 3;
|
||||
|
||||
|
||||
ucr->has_backends = uwsgi_courerouter_has_has_backends(ucr);
|
||||
ucr->has_backends = uwsgi_corerouter_has_backends(ucr);
|
||||
|
||||
|
||||
uwsgi_corerouter_setup_sockets(ucr);
|
||||
@@ -921,7 +923,7 @@ int uwsgi_corerouter_init(struct uwsgi_corerouter *ucr) {
|
||||
|
||||
struct uwsgi_plugin corerouter_plugin = {
|
||||
|
||||
.name = "courerouter",
|
||||
.name = "corerouter",
|
||||
};
|
||||
|
||||
void corerouter_send_stats(struct uwsgi_corerouter *ucr) {
|
||||
@@ -968,6 +970,29 @@ void corerouter_send_stats(struct uwsgi_corerouter *ucr) {
|
||||
if (uwsgi_stats_list_close(us)) goto end0;
|
||||
if (uwsgi_stats_comma(us)) goto end0;
|
||||
|
||||
if (ucr->static_nodes) {
|
||||
if (uwsgi_stats_key(us , "static_nodes")) goto end0;
|
||||
if (uwsgi_stats_list_open(us)) goto end0;
|
||||
|
||||
struct uwsgi_string_list *usl = ucr->static_nodes;
|
||||
while(usl) {
|
||||
if (uwsgi_stats_object_open(us)) goto end0;
|
||||
if (uwsgi_stats_keyvaln_comma(us, "name", usl->value, usl->len)) goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "hits", (unsigned long long) usl->custom2)) goto end0;
|
||||
if (uwsgi_stats_keylong(us, "grace", (unsigned long long) usl->custom)) goto end0;
|
||||
|
||||
if (uwsgi_stats_object_close(us)) goto end0;
|
||||
usl = usl->next;
|
||||
if (usl) {
|
||||
if (uwsgi_stats_comma(us)) goto end0;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_stats_list_close(us)) goto end0;
|
||||
if (uwsgi_stats_comma(us)) goto end0;
|
||||
}
|
||||
|
||||
if (ucr->has_subscription_sockets) {
|
||||
if (uwsgi_stats_key(us , "subscriptions")) goto end0;
|
||||
if (uwsgi_stats_list_open(us)) goto end0;
|
||||
|
||||
@@ -38,6 +38,8 @@ struct uwsgi_corerouter {
|
||||
int use_cache;
|
||||
int nevents;
|
||||
|
||||
int max_retries;
|
||||
|
||||
char *magic_table[256];
|
||||
|
||||
int queue;
|
||||
@@ -102,14 +104,13 @@ struct corerouter_session {
|
||||
uint16_t hostname_len;
|
||||
|
||||
int has_key;
|
||||
int retry;
|
||||
int connecting;
|
||||
|
||||
char *instance_address;
|
||||
uint64_t instance_address_len;
|
||||
|
||||
struct uwsgi_subscribe_node *un;
|
||||
struct uwsgi_string_list *static_node;
|
||||
int pass_fd;
|
||||
int soopt;
|
||||
int timed_out;
|
||||
|
||||
@@ -139,6 +140,8 @@ struct corerouter_session {
|
||||
ssize_t (*event_hook_instance_write)(struct corerouter_session *);
|
||||
|
||||
void (*close)(struct corerouter_session *);
|
||||
int (*retry)(struct uwsgi_corerouter *, struct corerouter_session *);
|
||||
size_t retries;
|
||||
|
||||
struct uwsgi_buffer *buffer;
|
||||
size_t buffer_len;
|
||||
@@ -151,6 +154,7 @@ struct corerouter_session {
|
||||
};
|
||||
|
||||
void uwsgi_opt_corerouter(char *, char *, void *);
|
||||
void uwsgi_opt_undeferred_corerouter(char *, char *, void *);
|
||||
void uwsgi_opt_corerouter_use_socket(char *, char *, void *);
|
||||
void uwsgi_opt_corerouter_use_base(char *, char *, void *);
|
||||
void uwsgi_opt_corerouter_use_pattern(char *, char *, void *);
|
||||
@@ -181,7 +185,7 @@ int uwsgi_cr_map_use_cs(struct uwsgi_corerouter *, struct corerouter_session *);
|
||||
int uwsgi_cr_map_use_to(struct uwsgi_corerouter *, struct corerouter_session *);
|
||||
int uwsgi_cr_map_use_static_nodes(struct uwsgi_corerouter *, struct corerouter_session *);
|
||||
|
||||
int uwsgi_courerouter_has_has_backends(struct uwsgi_corerouter *);
|
||||
int uwsgi_corerouter_has_backends(struct uwsgi_corerouter *);
|
||||
|
||||
int uwsgi_cr_hook_read(struct corerouter_session *, ssize_t (*)(struct corerouter_session *));
|
||||
int uwsgi_cr_hook_write(struct corerouter_session *, ssize_t (*)(struct corerouter_session *));
|
||||
|
||||
@@ -41,6 +41,10 @@ void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *ucr) {
|
||||
}
|
||||
else {
|
||||
ugs->port = strchr(ugs->name, ':');
|
||||
int current_defer_accept = uwsgi.no_defer_accept;
|
||||
if (ugs->no_defer) {
|
||||
uwsgi.no_defer_accept = 1;
|
||||
}
|
||||
if (ugs->fd == -1) {
|
||||
if (ugs->port) {
|
||||
ugs->fd = bind_to_tcp(ugs->name, uwsgi.listen_queue, ugs->port);
|
||||
@@ -51,6 +55,9 @@ void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *ucr) {
|
||||
ugs->fd = bind_to_unix(ugs->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
}
|
||||
if (ugs->no_defer) {
|
||||
uwsgi.no_defer_accept = current_defer_accept;
|
||||
}
|
||||
}
|
||||
// put socket in non-blocking mode
|
||||
uwsgi_socket_nb(ugs->fd);
|
||||
|
||||
@@ -233,6 +233,8 @@ ssize_t fr_instance_send_request_header(struct corerouter_session * cs) {
|
||||
|
||||
ssize_t fr_instance_connected(struct corerouter_session * cs) {
|
||||
|
||||
cs->connecting = 0;
|
||||
|
||||
socklen_t solen = sizeof(int);
|
||||
|
||||
// first check for errors
|
||||
@@ -250,6 +252,7 @@ ssize_t fr_instance_connected(struct corerouter_session * cs) {
|
||||
cs->buffer_pos = 0;
|
||||
|
||||
// ok instance is connected, wait for write again
|
||||
if (cs->static_node) cs->static_node->custom2++;
|
||||
if (cs->un) cs->un->requests++;
|
||||
uwsgi_cr_hook_instance_write(cs, fr_instance_send_request_header);
|
||||
// return a value > 0
|
||||
@@ -304,6 +307,7 @@ ssize_t fr_recv_uwsgi_vars(struct corerouter_session * cs) {
|
||||
// map the instance
|
||||
cs->corerouter->cr_table[cs->instance_fd] = cs;
|
||||
// wait for connection
|
||||
cs->connecting = 1;
|
||||
uwsgi_cr_hook_instance_write(cs, fr_instance_connected);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ var uwsgi_modifier1 int = -1;
|
||||
var uwsgi_env_gc = make(map[*C.struct_wsgi_request](*map[string]string))
|
||||
var uwsgi_signals_gc = make([]*func(int), 256)
|
||||
|
||||
var uwsgi_default_handler func(http.ResponseWriter, *http.Request) = nil
|
||||
var uwsgi_default_request_handler func(http.ResponseWriter, *http.Request) = nil
|
||||
var uwsgi_default_handler http.Handler = nil
|
||||
var uwsgi_post_fork_hook func() = nil
|
||||
var uwsgi_post_init_hook func() = nil
|
||||
|
||||
@@ -248,7 +249,11 @@ func PostInit(hook func()) {
|
||||
}
|
||||
|
||||
func RequestHandler(hook func(http.ResponseWriter, *http.Request)) {
|
||||
uwsgi_default_handler = hook
|
||||
uwsgi_default_request_handler = hook
|
||||
}
|
||||
|
||||
func Handler(handler http.Handler) {
|
||||
uwsgi_default_handler = handler
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -370,8 +375,10 @@ func uwsgi_go_helper_request(env *map[string]string, wsgi_req *C.struct_wsgi_req
|
||||
} else {
|
||||
httpReq.Body = &BodyReader{wsgi_req}
|
||||
w := ResponseWriter{httpReq, wsgi_req,http.Header{},false, ""}
|
||||
if uwsgi_default_handler != nil {
|
||||
uwsgi_default_handler(&w, httpReq)
|
||||
if uwsgi_default_request_handler != nil {
|
||||
uwsgi_default_request_handler(&w, httpReq)
|
||||
} else if uwsgi_default_handler != nil {
|
||||
uwsgi_default_handler.ServeHTTP(&w, httpReq)
|
||||
} else {
|
||||
http.DefaultServeMux.ServeHTTP(&w, httpReq)
|
||||
}
|
||||
|
||||
+25
-3
@@ -399,9 +399,9 @@ int http_parse(struct http_session *h_session, size_t http_req_len) {
|
||||
while (ptr < watermark) {
|
||||
if (*ptr == '\r') {
|
||||
if (ptr + 1 >= watermark)
|
||||
return 0;
|
||||
break;
|
||||
if (*(ptr + 1) != '\n')
|
||||
return 0;
|
||||
break;
|
||||
// multiline header ?
|
||||
if (ptr + 2 < watermark) {
|
||||
if (*(ptr + 2) == ' ' || *(ptr + 2) == '\t') {
|
||||
@@ -518,6 +518,14 @@ ssize_t hr_read_ssl_body(struct corerouter_session * cs) {
|
||||
if (cs->event_hook_write) {
|
||||
uwsgi_cr_hook_write(cs, NULL);
|
||||
}
|
||||
int ret2 = SSL_pending(hs->ssl);
|
||||
if (ret2 > 0) {
|
||||
if (uwsgi_buffer_fix(hs->post_buf, hs->post_buf->len + ret2 )) return -1;
|
||||
if (SSL_read(hs->ssl, hs->post_buf->buf + ret, ret2) != ret2) {
|
||||
return -1;
|
||||
}
|
||||
ret += ret2;
|
||||
}
|
||||
hs->post_buf_len = ret;
|
||||
hs->post_buf_pos = 0;
|
||||
uwsgi_cr_hook_read(cs, NULL);
|
||||
@@ -762,6 +770,12 @@ ssize_t hr_instance_send_request(struct corerouter_session * cs) {
|
||||
|
||||
|
||||
ssize_t hr_instance_send_request_header(struct corerouter_session * cs) {
|
||||
#ifdef __BIG_ENDIAN__
|
||||
// on the first round fix endianess
|
||||
if (cs->buffer_pos == 0) {
|
||||
cs->uh.pktsize = uwsgi_swap16(cs->uh.pktsize);
|
||||
}
|
||||
#endif
|
||||
ssize_t len = write(cs->instance_fd, &cs->uh + cs->buffer_pos, 4 - cs->buffer_pos);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
@@ -775,6 +789,10 @@ ssize_t hr_instance_send_request_header(struct corerouter_session * cs) {
|
||||
// for response
|
||||
if (cs->buffer_pos == 4) {
|
||||
cs->buffer_pos = 0;
|
||||
#ifdef __BIG_ENDIAN__
|
||||
// on the last round restore endianess
|
||||
cs->uh.pktsize = uwsgi_swap16(cs->uh.pktsize);
|
||||
#endif
|
||||
uwsgi_cr_hook_instance_write(cs, hr_instance_send_request);
|
||||
}
|
||||
|
||||
@@ -856,6 +874,8 @@ done:
|
||||
}
|
||||
|
||||
ssize_t hr_instance_connected(struct corerouter_session * cs) {
|
||||
|
||||
cs->connecting = 0;
|
||||
socklen_t solen = sizeof(int);
|
||||
|
||||
// first check for errors
|
||||
@@ -882,6 +902,7 @@ ssize_t hr_instance_connected(struct corerouter_session * cs) {
|
||||
return 1;
|
||||
}
|
||||
// ok instance is connected, wait for write again
|
||||
if (cs->static_node) cs->static_node->custom2++;
|
||||
if (cs->un) cs->un->requests++;
|
||||
uwsgi_cr_hook_instance_write(cs, hr_instance_send_request_header);
|
||||
// return a value > 0
|
||||
@@ -1024,6 +1045,7 @@ ssize_t hs_http_manage(struct corerouter_session * cs, ssize_t len) {
|
||||
// map the instance
|
||||
cs->corerouter->cr_table[cs->instance_fd] = cs;
|
||||
// wait for connection
|
||||
cs->connecting = 1;
|
||||
uwsgi_cr_hook_instance_write(cs, hr_instance_connected);
|
||||
break;
|
||||
}
|
||||
@@ -1117,7 +1139,7 @@ int http_init() {
|
||||
|
||||
uhttp.cr.session_size = sizeof(struct http_session);
|
||||
uhttp.cr.alloc_session = http_alloc_session;
|
||||
if (uhttp.cr.has_sockets && !uwsgi.sockets && !uwsgi_courerouter_has_has_backends(&uhttp.cr)) {
|
||||
if (uhttp.cr.has_sockets && !uwsgi.sockets && !uwsgi_corerouter_has_backends(&uhttp.cr)) {
|
||||
uwsgi_new_socket(uwsgi_concat2("127.0.0.1:0", ""));
|
||||
uhttp.cr.use_socket = 1;
|
||||
uhttp.cr.socket_num = 0;
|
||||
|
||||
@@ -308,6 +308,8 @@ static const luaL_reg uwsgi_api[] = {
|
||||
static int uwsgi_lua_input(lua_State *L) {
|
||||
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
int fd = wsgi_req->async_post ?
|
||||
fileno(wsgi_req->async_post) : wsgi_req->poll.fd;
|
||||
ssize_t sum, len, total;
|
||||
char *buf, *ptr;
|
||||
|
||||
@@ -330,7 +332,7 @@ static int uwsgi_lua_input(lua_State *L) {
|
||||
|
||||
ptr = buf;
|
||||
while(total) {
|
||||
len = read(wsgi_req->poll.fd, ptr, total);
|
||||
len = read(fd, ptr, total);
|
||||
ptr += len;
|
||||
total -= len;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@ struct uwsgi_php {
|
||||
struct uwsgi_string_list *index;
|
||||
struct uwsgi_string_list *set;
|
||||
struct uwsgi_string_list *append_config;
|
||||
struct uwsgi_string_list *vars;
|
||||
char *docroot;
|
||||
char *app;
|
||||
char *app_qs;
|
||||
size_t ini_size;
|
||||
int dump_config;
|
||||
char *server_software;
|
||||
@@ -49,6 +51,8 @@ struct uwsgi_option uwsgi_php_options[] = {
|
||||
{"php-allowed-script", required_argument, 0, "list the allowed php scripts (require absolute path)", uwsgi_opt_add_string_list, &uphp.allowed_scripts, 0},
|
||||
{"php-server-software", required_argument, 0, "force php SERVER_SOFTWARE", uwsgi_opt_set_str, &uphp.server_software, 0},
|
||||
{"php-app", required_argument, 0, "force the php file to run at each request", uwsgi_opt_set_str, &uphp.app, 0},
|
||||
{"php-var", required_argument, 0, "add/overwrite a CGI variable at each request", uwsgi_opt_add_string_list, &uphp.vars, 0},
|
||||
{"php-app-qs", required_argument, 0, "when in app mode force QUERY_STRING to the specified value + PATH_INFO", uwsgi_opt_set_str, &uphp.app_qs, 0},
|
||||
{"php-dump-config", no_argument, 0, "dump php config (if modified via --php-set or append options)", uwsgi_opt_true, &uphp.dump_config, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
@@ -285,6 +289,9 @@ static void sapi_uwsgi_register_variables(zval *track_vars_array TSRMLS_DC)
|
||||
}
|
||||
|
||||
php_register_variable_safe("PATH_INFO", wsgi_req->path_info, wsgi_req->path_info_len, track_vars_array TSRMLS_CC);
|
||||
if (wsgi_req->query_string_len > 0) {
|
||||
php_register_variable_safe("QUERY_STRING", wsgi_req->query_string, wsgi_req->query_string_len, track_vars_array TSRMLS_CC);
|
||||
}
|
||||
|
||||
php_register_variable_safe("SCRIPT_NAME", wsgi_req->script_name, wsgi_req->script_name_len, track_vars_array TSRMLS_CC);
|
||||
php_register_variable_safe("SCRIPT_FILENAME", wsgi_req->file, wsgi_req->file_len, track_vars_array TSRMLS_CC);
|
||||
@@ -304,6 +311,16 @@ static void sapi_uwsgi_register_variables(zval *track_vars_array TSRMLS_DC)
|
||||
|
||||
php_register_variable_safe("PHP_SELF", wsgi_req->script_name, wsgi_req->script_name_len, track_vars_array TSRMLS_CC);
|
||||
|
||||
struct uwsgi_string_list *usl = uphp.vars;
|
||||
while(usl) {
|
||||
char *equal = strchr(usl->value, '=');
|
||||
if (equal) {
|
||||
php_register_variable_safe( estrndup(usl->value, equal-usl->value),
|
||||
equal+1, strlen(equal+1), track_vars_array TSRMLS_CC);
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -658,6 +675,16 @@ int uwsgi_php_init(void) {
|
||||
uwsgi_log("--- end of PHP custom config ---\n");
|
||||
}
|
||||
|
||||
// fix docroot
|
||||
if (uphp.docroot) {
|
||||
char *orig_docroot = uphp.docroot;
|
||||
uphp.docroot = uwsgi_expand_path(uphp.docroot, strlen(uphp.docroot), NULL);
|
||||
if (!uphp.docroot) {
|
||||
uwsgi_log("unable to set php docroot to %s\n", orig_docroot);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_sapi_module.startup(&uwsgi_sapi_module);
|
||||
|
||||
// filling http status codes
|
||||
@@ -766,6 +793,27 @@ int uwsgi_php_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (uphp.app) {
|
||||
strcpy(real_filename, uphp.app);
|
||||
if (wsgi_req->path_info_len == 1 && wsgi_req->path_info[0] == '/') {
|
||||
goto appready;
|
||||
}
|
||||
if (uphp.app_qs) {
|
||||
size_t app_qs_len = strlen(uphp.app_qs);
|
||||
size_t qs_len = wsgi_req->path_info_len + app_qs_len;
|
||||
if (wsgi_req->query_string_len > 0) {
|
||||
qs_len += 1 + wsgi_req->query_string_len;
|
||||
}
|
||||
char *qs = ecalloc(1, qs_len+1);
|
||||
memcpy(qs, uphp.app_qs, app_qs_len);
|
||||
memcpy(qs+app_qs_len, wsgi_req->path_info, wsgi_req->path_info_len);
|
||||
if (wsgi_req->query_string_len > 0) {
|
||||
char *ptr = qs+app_qs_len+wsgi_req->path_info_len;
|
||||
*ptr = '&';
|
||||
memcpy(ptr+1, wsgi_req->query_string, wsgi_req->query_string_len);
|
||||
}
|
||||
wsgi_req->query_string = qs;
|
||||
wsgi_req->query_string_len = qs_len;
|
||||
}
|
||||
appready:
|
||||
wsgi_req->path_info = "";
|
||||
wsgi_req->path_info_len = 0;
|
||||
goto secure2;
|
||||
@@ -891,7 +939,6 @@ secure2:
|
||||
|
||||
secure3:
|
||||
|
||||
|
||||
if (wsgi_req->document_root[wsgi_req->document_root_len-1] == '/') {
|
||||
wsgi_req->script_name = real_filename + (wsgi_req->document_root_len-1);
|
||||
}
|
||||
|
||||
@@ -51,3 +51,4 @@ int uwsgi_perl_obj_can(SV *, char *, size_t);
|
||||
int uwsgi_perl_obj_isa(SV *, char *);
|
||||
int init_psgi_app(struct wsgi_request *, char *, uint16_t, PerlInterpreter **);
|
||||
PerlInterpreter *uwsgi_perl_new_interpreter(void);
|
||||
int uwsgi_perl_mule(char *);
|
||||
|
||||
@@ -233,6 +233,8 @@ xs_init(pTHX)
|
||||
/* DynaLoader is a special case */
|
||||
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
|
||||
|
||||
if (!uperl.tmp_input_stash) goto nonworker;
|
||||
|
||||
newXS("uwsgi::input::new", XS_input, "uwsgi::input");
|
||||
newXS("uwsgi::input::read", XS_input_read, "uwsgi::input");
|
||||
newXS("uwsgi::input::seek", XS_input_seek, "uwsgi::input");
|
||||
@@ -253,6 +255,8 @@ xs_init(pTHX)
|
||||
|
||||
uperl.tmp_streaming_stash[uperl.tmp_current_i] = gv_stashpv("uwsgi::streaming", 0);
|
||||
|
||||
nonworker:
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
init_perl_embedded_module();
|
||||
#endif
|
||||
@@ -496,3 +500,19 @@ void uwsgi_psgi_app() {
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_perl_mule(char *opt) {
|
||||
|
||||
if (uwsgi_endswith(opt, ".pl")) {
|
||||
PERL_SET_CONTEXT(uperl.main[0]);
|
||||
uperl.embedding[1] = opt;
|
||||
if (perl_parse(uperl.main[0], xs_init, 2, uperl.embedding, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
perl_run(uperl.main[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -595,6 +595,32 @@ void uwsgi_perl_enable_threads(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int uwsgi_perl_signal_handler(uint8_t sig, void *handler) {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
dSP;
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
PUSHMARK(SP);
|
||||
XPUSHs( sv_2mortal(newSViv(sig)));
|
||||
PUTBACK;
|
||||
|
||||
call_sv( SvRV((SV*)handler), G_DISCARD);
|
||||
|
||||
if(SvTRUE(ERRSV)) {
|
||||
uwsgi_log("[uwsgi-perl error] %s\n", SvPV_nolen(ERRSV));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
SPAGAIN;
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin psgi_plugin = {
|
||||
|
||||
.name = "psgi",
|
||||
@@ -606,6 +632,9 @@ struct uwsgi_plugin psgi_plugin = {
|
||||
.mount_app = uwsgi_perl_mount_app,
|
||||
|
||||
.init_thread = uwsgi_perl_init_thread,
|
||||
.signal_handler = uwsgi_perl_signal_handler,
|
||||
|
||||
.mule = uwsgi_perl_mule,
|
||||
|
||||
.post_fork = uwsgi_perl_post_fork,
|
||||
.request = uwsgi_perl_request,
|
||||
|
||||
@@ -59,6 +59,11 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SvTYPE(response) != SVt_PVAV) {
|
||||
uwsgi_log("invalid PSGI response type\n");
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
status_code = av_fetch(response, 0, 0);
|
||||
if (!status_code) { uwsgi_log("invalid PSGI status code\n"); return UWSGI_OK;}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "psgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_plugin psgi_plugin;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
|
||||
@@ -149,6 +150,27 @@ clear:
|
||||
|
||||
}
|
||||
|
||||
XS(XS_register_signal) {
|
||||
dXSARGS;
|
||||
|
||||
if (!uwsgi.master_process) {
|
||||
XSRETURN_NO;
|
||||
}
|
||||
|
||||
psgi_check_args(3);
|
||||
|
||||
uint8_t signum = SvIV(ST(0));
|
||||
STRLEN kindlen;
|
||||
char *kind = SvPV(ST(1), kindlen);
|
||||
|
||||
if (uwsgi_register_signal(signum, kind, (void *) newRV_inc(ST(2)), psgi_plugin.modifier1)) {
|
||||
XSRETURN_NO;
|
||||
}
|
||||
|
||||
XSRETURN_YES;
|
||||
|
||||
}
|
||||
|
||||
XS(XS_log) {
|
||||
|
||||
dXSARGS;
|
||||
@@ -219,6 +241,33 @@ XS(XS_suspend) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
XS(XS_signal_wait) {
|
||||
|
||||
dXSARGS;
|
||||
|
||||
psgi_check_args(0);
|
||||
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
int received_signal = -1;
|
||||
|
||||
wsgi_req->signal_received = -1;
|
||||
|
||||
if (items > 0) {
|
||||
received_signal = uwsgi_signal_wait(SvIV(ST(0)));
|
||||
}
|
||||
else {
|
||||
received_signal = uwsgi_signal_wait(-1);
|
||||
}
|
||||
|
||||
if (received_signal < 0) {
|
||||
XSRETURN_NO;
|
||||
}
|
||||
|
||||
wsgi_req->signal_received = received_signal;
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
void init_perl_embedded_module() {
|
||||
psgi_xs(reload);
|
||||
psgi_xs(cache_set);
|
||||
@@ -231,5 +280,7 @@ void init_perl_embedded_module() {
|
||||
psgi_xs(async_connect);
|
||||
psgi_xs(suspend);
|
||||
psgi_xs(signal);
|
||||
psgi_xs(register_signal);
|
||||
psgi_xs(signal_wait);
|
||||
}
|
||||
|
||||
|
||||
@@ -804,7 +804,7 @@ PyObject *py_uwsgi_offload_transfer(PyObject * self, PyObject * args) {
|
||||
|
||||
|
||||
UWSGI_RELEASE_GIL
|
||||
if (uwsgi_offload_request_do(wsgi_req, filename, len)) {
|
||||
if (uwsgi_offload_request_sendfile_do(wsgi_req, filename, len)) {
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_ValueError, "Unable to offload the request");
|
||||
}
|
||||
|
||||
@@ -1024,10 +1024,21 @@ VALUE init_rack_app( VALUE script ) {
|
||||
VALUE rack = rb_const_get(rb_cObject, rb_intern("Rack"));
|
||||
|
||||
#ifdef RUBY19
|
||||
if (rb_eval_string("module Rack;class BodyProxy;def each(&block);@body.each(&block);end;end;end")) {
|
||||
if (uwsgi.mywid <= 1) {
|
||||
uwsgi_log("Rack::BodyProxy successfully patched for ruby 1.9.x\n");
|
||||
}
|
||||
if (rb_funcall(rack, rb_intern("const_defined?"), 1, ID2SYM(rb_intern("BodyProxy"))) == Qtrue) {
|
||||
VALUE bodyproxy = rb_const_get(rack, rb_intern("BodyProxy"));
|
||||
// get the list of available instance_methods
|
||||
VALUE argv = Qfalse;
|
||||
VALUE methods_list = rb_class_instance_methods(1, &argv, bodyproxy);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s\n", RSTRING_PTR(rb_inspect(methods_list)));
|
||||
#endif
|
||||
if (rb_ary_includes(methods_list, ID2SYM(rb_intern("each"))) == Qfalse) {
|
||||
if (rb_eval_string("module Rack;class BodyProxy;def each(&block);@body.each(&block);end;end;end")) {
|
||||
if (uwsgi.mywid <= 1) {
|
||||
uwsgi_log("Rack::BodyProxy successfully patched for ruby 1.9.x\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+290
-20
@@ -2,65 +2,335 @@
|
||||
|
||||
uWSGI rawrouter
|
||||
|
||||
requires:
|
||||
|
||||
- async
|
||||
- caching
|
||||
- pcre (optional)
|
||||
|
||||
*/
|
||||
|
||||
#include "../../uwsgi.h"
|
||||
#include "../corerouter/cr.h"
|
||||
|
||||
struct uwsgi_rawrouter {
|
||||
struct uwsgi_corerouter cr;
|
||||
int xclient;
|
||||
} urr;
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#include "rr.h"
|
||||
|
||||
struct uwsgi_rawrouter urr;
|
||||
|
||||
struct rawrouter_session {
|
||||
struct corerouter_session crs;
|
||||
in_addr_t ip_addr;
|
||||
// XCLIENT ADDR=xxx\r\n
|
||||
char xclient[13+INET_ADDRSTRLEN+2];
|
||||
size_t xclient_len;
|
||||
off_t xclient_pos;
|
||||
size_t xclient_remains;
|
||||
// placeholder for \r\n
|
||||
size_t xclient_rn;
|
||||
};
|
||||
|
||||
struct uwsgi_option rawrouter_options[] = {
|
||||
{"rawrouter", required_argument, 0, "run the rawrouter on the specified port", uwsgi_opt_corerouter, &urr, 0},
|
||||
{"rawrouter", required_argument, 0, "run the rawrouter on the specified port", uwsgi_opt_undeferred_corerouter, &urr, 0},
|
||||
{"rawrouter-processes", required_argument, 0, "prefork the specified number of rawrouter processes", uwsgi_opt_set_int, &urr.cr.processes, 0},
|
||||
{"rawrouter-workers", required_argument, 0, "prefork the specified number of rawrouter processes", uwsgi_opt_set_int, &urr.cr.processes, 0},
|
||||
{"rawrouter-zerg", required_argument, 0, "attach the rawrouter to a zerg server", uwsgi_opt_corerouter_zerg, &urr, 0 },
|
||||
{"rawrouter-use-cache", no_argument, 0, "use uWSGI cache as address->server mapper for the rawrouter", uwsgi_opt_true, &urr.cr.use_cache, 0},
|
||||
{"rawrouter-zerg", required_argument, 0, "attach the rawrouter to a zerg server", uwsgi_opt_corerouter_zerg, &urr, 0},
|
||||
{"rawrouter-use-cache", no_argument, 0, "use uWSGI cache as hostname->server mapper for the rawrouter", uwsgi_opt_true, &urr.cr.use_cache, 0},
|
||||
|
||||
{"rawrouter-use-pattern", required_argument, 0, "use a pattern for rawrouter address->server mapping", uwsgi_opt_corerouter_use_pattern, &urr, 0},
|
||||
{"rawrouter-use-base", required_argument, 0, "use a base dir for rawrouter address->server mapping", uwsgi_opt_corerouter_use_base, &urr, 0},
|
||||
{"rawrouter-use-pattern", required_argument, 0, "use a pattern for rawrouter hostname->server mapping", uwsgi_opt_corerouter_use_pattern, &urr, 0},
|
||||
{"rawrouter-use-base", required_argument, 0, "use a base dir for rawrouter hostname->server mapping", uwsgi_opt_corerouter_use_base, &urr, 0},
|
||||
|
||||
{"rawrouter-fallback", required_argument, 0, "fallback to the specified node in case of error", uwsgi_opt_add_string_list, &urr.cr.fallback, 0},
|
||||
|
||||
|
||||
{"rawrouter-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &urr.cr.use_cluster, 0},
|
||||
|
||||
{"rawrouter-use-code-string", required_argument, 0, "use code string as address->server mapper for the rawrouter", uwsgi_opt_corerouter_cs, &urr, 0},
|
||||
{"rawrouter-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the rawrouter", uwsgi_opt_corerouter_cs, &urr, 0},
|
||||
{"rawrouter-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &urr, 0},
|
||||
{"rawrouter-to", required_argument, 0, "forward requests to the specified uwsgi server (you can specify it multiple times for load balancing)", uwsgi_opt_add_string_list, &urr.cr.static_nodes, 0},
|
||||
{"rawrouter-gracetime", required_argument, 0, "retry connections to dead static nodes after the specified amount of seconds", uwsgi_opt_set_int, &urr.cr.static_node_gracetime, 0},
|
||||
{"rawrouter-events", required_argument, 0, "set the maximum number of concurrent events", uwsgi_opt_set_int, &urr.cr.nevents, 0},
|
||||
{"rawrouter-max-retries", required_argument, 0, "set the maximum number of retries/fallbacks to other nodes", uwsgi_opt_set_int, &urr.cr.max_retries, 0},
|
||||
{"rawrouter-quiet", required_argument, 0, "do not report failed connections to instances", uwsgi_opt_true, &urr.cr.quiet, 0},
|
||||
{"rawrouter-cheap", no_argument, 0, "run the rawrouter in cheap mode", uwsgi_opt_true, &urr.cr.cheap, 0},
|
||||
{"rawrouter-subscription-server", required_argument, 0, "run the rawrouter subscription server on the spcified address", uwsgi_opt_corerouter_ss, &urr, 0},
|
||||
{"rawrouter-subscription-slot", required_argument, 0, "*** deprecated ***", uwsgi_opt_deprecated, (void *) "useless thanks to the new implementation", 0},
|
||||
|
||||
{"rawrouter-timeout", required_argument, 0, "set rawrouter timeout", uwsgi_opt_set_int, &urr.cr.socket_timeout, 0},
|
||||
|
||||
{"rawrouter-stats", required_argument, 0, "run the rawrouter stats server", uwsgi_opt_set_str, &urr.cr.stats_server, 0},
|
||||
{"rawrouter-stats-server", required_argument, 0, "run the rawrouter stats server", uwsgi_opt_set_str, &urr.cr.stats_server, 0},
|
||||
{"rawrouter-ss", required_argument, 0, "run the rawrouter stats server", uwsgi_opt_set_str, &urr.cr.stats_server, 0},
|
||||
{"rawrouter-harakiri", required_argument, 0, "enable rawrouter harakiri", uwsgi_opt_set_int, &urr.cr.harakiri, 0},
|
||||
|
||||
{"rawrouter-xclient", no_argument, 0, "use the xclient protocol to pass the client addres", uwsgi_opt_true, &urr.xclient, 0},
|
||||
|
||||
{"rawrouter-harakiri", required_argument, 0, "enable rawrouter harakiri", uwsgi_opt_set_int, &urr.cr.harakiri, 0 },
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
ssize_t rr_instance_read(struct corerouter_session *);
|
||||
ssize_t rr_read(struct corerouter_session *);
|
||||
|
||||
// write to backend
|
||||
ssize_t rr_instance_write(struct corerouter_session * cs) {
|
||||
ssize_t len = write(cs->instance_fd, cs->buffer->buf + cs->buffer_pos, cs->buffer_len - cs->buffer_pos);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
uwsgi_error("fr_instance_write()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cs->buffer_pos += len;
|
||||
|
||||
// the chunk has been sent, start (again) reading from client and instance
|
||||
if (cs->buffer_pos == (ssize_t) cs->buffer_len) {
|
||||
uwsgi_cr_hook_instance_write(cs, NULL);
|
||||
uwsgi_cr_hook_instance_read(cs, rr_instance_read);
|
||||
uwsgi_cr_hook_read(cs, rr_read);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// write to client
|
||||
ssize_t rr_write(struct corerouter_session * cs) {
|
||||
ssize_t len = write(cs->fd, cs->buffer->buf + cs->buffer_pos, cs->buffer_len - cs->buffer_pos);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
uwsgi_error("rr_write()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cs->buffer_pos += len;
|
||||
|
||||
// ok this response chunk is sent, let's wait for another one
|
||||
if (cs->buffer_pos == (ssize_t) cs->buffer_len) {
|
||||
uwsgi_cr_hook_write(cs, NULL);
|
||||
uwsgi_cr_hook_instance_read(cs, rr_instance_read);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t rr_instance_read(struct corerouter_session * cs) {
|
||||
ssize_t len = read(cs->instance_fd, cs->buffer->buf, cs->buffer->len);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
uwsgi_error("rr_instance_read()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// end of the response
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cs->buffer_pos = 0;
|
||||
cs->buffer_len = len;
|
||||
// ok stop reading from the instance, and start writing to the client
|
||||
uwsgi_cr_hook_instance_read(cs, NULL);
|
||||
uwsgi_cr_hook_write(cs, rr_write);
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t rr_xclient_write(struct corerouter_session *);
|
||||
|
||||
ssize_t rr_xclient_read(struct corerouter_session * cs) {
|
||||
struct rawrouter_session *rr = (struct rawrouter_session *) cs;
|
||||
cs->buffer_len = cs->buffer->len;
|
||||
ssize_t len = read(cs->instance_fd, cs->buffer->buf + cs->buffer_pos, cs->buffer_len - cs->buffer_pos);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
uwsgi_error("rr_xclient_read()");
|
||||
return -1;
|
||||
}
|
||||
if (len == 0) return 0;
|
||||
|
||||
char *ptr = cs->buffer->buf + cs->buffer_pos;
|
||||
ssize_t i;
|
||||
for(i=0;i<len;i++) {
|
||||
if (rr->xclient_rn == 1) {
|
||||
if (ptr[i] != '\n') {
|
||||
return -1;
|
||||
}
|
||||
// banner received
|
||||
cs->buffer_pos = len - (i+1);
|
||||
uwsgi_cr_hook_instance_read(cs, NULL);
|
||||
uwsgi_cr_hook_instance_write(cs, rr_xclient_write);
|
||||
return len;
|
||||
}
|
||||
else if (ptr[i] == '\r') {
|
||||
rr->xclient_rn = 1;
|
||||
}
|
||||
}
|
||||
|
||||
cs->buffer_pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t rr_xclient_write(struct corerouter_session * cs) {
|
||||
struct rawrouter_session *rr = (struct rawrouter_session *) cs;
|
||||
ssize_t len = write(cs->instance_fd, rr->xclient + rr->xclient_pos, rr->xclient_len - rr->xclient_pos);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
uwsgi_error("rr_xclient_write()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rr->xclient_pos += len;
|
||||
if (rr->xclient_pos == (ssize_t) rr->xclient_len) {
|
||||
uwsgi_cr_hook_instance_write(cs, NULL);
|
||||
if (cs->buffer_pos > 0) {
|
||||
// send remaining data...
|
||||
uwsgi_cr_hook_write(cs, rr_write);
|
||||
}
|
||||
else {
|
||||
uwsgi_cr_hook_instance_read(cs, rr_instance_read);
|
||||
uwsgi_cr_hook_read(cs, rr_read);
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t rr_instance_connected(struct corerouter_session * cs) {
|
||||
|
||||
cs->connecting = 0;
|
||||
|
||||
socklen_t solen = sizeof(int);
|
||||
|
||||
// first check for errors
|
||||
if (getsockopt(cs->instance_fd, SOL_SOCKET, SO_ERROR, (void *) (&cs->soopt), &solen) < 0) {
|
||||
uwsgi_error("rr_instance_connected()/getsockopt()");
|
||||
cs->instance_failed = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cs->soopt) {
|
||||
cs->instance_failed = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cs->buffer_pos = 0;
|
||||
|
||||
// ok instance is connected, begin...
|
||||
if (cs->static_node) cs->static_node->custom2++;
|
||||
if (cs->un) cs->un->requests++;
|
||||
|
||||
uwsgi_cr_hook_instance_write(cs, NULL);
|
||||
if (urr.xclient) {
|
||||
uwsgi_cr_hook_instance_read(cs, rr_xclient_read);
|
||||
return 1;
|
||||
}
|
||||
uwsgi_cr_hook_instance_read(cs, rr_instance_read);
|
||||
uwsgi_cr_hook_read(cs, rr_read);
|
||||
// return a value > 0
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t rr_read(struct corerouter_session * cs) {
|
||||
ssize_t len = read(cs->fd, cs->buffer->buf, cs->buffer->len);
|
||||
if (len < 0) {
|
||||
cr_try_again;
|
||||
uwsgi_error("rr_recv()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len == 0) return 0;
|
||||
|
||||
cs->buffer_pos = 0;
|
||||
cs->buffer_len = len;
|
||||
|
||||
uwsgi_cr_hook_read(cs, NULL);
|
||||
uwsgi_cr_hook_instance_read(cs, NULL);
|
||||
uwsgi_cr_hook_instance_write(cs, rr_instance_write);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int rr_retry(struct uwsgi_corerouter *ucr, struct corerouter_session *cs) {
|
||||
|
||||
if (cs->instance_address_len > 0) goto retry;
|
||||
|
||||
if (ucr->mapper(ucr, cs)) {
|
||||
cs->instance_failed = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cs->instance_address_len == 0) {
|
||||
cs->instance_failed = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
retry:
|
||||
// start async connect
|
||||
cs->instance_fd = uwsgi_connectn(cs->instance_address, cs->instance_address_len, 0, 1);
|
||||
if (cs->instance_fd < 0) {
|
||||
cs->instance_failed = 1;
|
||||
cs->soopt = errno;
|
||||
return -1;
|
||||
}
|
||||
// map the instance
|
||||
cs->corerouter->cr_table[cs->instance_fd] = cs;
|
||||
// wait for connection
|
||||
cs->connecting = 1;
|
||||
// wait for connection
|
||||
uwsgi_cr_hook_instance_write(cs, rr_instance_connected);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rawrouter_alloc_session(struct uwsgi_corerouter *ucr, struct uwsgi_gateway_socket *ugs, struct corerouter_session *cs, struct sockaddr *sa, socklen_t s_len) {
|
||||
|
||||
// use the address as hostname
|
||||
cs->hostname = cs->ugs->name;
|
||||
cs->hostname_len = cs->ugs->name_len;
|
||||
|
||||
if (sa && sa->sa_family == AF_INET) {
|
||||
struct rawrouter_session *rr = (struct rawrouter_session *) cs;
|
||||
rr->ip_addr = ((struct sockaddr_in *) sa)->sin_addr.s_addr;
|
||||
if (urr.xclient) {
|
||||
if (!inet_ntop(AF_INET, &rr->ip_addr, rr->xclient+13, INET_ADDRSTRLEN)) {
|
||||
uwsgi_error("rawrouter_alloc_session() -> inet_ntop()");
|
||||
cs->instance_failed = 1;
|
||||
return;
|
||||
}
|
||||
// fix string
|
||||
size_t ip_addr_len = strlen(rr->xclient+13);
|
||||
memcpy(rr->xclient,"XCLIENT ADDR=", 13);
|
||||
rr->xclient[13+ip_addr_len] = '\r';
|
||||
rr->xclient[13+ip_addr_len+1] = '\n';
|
||||
rr->xclient_len = 13 + ip_addr_len + 2;
|
||||
}
|
||||
}
|
||||
|
||||
// the mapper hook
|
||||
if (ucr->mapper(ucr, cs)) {
|
||||
cs->instance_failed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cs->instance_address_len == 0) {
|
||||
cs->instance_failed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// ok, now we could retry
|
||||
cs->retry = rr_retry;
|
||||
|
||||
// start async connect
|
||||
cs->instance_fd = uwsgi_connectn(cs->instance_address, cs->instance_address_len, 0, 1);
|
||||
if (cs->instance_fd < 0) {
|
||||
cs->instance_failed = 1;
|
||||
cs->soopt = errno;
|
||||
return;
|
||||
}
|
||||
// map the instance
|
||||
cs->corerouter->cr_table[cs->instance_fd] = cs;
|
||||
// wait for connection
|
||||
cs->connecting = 1;
|
||||
uwsgi_cr_hook_instance_write(cs, rr_instance_connected);
|
||||
}
|
||||
|
||||
int rawrouter_init() {
|
||||
|
||||
urr.cr.session_size = sizeof(struct rawrouter_session);
|
||||
urr.cr.switch_events = uwsgi_rawrouter_switch_events;
|
||||
urr.cr.alloc_session = rawrouter_alloc_session;
|
||||
uwsgi_corerouter_init((struct uwsgi_corerouter *) &urr);
|
||||
uwsgi_corerouter_init((struct uwsgi_corerouter *) &urr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "../corerouter/cr.h"
|
||||
|
||||
|
||||
struct uwsgi_rawrouter {
|
||||
|
||||
struct uwsgi_corerouter cr;
|
||||
|
||||
};
|
||||
|
||||
struct rawrouter_session {
|
||||
|
||||
struct corerouter_session crs;
|
||||
};
|
||||
|
||||
void uwsgi_rawrouter_switch_events(struct uwsgi_corerouter *, struct corerouter_session *, int interesting_fd);
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
#include "rr.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_rawrouter urr;
|
||||
|
||||
void uwsgi_rawrouter_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_session *cs, int interesting_fd) {
|
||||
|
||||
socklen_t solen = sizeof(int);
|
||||
ssize_t len;
|
||||
char buf[8192];
|
||||
|
||||
switch (cs->status) {
|
||||
|
||||
case COREROUTER_STATUS_RECV_HDR:
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(ucr->queue, cs->fd);
|
||||
#endif
|
||||
// use the address as hostname
|
||||
cs->hostname = cs->ugs->name;
|
||||
cs->hostname_len = cs->ugs->name_len;
|
||||
|
||||
// the mapper hook
|
||||
if (ucr->mapper(ucr, cs))
|
||||
break;
|
||||
|
||||
// no address found
|
||||
if (!cs->instance_address_len) {
|
||||
// if fallback nodes are configured, trigger them
|
||||
if (ucr->fallback) {
|
||||
cs->instance_failed = 1;
|
||||
}
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
cs->instance_fd = uwsgi_connectn(cs->instance_address, cs->instance_address_len, 0, 1);
|
||||
|
||||
if (cs->instance_fd < 0) {
|
||||
cs->instance_failed = 1;
|
||||
cs->soopt = errno;
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
cs->status = COREROUTER_STATUS_CONNECTING;
|
||||
ucr->cr_table[cs->instance_fd] = cs;
|
||||
event_queue_add_fd_write(ucr->queue, cs->instance_fd);
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case COREROUTER_STATUS_CONNECTING:
|
||||
|
||||
if (interesting_fd == cs->instance_fd) {
|
||||
|
||||
if (getsockopt(cs->instance_fd, SOL_SOCKET, SO_ERROR, (void *) (&cs->soopt), &solen) < 0) {
|
||||
uwsgi_error("getsockopt()");
|
||||
cs->instance_failed = 1;
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cs->soopt) {
|
||||
cs->instance_failed = 1;
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
// increment node requests counter
|
||||
if (cs->un)
|
||||
cs->un->requests++;
|
||||
|
||||
event_queue_fd_write_to_read(ucr->queue, cs->instance_fd);
|
||||
cs->status = COREROUTER_STATUS_RESPONSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COREROUTER_STATUS_RESPONSE:
|
||||
|
||||
// data from instance
|
||||
if (interesting_fd == cs->instance_fd) {
|
||||
len = recv(cs->instance_fd, buf, 8192, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(ucr->queue, cs->instance_fd);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
if (len < 0)
|
||||
uwsgi_error("recv()");
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
len = send(cs->fd, buf, len, 0);
|
||||
|
||||
if (len <= 0) {
|
||||
if (len < 0)
|
||||
uwsgi_error("send()");
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
// update transfer statistics
|
||||
if (cs->un)
|
||||
cs->un->transferred += len;
|
||||
}
|
||||
// body from client
|
||||
else if (interesting_fd == cs->fd) {
|
||||
|
||||
//uwsgi_log("receiving body...\n");
|
||||
len = recv(cs->fd, buf, 8192, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(ucr->queue, cs->fd);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
if (len < 0)
|
||||
uwsgi_error("recv()");
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
len = send(cs->instance_fd, buf, len, 0);
|
||||
|
||||
if (len <= 0) {
|
||||
if (len < 0)
|
||||
uwsgi_error("send()");
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// fallback to destroy !!!
|
||||
default:
|
||||
uwsgi_log("unknown event: closing session\n");
|
||||
corerouter_close_session(ucr, cs);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,4 @@ LIBS = []
|
||||
|
||||
REQUIRES = ['corerouter']
|
||||
|
||||
GCC_LIST = ['rawrouter', 'rr_events']
|
||||
GCC_LIST = ['rawrouter']
|
||||
|
||||
@@ -12,6 +12,21 @@ int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *u
|
||||
// get the http address from the route
|
||||
char *addr = ur->data;
|
||||
|
||||
// convert the wsgi_request to an http proxy request
|
||||
struct uwsgi_buffer *ub = uwsgi_to_http(wsgi_req, ur->data2, ur->data2_len);
|
||||
if (!ub) {
|
||||
uwsgi_log("unable to generate http request for %s\n", addr);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
// ok now if have offload threads, directly use them
|
||||
if (wsgi_req->socket->can_offload) {
|
||||
if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) {
|
||||
wsgi_req->status = -30;
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
// connect to the http server
|
||||
int http_fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
if (http_fd < 0) {
|
||||
@@ -19,14 +34,6 @@ int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *u
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
// convert the wsgi_request to an http proxy request
|
||||
struct uwsgi_buffer *ub = uwsgi_to_http(wsgi_req, ur->data2, ur->data2_len);
|
||||
if (!ub) {
|
||||
uwsgi_log("unable to generate http request for %s\n", addr);
|
||||
close(http_fd);
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
}
|
||||
|
||||
// send the request
|
||||
if (uwsgi_buffer_send(ub, http_fd)) {
|
||||
uwsgi_log("error routing request to http server %s\n", addr);
|
||||
|
||||
@@ -5,6 +5,8 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
|
||||
|
||||
char *tmp_qs = NULL;
|
||||
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
|
||||
|
||||
@@ -18,28 +20,26 @@ int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route
|
||||
path_info_len = query_string - path_info;
|
||||
query_string++;
|
||||
query_string_len = strlen(query_string);
|
||||
|
||||
if (wsgi_req->query_string_len > 0) {
|
||||
tmp_qs = uwsgi_concat4n(query_string, query_string_len, "&", 1, wsgi_req->query_string, wsgi_req->query_string_len, "", 0);
|
||||
query_string = tmp_qs;
|
||||
query_string_len = strlen(query_string);
|
||||
}
|
||||
}
|
||||
// over engineering, could be requiredin the future...
|
||||
else {
|
||||
query_string = "";
|
||||
if (wsgi_req->query_string_len > 0) {
|
||||
query_string = wsgi_req->query_string;
|
||||
query_string_len = wsgi_req->query_string_len;
|
||||
}
|
||||
else {
|
||||
query_string = "";
|
||||
}
|
||||
}
|
||||
|
||||
char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, path_info, path_info_len);
|
||||
if (!ptr) goto clear;
|
||||
|
||||
// fill iovec
|
||||
if (wsgi_req->var_cnt + 2 >= uwsgi.vec_size - (4 + 1)) {
|
||||
uwsgi_log("not enough io vectors for rewriting url\n");
|
||||
goto clear;
|
||||
}
|
||||
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptr - (2 + 9);
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = 9;
|
||||
wsgi_req->var_cnt++;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptr;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = path_info_len;
|
||||
wsgi_req->var_cnt++;
|
||||
|
||||
// set new path_info
|
||||
wsgi_req->path_info = ptr;
|
||||
wsgi_req->path_info_len = path_info_len;
|
||||
@@ -47,31 +47,19 @@ int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route
|
||||
ptr = uwsgi_req_append(wsgi_req, "QUERY_STRING", 12, query_string, query_string_len);
|
||||
if (!ptr) goto clear;
|
||||
|
||||
// fill iovec
|
||||
if (wsgi_req->var_cnt + 2 >= uwsgi.vec_size - (4 + 1)) {
|
||||
uwsgi_log("not enough io vectors for rewriting url\n");
|
||||
goto clear;
|
||||
}
|
||||
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptr - (2 + 12);
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = 12;
|
||||
wsgi_req->var_cnt++;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptr;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = query_string_len;
|
||||
wsgi_req->var_cnt++;
|
||||
|
||||
|
||||
// set new query_string
|
||||
wsgi_req->query_string = ptr;
|
||||
wsgi_req->query_string_len = query_string_len;
|
||||
|
||||
free(path_info);
|
||||
if (tmp_qs) free(tmp_qs);
|
||||
if (ur->custom)
|
||||
return UWSGI_ROUTE_CONTINUE;
|
||||
return UWSGI_ROUTE_NEXT;
|
||||
|
||||
clear:
|
||||
free(path_info);
|
||||
if (tmp_qs) free(tmp_qs);
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,23 @@ int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
uwsgi_req_append(wsgi_req, "UWSGI_APPID", 11, ur->data2, ur->data2_len);
|
||||
}
|
||||
|
||||
// ok now if have offload threads, directly use them
|
||||
if (wsgi_req->socket->can_offload) {
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh.pktsize);
|
||||
if (ub) {
|
||||
uh->pktsize = wsgi_req->uh.pktsize;
|
||||
if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto bad;
|
||||
if (uwsgi_buffer_append(ub, wsgi_req->buffer, uh->pktsize)) goto bad;
|
||||
if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) {
|
||||
wsgi_req->status = -30;
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
bad:
|
||||
uwsgi_buffer_destroy(ub);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
if (uwsgi_fd < 0) {
|
||||
uwsgi_log("unable to connect to host %s\n", addr);
|
||||
|
||||
@@ -19,6 +19,14 @@ my $two = sub {
|
||||
print "two\n";
|
||||
};
|
||||
|
||||
my $four = sub {
|
||||
my $signum = shift;
|
||||
print "i am signal ".$signum."\n" ;
|
||||
};
|
||||
|
||||
uwsgi::register_signal(17, '', $four);
|
||||
uwsgi::register_signal(30, '', $two);
|
||||
|
||||
my $three = sub {
|
||||
my $env = shift;
|
||||
sleep(1);
|
||||
@@ -27,6 +35,9 @@ my $three = sub {
|
||||
|
||||
my $app = sub {
|
||||
my $env = shift;
|
||||
uwsgi::signal(17);
|
||||
uwsgi::signal(30);
|
||||
|
||||
if ($env->{'psgix.cleanup'}) {
|
||||
print "cleanup supported\n";
|
||||
push @{$env->{'psgix.cleanup.handlers'}}, $one;
|
||||
|
||||
@@ -37,7 +37,7 @@ extern "C" {
|
||||
#define thunder_lock if (uwsgi.threads > 1 && !uwsgi.is_et) {pthread_mutex_lock(&uwsgi.thunder_mutex);}
|
||||
#define thunder_unlock if (uwsgi.threads > 1 && !uwsgi.is_et) {pthread_mutex_unlock(&uwsgi.thunder_mutex);}
|
||||
|
||||
#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5) || !uwsgi_startswith(file, "exec://", 7) || !uwsgi_startswith(file, "section://", 10))
|
||||
#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "emperor://", 10) || !uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5) || !uwsgi_startswith(file, "exec://", 7) || !uwsgi_startswith(file, "section://", 10))
|
||||
|
||||
#define ushared uwsgi.shared
|
||||
|
||||
@@ -308,6 +308,7 @@ struct uwsgi_string_list {
|
||||
char *value;
|
||||
size_t len;
|
||||
uint64_t custom;
|
||||
uint64_t custom2;
|
||||
struct uwsgi_string_list *next;
|
||||
};
|
||||
|
||||
@@ -441,6 +442,8 @@ struct uwsgi_gateway_socket {
|
||||
char *port;
|
||||
int port_len;
|
||||
|
||||
int no_defer;
|
||||
|
||||
void *data;
|
||||
// this requires UDP
|
||||
int subscription;
|
||||
@@ -638,6 +641,7 @@ struct uwsgi_socket {
|
||||
void *ctx;
|
||||
|
||||
int queue;
|
||||
int no_defer;
|
||||
|
||||
int auto_port;
|
||||
// true if connection must be initialized for each core
|
||||
@@ -1214,6 +1218,7 @@ struct uwsgi_server {
|
||||
|
||||
// enable threads
|
||||
int has_threads;
|
||||
int no_threads_wait;
|
||||
|
||||
// default app id
|
||||
int default_app;
|
||||
@@ -1472,6 +1477,7 @@ struct uwsgi_server {
|
||||
struct uwsgi_string_list *requested_logger;
|
||||
|
||||
#ifdef UWSGI_PCRE
|
||||
int pcre_jit;
|
||||
struct uwsgi_regexp_list *log_drain_rules;
|
||||
struct uwsgi_regexp_list *log_filter_rules;
|
||||
struct uwsgi_regexp_list *log_route;
|
||||
@@ -1517,12 +1523,11 @@ struct uwsgi_server {
|
||||
struct uwsgi_dyn_dict *static_expires_path_info;
|
||||
struct uwsgi_dyn_dict *static_expires_path_info_mtime;
|
||||
|
||||
int offload_threads;
|
||||
int offload_threads_events;
|
||||
struct uwsgi_thread **offload_thread;
|
||||
|
||||
int check_static_docroot;
|
||||
int static_offload_to_thread;
|
||||
struct uwsgi_thread *offload_thread;
|
||||
// linked list for offloaded requests
|
||||
struct uwsgi_offload_request *offload_requests_head;
|
||||
struct uwsgi_offload_request *offload_requests_tail;
|
||||
|
||||
char *daemonize;
|
||||
char *daemonize2;
|
||||
@@ -2053,12 +2058,17 @@ struct uwsgi_core {
|
||||
//time_t harakiri;
|
||||
|
||||
uint64_t requests;
|
||||
uint64_t failed_requests;
|
||||
uint64_t failed_requests;
|
||||
uint64_t static_requests;
|
||||
uint64_t routed_requests;
|
||||
uint64_t offloaded_requests;
|
||||
|
||||
#ifdef UWSGI_THREADING
|
||||
pthread_t thread_id;
|
||||
#endif
|
||||
|
||||
int offload_rr;
|
||||
|
||||
// one ts-perapp
|
||||
void **ts;
|
||||
|
||||
@@ -2985,6 +2995,7 @@ void uwsgi_opt_set_str_spaced(char *, char *, void *);
|
||||
void uwsgi_opt_add_string_list(char *, char *, void *);
|
||||
void uwsgi_opt_add_dyn_dict(char *, char *, void *);
|
||||
#ifdef UWSGI_PCRE
|
||||
void uwsgi_opt_pcre_jit(char *, char *, void *);
|
||||
void uwsgi_opt_add_regexp_dyn_dict(char *, char *, void *);
|
||||
void uwsgi_opt_add_regexp_list(char *, char *, void *);
|
||||
void uwsgi_opt_add_regexp_custom_list(char *, char *, void *);
|
||||
@@ -3139,6 +3150,7 @@ int uwsgi_try_autoload(char *);
|
||||
|
||||
uint64_t uwsgi_micros(void);
|
||||
int uwsgi_is_file(char *);
|
||||
int uwsgi_is_link(char *);
|
||||
|
||||
void uwsgi_receive_signal(int, char *, int);
|
||||
void uwsgi_exec_atexit(void);
|
||||
@@ -3170,6 +3182,7 @@ struct uwsgi_stats_pusher_instance {
|
||||
struct uwsgi_stats_pusher_instance *next;
|
||||
};
|
||||
|
||||
struct uwsgi_thread;
|
||||
void uwsgi_stats_pusher_loop(struct uwsgi_thread *);
|
||||
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *, char *, size_t);
|
||||
void uwsgi_stats_pusher_socket(struct uwsgi_stats_pusher_instance *, char *, size_t);
|
||||
@@ -3392,25 +3405,42 @@ struct uwsgi_thread {
|
||||
uint64_t custom1;
|
||||
uint64_t custom2;
|
||||
uint64_t custom3;
|
||||
// linked list for offloaded requests
|
||||
struct uwsgi_offload_request *offload_requests_head;
|
||||
struct uwsgi_offload_request *offload_requests_tail;
|
||||
void (*func)(struct uwsgi_thread *);
|
||||
};
|
||||
struct uwsgi_thread *uwsgi_thread_new(void (*)(struct uwsgi_thread *));
|
||||
|
||||
struct uwsgi_offload_request {
|
||||
// the request socket
|
||||
int s;
|
||||
// the peer
|
||||
int fd;
|
||||
|
||||
// internal state
|
||||
int status;
|
||||
|
||||
off_t pos;
|
||||
char *buf;
|
||||
off_t buf_pos;
|
||||
|
||||
size_t to_write;
|
||||
size_t len;
|
||||
size_t written;
|
||||
|
||||
// a uwsgi_buffer (will be destroyed at the end of the task)
|
||||
struct uwsgi_buffer *ubuf;
|
||||
|
||||
int (*func)(struct uwsgi_thread *, struct uwsgi_offload_request *, int);
|
||||
|
||||
struct uwsgi_offload_request *prev;
|
||||
struct uwsgi_offload_request *next;
|
||||
};
|
||||
|
||||
struct uwsgi_thread *uwsgi_offload_thread_start(void);
|
||||
int uwsgi_offload_request_do(struct wsgi_request *, char *, size_t);
|
||||
int uwsgi_offload_request_sendfile_do(struct wsgi_request *, char *, size_t);
|
||||
int uwsgi_offload_request_net_do(struct wsgi_request *, char *, struct uwsgi_buffer *);
|
||||
|
||||
void uwsgi_subscription_set_algo(char *);
|
||||
struct uwsgi_subscribe_slot **uwsgi_subscription_init_ht(void);
|
||||
@@ -3449,6 +3479,8 @@ void uwsgi_user_lock(int);
|
||||
void uwsgi_user_unlock(int);
|
||||
|
||||
void simple_loop_run_int(int);
|
||||
int uwsgi_valid_fd(int);
|
||||
void uwsgi_close_all_fds(void);
|
||||
|
||||
void uwsgi_check_emperor(void);
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
|
||||
+12
-6
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '1.4-dev'
|
||||
uwsgi_version = '1.4.3'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -33,15 +33,20 @@ if not GCC:
|
||||
|
||||
CPP = os.environ.get('CPP', 'cpp')
|
||||
|
||||
CPUCOUNT = 1
|
||||
try:
|
||||
import multiprocessing
|
||||
CPUCOUNT = multiprocessing.cpu_count()
|
||||
CPUCOUNT = int(os.environ.get('CPUCOUNT', -1))
|
||||
except:
|
||||
CPUCOUNT = -1
|
||||
|
||||
if CPUCOUNT < 1:
|
||||
try:
|
||||
CPUCOUNT = int(os.sysconf('SC_NPROCESSORS_ONLN'))
|
||||
import multiprocessing
|
||||
CPUCOUNT = multiprocessing.cpu_count()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
CPUCOUNT = int(os.sysconf('SC_NPROCESSORS_ONLN'))
|
||||
except:
|
||||
CPUCOUNT = 1
|
||||
|
||||
binary_list = []
|
||||
|
||||
@@ -444,6 +449,7 @@ class uConf(object):
|
||||
self.config.read(filename)
|
||||
self.gcc_list = ['core/utils', 'core/protocol', 'core/socket', 'core/logging', 'core/master', 'core/master_utils', 'core/emperor',
|
||||
'core/notify', 'core/mule', 'core/subscription', 'core/stats', 'core/sendfile',
|
||||
'core/offload',
|
||||
'core/setup_utils', 'core/clock', 'core/init', 'core/buffer',
|
||||
'core/plugins', 'core/lock', 'core/cache', 'core/daemons',
|
||||
'core/queue', 'core/event', 'core/signal', 'core/cluster',
|
||||
|
||||
Reference in New Issue
Block a user