mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ae1c6fbd1 | ||
|
|
51b9b5d070 | ||
|
|
dafe3bb12c | ||
|
|
973e508af7 | ||
|
|
8e31bb612e | ||
|
|
f920ac0fb0 | ||
|
|
ae1b5afd7d | ||
|
|
1f2bae130e | ||
|
|
4417e55862 | ||
|
|
74a84bdd3a | ||
|
|
b764252e7f | ||
|
|
2fd71be9d9 | ||
|
|
d65f873e77 | ||
|
|
1427c9ce1c | ||
|
|
c3de9320d7 | ||
|
|
674151e485 | ||
|
|
9c042ffc1c | ||
|
|
c5dc74b021 | ||
|
|
97137488f9 | ||
|
|
8cff01a1c7 | ||
|
|
3c8452313e | ||
|
|
322b130fc9 | ||
|
|
6c001c2fda | ||
|
|
5d4050817d | ||
|
|
0a1147a4f6 | ||
|
|
f92cb0e6a2 | ||
|
|
8b79c76261 | ||
|
|
0015b51262 | ||
|
|
b1dc8cd9c6 | ||
|
|
3269e2d288 | ||
|
|
71a9747d96 | ||
|
|
455d041ce4 | ||
|
|
88205f8dd1 | ||
|
|
7d9dadddf6 | ||
|
|
57e78dd76f | ||
|
|
7d0d2b33f4 | ||
|
|
03c739102d | ||
|
|
392bb8d7b1 | ||
|
|
505b35be29 | ||
|
|
fdb002ad9b | ||
|
|
557c46373f | ||
|
|
3cde8be505 | ||
|
|
c2cf1f3a62 | ||
|
|
956cb1f13c |
@@ -53,3 +53,5 @@ e1568fd16b7b586cc72deb4dfccbbe64ae0b84df 1.1
|
||||
29de0fb320bc0a1ce84972f9f249360e315d3c10 1.2-rc2
|
||||
c3cdecbf2bac591336baddd14f9ac22e18d6e200 1.2
|
||||
14524da00a8b382dffb1d16a0e70cdf4a946f369 1.3-rc2
|
||||
883b946db9038372cb1d76cb1d328a3093140e7b 1.3-rc3
|
||||
aeea5a5d2e8b62ad55e23d539e1be02f2b6962af 1.3-rc4
|
||||
|
||||
@@ -10,12 +10,27 @@
|
||||
- merged routers codebase (fastrouter, http, rawrouter)
|
||||
- https support in the http router
|
||||
- config report at the end of uWSGI build process
|
||||
- support for keepalive in the http router
|
||||
- improved subscription system (multicast and unix socket)
|
||||
- custom options
|
||||
- graceful reloads on shared sockets
|
||||
- configurable log-master buffer size
|
||||
- extreme-optimizations for the stats subsystem
|
||||
- redislog and mongodblog plugins
|
||||
- added python logger
|
||||
- mongodb and postgres imperial monitors
|
||||
- implemented psgix.logger and psgix.cleanup
|
||||
- full rack spec compliance
|
||||
- preliminary ipv6 support
|
||||
- gevent graceful reloads
|
||||
- support for multiple loggers and logformat
|
||||
- lazy-apps to load apps after fork() but without changing reloading subsystem
|
||||
- emperor heartbeat subsystem
|
||||
- cheaper busyness plugin
|
||||
- pluggable clock sources
|
||||
- added router_rewrite and router_http plugins
|
||||
- external spoolers
|
||||
- support for section:// and fd:// loaders
|
||||
- alarm subsystem (with curl and xmpp plugins)
|
||||
|
||||
|
||||
*** april 2012 ***
|
||||
|
||||
@@ -3,3 +3,6 @@ all:
|
||||
|
||||
clean:
|
||||
python uwsgiconfig.py --clean
|
||||
|
||||
check:
|
||||
python uwsgiconfig.py --check
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ async = true
|
||||
ldap = auto
|
||||
pcre = auto
|
||||
routing = auto
|
||||
alarm = auto
|
||||
ipv6 = false
|
||||
debug = false
|
||||
unbit = false
|
||||
@@ -29,7 +30,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, router_rewrite, router_http
|
||||
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
|
||||
as_shared_library = false
|
||||
|
||||
locking = auto
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
[uwsgi]
|
||||
xml = true
|
||||
ini = true
|
||||
snmp = true
|
||||
erlang = false
|
||||
spooler = true
|
||||
embedded = true
|
||||
udp = true
|
||||
multicast = true
|
||||
threading = true
|
||||
sendfile = true
|
||||
proxy = true
|
||||
minterpreters = true
|
||||
async = true
|
||||
http = true
|
||||
evdis = false
|
||||
ldap = false
|
||||
routing = false
|
||||
stackless = false
|
||||
debug = false
|
||||
unbit = false
|
||||
xml_implementation = libxml2
|
||||
plugins =
|
||||
bin_name = uwsgi
|
||||
plugin_dir = .
|
||||
embedded_plugins = python, ping, nagios, rack
|
||||
|
||||
[python]
|
||||
paste = true
|
||||
web3 = true
|
||||
@@ -1,29 +0,0 @@
|
||||
[uwsgi]
|
||||
xml = true
|
||||
ini = true
|
||||
yaml = true
|
||||
snmp = true
|
||||
erlang = false
|
||||
spooler = false
|
||||
embedded = false
|
||||
udp = true
|
||||
multicast = false
|
||||
threading = true
|
||||
sendfile = true
|
||||
nagios = true
|
||||
proxy = true
|
||||
minterpreters = true
|
||||
async = true
|
||||
ugreen = false
|
||||
http = true
|
||||
evdis = false
|
||||
ldap = false
|
||||
routing = false
|
||||
stackless = false
|
||||
debug = false
|
||||
unbit = false
|
||||
xml_implementation = libxml2
|
||||
plugins = rack
|
||||
bin_name = uwsgi
|
||||
plugin_dir = .
|
||||
embedded_plugins =
|
||||
@@ -17,6 +17,7 @@ async = true
|
||||
ldap = true
|
||||
pcre = true
|
||||
routing = true
|
||||
alarm = true
|
||||
debug = false
|
||||
unbit = true
|
||||
xml_implementation = expat
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
[uwsgi]
|
||||
xml = false
|
||||
ini = true
|
||||
yaml = false
|
||||
json = false
|
||||
sqlite3 = false
|
||||
zeromq = false
|
||||
snmp = false
|
||||
spooler = true
|
||||
embedded = true
|
||||
udp = true
|
||||
multicast = false
|
||||
threading = true
|
||||
sendfile = true
|
||||
minterpreters = true
|
||||
async = true
|
||||
evdis = false
|
||||
ldap = false
|
||||
pcre = true
|
||||
routing = true
|
||||
debug = false
|
||||
unbit = false
|
||||
xml_implementation = libxml2
|
||||
yaml_implementation = auto
|
||||
malloc_implementation = libc
|
||||
extras =
|
||||
plugins =
|
||||
bin_name = uwsgi
|
||||
append_version =
|
||||
plugin_dir = .
|
||||
embedded_plugins =
|
||||
as_shared_library = false
|
||||
|
||||
locking = auto
|
||||
event = auto
|
||||
timer = auto
|
||||
filemonitor = auto
|
||||
|
||||
blacklist =
|
||||
whitelist =
|
||||
|
||||
embed_files =
|
||||
|
||||
embed_config =
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
#include "../uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
// generate a uwsgi signal on alarm
|
||||
void uwsgi_alarm_init_signal(struct uwsgi_alarm_instance *uai) {
|
||||
uai->data8 = atoi(uai->arg);
|
||||
}
|
||||
|
||||
void uwsgi_alarm_func_signal(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
uwsgi_route_signal(uai->data8);
|
||||
}
|
||||
|
||||
// run a command on alarm
|
||||
void uwsgi_alarm_init_cmd(struct uwsgi_alarm_instance *uai) {
|
||||
uai->data_ptr = uai->arg;
|
||||
}
|
||||
|
||||
void uwsgi_alarm_func_cmd(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
int pipe[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe)) {
|
||||
return;
|
||||
}
|
||||
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]);
|
||||
return;
|
||||
}
|
||||
uwsgi_run_command(uai->data_ptr, pipe, -1);
|
||||
close(pipe[0]);
|
||||
close(pipe[1]);
|
||||
}
|
||||
|
||||
// pass the log line to a mule
|
||||
|
||||
void uwsgi_alarm_init_mule(struct uwsgi_alarm_instance *uai) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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];
|
||||
}
|
||||
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) {
|
||||
// skip already initialized alarms
|
||||
if (!strcmp(ua->name, name)) {
|
||||
return;
|
||||
}
|
||||
old_ua = ua;
|
||||
ua = ua->next;
|
||||
}
|
||||
|
||||
ua = uwsgi_calloc(sizeof(struct uwsgi_alarm));
|
||||
ua->name = name;
|
||||
ua->init = init;
|
||||
ua->func = func;
|
||||
|
||||
if (old_ua) {
|
||||
old_ua->next = ua;
|
||||
}
|
||||
else {
|
||||
uwsgi.alarms = ua;
|
||||
}
|
||||
}
|
||||
|
||||
// register embedded alarms
|
||||
void uwsgi_register_embedded_alarms() {
|
||||
uwsgi_register_alarm("signal", uwsgi_alarm_init_signal, uwsgi_alarm_func_signal);
|
||||
uwsgi_register_alarm("cmd", uwsgi_alarm_init_cmd, uwsgi_alarm_func_cmd);
|
||||
uwsgi_register_alarm("mule", uwsgi_alarm_init_mule, uwsgi_alarm_func_mule);
|
||||
}
|
||||
|
||||
static int uwsgi_alarm_add(char *name, char *plugin, char *arg) {
|
||||
struct uwsgi_alarm *ua = uwsgi.alarms;
|
||||
while(ua) {
|
||||
if (!strcmp(ua->name, plugin)) {
|
||||
break;
|
||||
}
|
||||
ua = ua->next;
|
||||
}
|
||||
|
||||
if (!ua) return -1;
|
||||
|
||||
struct uwsgi_alarm_instance *old_uai = NULL, *uai = uwsgi.alarm_instances;
|
||||
while(uai) {
|
||||
old_uai = uai;
|
||||
uai = uai->next;
|
||||
}
|
||||
|
||||
uai = uwsgi_calloc(sizeof(struct uwsgi_alarm_instance));
|
||||
uai->name = name;
|
||||
uai->alarm = ua;
|
||||
uai->arg = arg;
|
||||
uai->last_msg = uwsgi_malloc(uwsgi.log_master_bufsize);
|
||||
|
||||
if (old_uai) {
|
||||
old_uai->next = uai;
|
||||
}
|
||||
else {
|
||||
uwsgi.alarm_instances = uai;
|
||||
}
|
||||
|
||||
ua->init(uai);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (!strcmp(name, uai->name)) {
|
||||
return uai;
|
||||
}
|
||||
uai = uai->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_alarm_log_add(char *alarms, char *regexp) {
|
||||
|
||||
struct uwsgi_alarm_log *old_ual = NULL, *ual = uwsgi.alarm_logs;
|
||||
while(ual) {
|
||||
old_ual = ual;
|
||||
ual = ual->next;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
uwsgi.alarm_logs = ual;
|
||||
}
|
||||
|
||||
// map instances to the log
|
||||
char *list = uwsgi_str(alarms);
|
||||
char *p = strtok(list, ",");
|
||||
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) {
|
||||
old_uall = uall;
|
||||
uall = uall->next;
|
||||
}
|
||||
|
||||
uall = uwsgi_calloc(sizeof(struct uwsgi_alarm_ll));
|
||||
uall->alarm = uai;
|
||||
if (old_uall) {
|
||||
old_uall->next = uall;
|
||||
}
|
||||
else {
|
||||
ual->alarms = uall;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// initialize alarms, instances and log regexps
|
||||
void uwsgi_alarms_init() {
|
||||
|
||||
// first of all, create instance of alarms
|
||||
struct uwsgi_string_list *usl = uwsgi.alarm_list;
|
||||
while(usl) {
|
||||
char *line = uwsgi_str(usl->value);
|
||||
char *space = strchr(line, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid alarm syntax: %s\n", usl->value);
|
||||
exit(1);
|
||||
}
|
||||
*space = 0;
|
||||
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;
|
||||
// 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);
|
||||
exit(1);
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
// then map log-alarm
|
||||
usl = uwsgi.alarm_logs_list;
|
||||
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);
|
||||
}
|
||||
|
||||
usl = usl->next;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// call the alarm func
|
||||
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;
|
||||
}
|
||||
uai->alarm->func(uai, msg, len);
|
||||
uai->last_run = uwsgi_now();
|
||||
memcpy(uai->last_msg, msg, len);
|
||||
uai->last_msg_size = 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) {
|
||||
uwsgi_alarm_run(uall->alarm, msg, len);
|
||||
uall = uall->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -3,7 +3,6 @@
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void uwsgi_init_cache() {
|
||||
int i;
|
||||
|
||||
if (!uwsgi.cache_blocksize)
|
||||
uwsgi.cache_blocksize = UMAX16;
|
||||
@@ -64,6 +63,7 @@ void uwsgi_init_cache() {
|
||||
}
|
||||
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));
|
||||
}
|
||||
@@ -102,7 +102,7 @@ uint32_t djb33x_hash(char *key, int keylen) {
|
||||
}
|
||||
|
||||
|
||||
inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
|
||||
static inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
|
||||
|
||||
uint32_t hash = djb33x_hash(key, keylen);
|
||||
|
||||
@@ -243,7 +243,6 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
|
||||
struct uwsgi_cache_item *uci, *ucii;
|
||||
|
||||
int ret = -1;
|
||||
int slot;
|
||||
|
||||
if (!keylen || !vallen) return -1;
|
||||
|
||||
@@ -283,7 +282,7 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
|
||||
uci->keysize = keylen;
|
||||
ret = 0;
|
||||
// now put the value in the 16bit hashtable
|
||||
slot = uci->djbhash % 0xffff;
|
||||
int slot = uci->djbhash % 0xffff;
|
||||
// reset values
|
||||
uci->prev = 0;
|
||||
uci->next = 0;
|
||||
|
||||
+37
-1
@@ -498,7 +498,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
|
||||
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (uid == 0 || gid == 0) {
|
||||
uwsgi_log("[emperor-tyrant] invalid permissions for file %s\n", name);
|
||||
uwsgi_log("[emperor-tyrant] invalid permissions for vassal %s\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1208,6 +1208,9 @@ void emperor_send_stats(int fd) {
|
||||
if (uwsgi_stats_keylong_comma(us, "gid", (unsigned long long) c_ui->gid))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keyval_comma(us, "monitor", c_ui->scanner->arg))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong(us, "respawns", (unsigned long long) c_ui->respawns))
|
||||
goto end0;
|
||||
|
||||
@@ -1338,3 +1341,36 @@ void uwsgi_check_emperor() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -104,7 +104,6 @@ int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
||||
int ret;
|
||||
uint_t nget = 1;
|
||||
timespec_t ts;
|
||||
port_event_t *pe;
|
||||
|
||||
if (timeout >= 0) {
|
||||
ts.tv_sec = timeout;
|
||||
@@ -123,8 +122,6 @@ int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pe = (port_event_t *) events;
|
||||
|
||||
return nget;
|
||||
}
|
||||
|
||||
@@ -926,10 +923,10 @@ struct uwsgi_timer *event_queue_ack_timer(int id) {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int event_queue_read() {
|
||||
int event_queue_read() {
|
||||
return UWSGI_EVENT_IN;
|
||||
}
|
||||
|
||||
inline int event_queue_write() {
|
||||
int event_queue_write() {
|
||||
return UWSGI_EVENT_OUT;
|
||||
}
|
||||
|
||||
+37
@@ -74,6 +74,15 @@ void uwsgi_init_default() {
|
||||
uwsgi.subscriptions_sign_check_tolerance = 3600 * 24;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
uwsgi.alarm_freq = 3;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
uwsgi.multicast_ttl = 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_setup_reload() {
|
||||
@@ -252,3 +261,31 @@ void uwsgi_setup_workers() {
|
||||
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();
|
||||
|
||||
uwsgi.workers[0].pid = uwsgi.mypid;
|
||||
|
||||
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile);
|
||||
}
|
||||
|
||||
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile2);
|
||||
}
|
||||
|
||||
return uwsgi.mypid;
|
||||
}
|
||||
|
||||
@@ -265,6 +265,9 @@ int uwsgi_master_log(void) {
|
||||
|
||||
ssize_t rlen = read(uwsgi.shared->worker_log_pipe[0], uwsgi.log_master_buf, uwsgi.log_master_bufsize);
|
||||
if (rlen > 0) {
|
||||
#ifdef UWSGI_ALARM
|
||||
uwsgi_alarm_log_check(uwsgi.log_master_buf, rlen);
|
||||
#endif
|
||||
#ifdef UWSGI_PCRE
|
||||
struct uwsgi_regexp_list *url = uwsgi.log_drain_rules;
|
||||
while(url) {
|
||||
@@ -644,6 +647,11 @@ int master_loop(char **argv, char **environ) {
|
||||
uwsgi.threaded_logger = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
// initialize the alarm subsystem
|
||||
uwsgi_alarms_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (uwsgi.cache_max_items > 0 && !uwsgi.cache_no_expire) {
|
||||
|
||||
+31
-1
@@ -2,6 +2,27 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#ifdef UWSGI_ELF
|
||||
static void uwsgi_plugin_parse_section(char *filename) {
|
||||
size_t s_len = 0;
|
||||
char *buf = uwsgi_elf_section(filename, "uwsgi", &s_len);
|
||||
if (buf) {
|
||||
char *p = strtok(buf, "\n");
|
||||
while(p) {
|
||||
char *equal = strchr(p, '=');
|
||||
if (equal) {
|
||||
*equal = 0;
|
||||
if (!strcmp(p, "requires")) {
|
||||
uwsgi_load_plugin(-1, equal+1, NULL);
|
||||
}
|
||||
}
|
||||
p = strtok(NULL, "\n");
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int plugin_already_loaded(const char *plugin) {
|
||||
int i;
|
||||
|
||||
@@ -79,6 +100,9 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
|
||||
// step 1: check for absolute plugin (stop if it fails)
|
||||
if (strchr(plugin_name, '/')) {
|
||||
#ifdef UWSGI_ELF
|
||||
uwsgi_plugin_parse_section(plugin_name);
|
||||
#endif
|
||||
plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!plugin_handle) {
|
||||
if (!has_option)
|
||||
@@ -95,6 +119,9 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
|
||||
while(pdir) {
|
||||
plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
|
||||
#ifdef UWSGI_ELF
|
||||
uwsgi_plugin_parse_section(plugin_filename);
|
||||
#endif
|
||||
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (plugin_handle) {
|
||||
plugin_abs_path = plugin_filename;
|
||||
@@ -109,6 +136,9 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
// last step: search in compile-time plugin_dir
|
||||
if (!plugin_handle) {
|
||||
plugin_filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin_name);
|
||||
#ifdef UWSGI_ELF
|
||||
uwsgi_plugin_parse_section(plugin_filename);
|
||||
#endif
|
||||
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
|
||||
plugin_abs_path = plugin_filename;
|
||||
//free(plugin_filename);
|
||||
@@ -117,7 +147,7 @@ void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
|
||||
success:
|
||||
if (!plugin_handle) {
|
||||
if (!has_option)
|
||||
uwsgi_log( "%s\n", dlerror());
|
||||
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);
|
||||
|
||||
+225
-216
@@ -4,13 +4,13 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_signal_handler(uint8_t sig) {
|
||||
|
||||
struct uwsgi_signal_entry *use = NULL;
|
||||
struct uwsgi_signal_entry *use = NULL;
|
||||
|
||||
use = &uwsgi.shared->signal_table[sig];
|
||||
|
||||
if (!uwsgi.p[use->modifier1]->signal_handler) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// check for COW
|
||||
if (uwsgi.master_process) {
|
||||
@@ -34,52 +34,52 @@ int uwsgi_signal_handler(uint8_t sig) {
|
||||
}
|
||||
}
|
||||
|
||||
// set harakiri here (if required and if i am a worker)
|
||||
|
||||
// set harakiri here (if required and if i am a worker)
|
||||
|
||||
if (uwsgi.mywid > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].sig = 1;
|
||||
uwsgi.workers[uwsgi.mywid].signum = sig;
|
||||
uwsgi.workers[uwsgi.mywid].sig = 1;
|
||||
uwsgi.workers[uwsgi.mywid].signum = sig;
|
||||
uwsgi.workers[uwsgi.mywid].signals++;
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uwsgi.muleid > 0) {
|
||||
uwsgi.mules[uwsgi.muleid-1].sig = 1;
|
||||
uwsgi.mules[uwsgi.muleid-1].signum = sig;
|
||||
uwsgi.mules[uwsgi.muleid-1].signals++;
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI] > 0) {
|
||||
set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]);
|
||||
uwsgi.mules[uwsgi.muleid - 1].sig = 1;
|
||||
uwsgi.mules[uwsgi.muleid - 1].signum = sig;
|
||||
uwsgi.mules[uwsgi.muleid - 1].signals++;
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI] > 0) {
|
||||
set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]);
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_SPOOLER
|
||||
else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) {
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
|
||||
}
|
||||
}
|
||||
else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) {
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ret = uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
|
||||
|
||||
if (uwsgi.mywid > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].sig = 0;
|
||||
if(uwsgi.workers[uwsgi.mywid].harakiri > 0) {
|
||||
set_harakiri(0);
|
||||
uwsgi.workers[uwsgi.mywid].sig = 0;
|
||||
if (uwsgi.workers[uwsgi.mywid].harakiri > 0) {
|
||||
set_harakiri(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uwsgi.muleid > 0) {
|
||||
uwsgi.mules[uwsgi.muleid-1].sig = 0;
|
||||
if(uwsgi.mules[uwsgi.muleid-1].harakiri > 0) {
|
||||
set_mule_harakiri(0);
|
||||
uwsgi.mules[uwsgi.muleid - 1].sig = 0;
|
||||
if (uwsgi.mules[uwsgi.muleid - 1].harakiri > 0) {
|
||||
set_mule_harakiri(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_SPOOLER
|
||||
else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) {
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(0);
|
||||
}
|
||||
}
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
|
||||
set_spooler_harakiri(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
@@ -97,7 +97,8 @@ int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t mo
|
||||
|
||||
struct uwsgi_signal_entry *use = NULL;
|
||||
|
||||
if (strlen(receiver) > 63) return -1;
|
||||
if (strlen(receiver) > 63)
|
||||
return -1;
|
||||
|
||||
uwsgi_lock(uwsgi.signal_table_lock);
|
||||
|
||||
@@ -109,7 +110,7 @@ int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t mo
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(use->receiver, receiver, strlen(receiver)+1);
|
||||
strncpy(use->receiver, receiver, strlen(receiver) + 1);
|
||||
use->handler = handler;
|
||||
use->modifier1 = modifier1;
|
||||
use->wid = uwsgi.mywid;
|
||||
@@ -129,7 +130,7 @@ int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t mo
|
||||
|
||||
int uwsgi_add_file_monitor(uint8_t sig, char *filename) {
|
||||
|
||||
if (strlen(filename) > (0xff-1)) {
|
||||
if (strlen(filename) > (0xff - 1)) {
|
||||
uwsgi_log("uwsgi_add_file_monitor: invalid filename length\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -140,9 +141,9 @@ int uwsgi_add_file_monitor(uint8_t sig, char *filename) {
|
||||
|
||||
// fill the fmon table, the master will use it to add items to the event queue
|
||||
memcpy(ushared->files_monitored[ushared->files_monitored_cnt].filename, filename, strlen(filename));
|
||||
ushared->files_monitored[ushared->files_monitored_cnt].registered = 0;
|
||||
ushared->files_monitored[ushared->files_monitored_cnt].registered = 0;
|
||||
ushared->files_monitored[ushared->files_monitored_cnt].sig = sig;
|
||||
|
||||
|
||||
ushared->files_monitored_cnt++;
|
||||
}
|
||||
else {
|
||||
@@ -157,31 +158,31 @@ int uwsgi_add_file_monitor(uint8_t sig, char *filename) {
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_probe *uwsgi_probe_register(struct uwsgi_probe **up, char *name, int (*func)(int, struct uwsgi_signal_probe *)) {
|
||||
struct uwsgi_probe *uwsgi_probe_register(struct uwsgi_probe **up, char *name, int (*func) (int, struct uwsgi_signal_probe *)) {
|
||||
|
||||
struct uwsgi_probe *uwsgi_up = *up, *old_up;
|
||||
struct uwsgi_probe *uwsgi_up = *up, *old_up;
|
||||
|
||||
if (!uwsgi_up) {
|
||||
*up = uwsgi_malloc(sizeof(struct uwsgi_probe));
|
||||
uwsgi_up = *up;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_up) {
|
||||
old_up = uwsgi_up;
|
||||
uwsgi_up = uwsgi_up->next;
|
||||
}
|
||||
if (!uwsgi_up) {
|
||||
*up = uwsgi_malloc(sizeof(struct uwsgi_probe));
|
||||
uwsgi_up = *up;
|
||||
}
|
||||
else {
|
||||
while (uwsgi_up) {
|
||||
old_up = uwsgi_up;
|
||||
uwsgi_up = uwsgi_up->next;
|
||||
}
|
||||
|
||||
uwsgi_up = uwsgi_malloc(sizeof(struct uwsgi_probe));
|
||||
old_up->next = uwsgi_up;
|
||||
}
|
||||
uwsgi_up = uwsgi_malloc(sizeof(struct uwsgi_probe));
|
||||
old_up->next = uwsgi_up;
|
||||
}
|
||||
|
||||
uwsgi_up->name = name;
|
||||
uwsgi_up->func = func;
|
||||
uwsgi_up->next = NULL;
|
||||
uwsgi_up->name = name;
|
||||
uwsgi_up->func = func;
|
||||
uwsgi_up->next = NULL;
|
||||
|
||||
uwsgi_log("registered new probe \"%s\" at %p\n", name, uwsgi_up);
|
||||
|
||||
return uwsgi_up;
|
||||
return uwsgi_up;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,10 +190,10 @@ int uwsgi_add_probe(uint8_t sig, char *kind, char *args, int timeout, int freq)
|
||||
|
||||
uwsgi_lock(uwsgi.probe_table_lock);
|
||||
|
||||
if (ushared->probes_cnt < MAX_PROBES) {
|
||||
if (ushared->probes_cnt < MAX_PROBES) {
|
||||
|
||||
struct uwsgi_probe *up = uwsgi.probes;
|
||||
while(up) {
|
||||
while (up) {
|
||||
if (!strcmp(up->name, kind)) {
|
||||
break;
|
||||
}
|
||||
@@ -201,15 +202,15 @@ int uwsgi_add_probe(uint8_t sig, char *kind, char *args, int timeout, int freq)
|
||||
|
||||
if (!up) {
|
||||
uwsgi_log("unable to find probe \"%s\" !!!\n", kind);
|
||||
uwsgi_unlock(uwsgi.probe_table_lock);
|
||||
return -1;
|
||||
uwsgi_unlock(uwsgi.probe_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// fill the probe table
|
||||
ushared->probes[ushared->probes_cnt].func = up->func;
|
||||
strncpy(ushared->probes[ushared->probes_cnt].args, args, 1024-1);
|
||||
ushared->probes[ushared->probes_cnt].registered = 0;
|
||||
ushared->probes[ushared->probes_cnt].sig = sig;
|
||||
// fill the probe table
|
||||
ushared->probes[ushared->probes_cnt].func = up->func;
|
||||
strncpy(ushared->probes[ushared->probes_cnt].args, args, 1024 - 1);
|
||||
ushared->probes[ushared->probes_cnt].registered = 0;
|
||||
ushared->probes[ushared->probes_cnt].sig = sig;
|
||||
ushared->probes[ushared->probes_cnt].fd = -1;
|
||||
ushared->probes[ushared->probes_cnt].state = 0;
|
||||
ushared->probes[ushared->probes_cnt].last_event = 0;
|
||||
@@ -225,15 +226,15 @@ int uwsgi_add_probe(uint8_t sig, char *kind, char *args, int timeout, int freq)
|
||||
freq = 1;
|
||||
}
|
||||
ushared->probes[ushared->probes_cnt].freq = freq;
|
||||
ushared->probes_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d probes !!!\n", MAX_PROBES);
|
||||
uwsgi_unlock(uwsgi.probe_table_lock);
|
||||
return -1;
|
||||
}
|
||||
ushared->probes_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d probes !!!\n", MAX_PROBES);
|
||||
uwsgi_unlock(uwsgi.probe_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.probe_table_lock);
|
||||
uwsgi_unlock(uwsgi.probe_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -267,107 +268,109 @@ void uwsgi_opt_add_cron(char *opt, char *value, void *foobar) {
|
||||
int i;
|
||||
|
||||
struct uwsgi_cron *old_uc, *uc = uwsgi.crons;
|
||||
if (!uc) {
|
||||
uc = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uwsgi.crons = uc;
|
||||
}
|
||||
else {
|
||||
old_uc = uc;
|
||||
while(uc->next) {
|
||||
uc = uc->next;
|
||||
old_uc = uc;
|
||||
}
|
||||
if (!uc) {
|
||||
uc = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uwsgi.crons = uc;
|
||||
}
|
||||
else {
|
||||
old_uc = uc;
|
||||
while (uc->next) {
|
||||
uc = uc->next;
|
||||
old_uc = uc;
|
||||
}
|
||||
|
||||
old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uc = old_uc->next;
|
||||
}
|
||||
old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uc = old_uc->next;
|
||||
}
|
||||
|
||||
memset(uc, 0, sizeof(struct uwsgi_cron));
|
||||
memset(uc, 0, sizeof(struct uwsgi_cron));
|
||||
|
||||
if (sscanf(value, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) {
|
||||
uwsgi_log("invalid cron syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
uc->command = value+i;
|
||||
if (sscanf(value, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) {
|
||||
uwsgi_log("invalid cron syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
uc->command = value + i;
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) {
|
||||
|
||||
if (!uwsgi.master_process) return -1;
|
||||
if (!uwsgi.master_process)
|
||||
return -1;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
|
||||
if (ushared->cron_cnt < MAX_CRONS) {
|
||||
if (ushared->cron_cnt < MAX_CRONS) {
|
||||
|
||||
ushared->cron[ushared->cron_cnt].sig = sig;
|
||||
ushared->cron[ushared->cron_cnt].minute = minute;
|
||||
ushared->cron[ushared->cron_cnt].hour = hour;
|
||||
ushared->cron[ushared->cron_cnt].day = day;
|
||||
ushared->cron[ushared->cron_cnt].month = month;
|
||||
ushared->cron[ushared->cron_cnt].week = week;
|
||||
ushared->cron_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
return -1;
|
||||
}
|
||||
ushared->cron[ushared->cron_cnt].sig = sig;
|
||||
ushared->cron[ushared->cron_cnt].minute = minute;
|
||||
ushared->cron[ushared->cron_cnt].hour = hour;
|
||||
ushared->cron[ushared->cron_cnt].day = day;
|
||||
ushared->cron[ushared->cron_cnt].month = month;
|
||||
ushared->cron[ushared->cron_cnt].week = week;
|
||||
ushared->cron_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_rb_timer(uint8_t sig, int secs, int iterations) {
|
||||
|
||||
if (!uwsgi.master_process) return -1;
|
||||
if (!uwsgi.master_process)
|
||||
return -1;
|
||||
|
||||
uwsgi_lock(uwsgi.rb_timer_table_lock);
|
||||
uwsgi_lock(uwsgi.rb_timer_table_lock);
|
||||
|
||||
if (ushared->rb_timers_cnt < 64) {
|
||||
if (ushared->rb_timers_cnt < 64) {
|
||||
|
||||
// fill the timer table, the master will use it to add items to the event queue
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].value = secs;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].registered = 0;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].iterations = iterations;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].iterations_done = 0;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].sig = sig;
|
||||
ushared->rb_timers_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max 64 rb_timers !!!\n");
|
||||
uwsgi_unlock(uwsgi.rb_timer_table_lock);
|
||||
return -1;
|
||||
}
|
||||
// fill the timer table, the master will use it to add items to the event queue
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].value = secs;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].registered = 0;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].iterations = iterations;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].iterations_done = 0;
|
||||
ushared->rb_timers[ushared->rb_timers_cnt].sig = sig;
|
||||
ushared->rb_timers_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max 64 rb_timers !!!\n");
|
||||
uwsgi_unlock(uwsgi.rb_timer_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.rb_timer_table_lock);
|
||||
uwsgi_unlock(uwsgi.rb_timer_table_lock);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void create_signal_pipe(int *sigpipe) {
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sigpipe)) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_socket_nb(sigpipe[0]);
|
||||
uwsgi_socket_nb(sigpipe[1]);
|
||||
uwsgi_error("socketpair()\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_socket_nb(sigpipe[0]);
|
||||
uwsgi_socket_nb(sigpipe[1]);
|
||||
|
||||
if (uwsgi.signal_bufsize) {
|
||||
if (setsockopt(sigpipe[0], SOL_SOCKET, SO_SNDBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
if (setsockopt(sigpipe[0], SOL_SOCKET, SO_SNDBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
if (setsockopt(sigpipe[0], SOL_SOCKET, SO_RCVBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
if (setsockopt(sigpipe[0], SOL_SOCKET, SO_RCVBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
|
||||
if (setsockopt(sigpipe[1], SOL_SOCKET, SO_SNDBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
if (setsockopt(sigpipe[1], SOL_SOCKET, SO_SNDBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
if (setsockopt(sigpipe[1], SOL_SOCKET, SO_RCVBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
if (setsockopt(sigpipe[1], SOL_SOCKET, SO_RCVBUF, &uwsgi.signal_bufsize, sizeof(int))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,9 +382,10 @@ int uwsgi_remote_signal_send(char *addr, uint8_t sig) {
|
||||
uh.modifier1 = 110;
|
||||
uh.pktsize = 0;
|
||||
uh.modifier2 = sig;
|
||||
|
||||
|
||||
int fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
if (fd < 0) return -1;
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
if (write(fd, (char *) &uh, 4) != 4) {
|
||||
uwsgi_error("uwsgi_remote_signal_send()");
|
||||
@@ -403,16 +407,16 @@ int uwsgi_signal_send(int fd, uint8_t sig) {
|
||||
|
||||
if (write(fd, &sig, 1) != 1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
|
||||
uwsgi_error("getsockopt()");
|
||||
}
|
||||
uwsgi_log("*** SIGNAL QUEUE IS FULL: buffer size %d bytes (you can tune it with --signal-bufsize) ***\n", so_bufsize);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
|
||||
uwsgi_error("getsockopt()");
|
||||
}
|
||||
uwsgi_log("*** SIGNAL QUEUE IS FULL: buffer size %d bytes (you can tune it with --signal-bufsize) ***\n", so_bufsize);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("uwsgi_signal_send()");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
@@ -430,7 +434,7 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
}
|
||||
// send to all workers
|
||||
else if (!strcmp(use->receiver, "workers")) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi_signal_send(uwsgi.workers[i].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
@@ -438,13 +442,13 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
}
|
||||
// route to specific worker
|
||||
else if (!strncmp(use->receiver, "worker", 6)) {
|
||||
i = atoi(use->receiver+6);
|
||||
i = atoi(use->receiver + 6);
|
||||
if (i > uwsgi.numproc) {
|
||||
uwsgi_log("invalid signal target: %s\n", use->receiver);
|
||||
}
|
||||
if (uwsgi_signal_send(uwsgi.workers[i].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
}
|
||||
// route to subscribed
|
||||
else if (!strcmp(use->receiver, "subscribed")) {
|
||||
@@ -454,54 +458,54 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
else if (!strcmp(use->receiver, "spooler")) {
|
||||
if (ushared->worker_signal_pipe[0] != -1) {
|
||||
if (uwsgi_signal_send(ushared->spooler_signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to the spooler\n", sig);
|
||||
}
|
||||
uwsgi_log("could not deliver signal %d to the spooler\n", sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp(use->receiver, "mules")) {
|
||||
for(i=0;i<uwsgi.mules_cnt;i++) {
|
||||
for (i = 0; i < uwsgi.mules_cnt; i++) {
|
||||
if (uwsgi_signal_send(uwsgi.mules[i].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i+1);
|
||||
}
|
||||
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strncmp(use->receiver, "mule", 4)) {
|
||||
i = atoi(use->receiver+4);
|
||||
i = atoi(use->receiver + 4);
|
||||
if (i > uwsgi.mules_cnt) {
|
||||
uwsgi_log("invalid signal target: %s\n", use->receiver);
|
||||
}
|
||||
else if (i == 0) {
|
||||
if (uwsgi_signal_send(ushared->mule_signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to a mule\n", sig);
|
||||
}
|
||||
uwsgi_log("could not deliver signal %d to a mule\n", sig);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (uwsgi_signal_send(uwsgi.mules[i-1].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i);
|
||||
}
|
||||
if (uwsgi_signal_send(uwsgi.mules[i - 1].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strncmp(use->receiver, "farm_", 5)) {
|
||||
char *name = use->receiver+5;
|
||||
char *name = use->receiver + 5;
|
||||
struct uwsgi_farm *uf = get_farm_by_name(name);
|
||||
if (!uf) {
|
||||
uwsgi_log("unknown farm: %s\n", name);
|
||||
return;
|
||||
}
|
||||
if (uwsgi_signal_send(uf->signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to farm %d (%s)\n", sig, uf->id, uf->name);
|
||||
}
|
||||
uwsgi_log("could not deliver signal %d to farm %d (%s)\n", sig, uf->id, uf->name);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(use->receiver, "farm", 4)) {
|
||||
i = atoi(use->receiver+4);
|
||||
i = atoi(use->receiver + 4);
|
||||
if (i > uwsgi.farms_cnt || i <= 0) {
|
||||
uwsgi_log("invalid signal target: %s\n", use->receiver);
|
||||
}
|
||||
else {
|
||||
if (uwsgi_signal_send(uwsgi.farms[i-1].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to farm %d (%s)\n", sig, i, uwsgi.farms[i-1].name);
|
||||
}
|
||||
if (uwsgi_signal_send(uwsgi.farms[i - 1].signal_pipe[0], sig)) {
|
||||
uwsgi_log("could not deliver signal %d to farm %d (%s)\n", sig, i, uwsgi.farms[i - 1].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,51 +516,56 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t uwsgi_signal_wait(int signum) {
|
||||
int uwsgi_signal_wait(int signum) {
|
||||
|
||||
int wait_for_specific_signal = 0;
|
||||
uint8_t uwsgi_signal = 0;
|
||||
uint8_t received_signal;
|
||||
int ret;
|
||||
struct pollfd pfd[2];
|
||||
int wait_for_specific_signal = 0;
|
||||
uint8_t uwsgi_signal = 0;
|
||||
int received_signal = -1;
|
||||
int ret;
|
||||
struct pollfd pfd[2];
|
||||
|
||||
if (signum > -1) {
|
||||
wait_for_specific_signal = 1;
|
||||
}
|
||||
wait_for_specific_signal = 1;
|
||||
}
|
||||
|
||||
pfd[0].fd = uwsgi.signal_socket;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = uwsgi.my_signal_socket;
|
||||
pfd[1].events = POLLIN;
|
||||
|
||||
pfd[0].fd = uwsgi.signal_socket;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = uwsgi.my_signal_socket;
|
||||
pfd[1].events = POLLIN;
|
||||
cycle:
|
||||
ret = poll(pfd, 2, -1);
|
||||
if (ret > 0) {
|
||||
if (pfd[0].revents == POLLIN) {
|
||||
if (read(uwsgi.signal_socket, &received_signal, 1) != 1) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
(void)uwsgi_signal_handler(received_signal);
|
||||
if (wait_for_specific_signal) {
|
||||
if (received_signal != uwsgi_signal) goto cycle;
|
||||
}
|
||||
}
|
||||
ret = poll(pfd, 2, -1);
|
||||
if (ret > 0) {
|
||||
if (pfd[0].revents == POLLIN) {
|
||||
if (read(uwsgi.signal_socket, &uwsgi_signal, 1) != 1) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
(void) uwsgi_signal_handler(uwsgi_signal);
|
||||
if (wait_for_specific_signal) {
|
||||
if (signum != uwsgi_signal)
|
||||
goto cycle;
|
||||
}
|
||||
received_signal = uwsgi_signal;
|
||||
}
|
||||
}
|
||||
if (pfd[1].revents == POLLIN) {
|
||||
if (read(uwsgi.my_signal_socket, &uwsgi_signal, 1) != 1) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
(void) uwsgi_signal_handler(uwsgi_signal);
|
||||
if (wait_for_specific_signal) {
|
||||
if (signum != uwsgi_signal)
|
||||
goto cycle;
|
||||
}
|
||||
}
|
||||
received_signal = uwsgi_signal;
|
||||
}
|
||||
if (pfd[1].revents == POLLIN) {
|
||||
if (read(uwsgi.my_signal_socket, &received_signal, 1) != 1) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
(void)uwsgi_signal_handler(received_signal);
|
||||
if (wait_for_specific_signal) {
|
||||
if (received_signal != uwsgi_signal) goto cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return received_signal;
|
||||
return received_signal;
|
||||
}
|
||||
|
||||
void uwsgi_receive_signal(int fd, char *name, int id) {
|
||||
@@ -565,27 +574,27 @@ void uwsgi_receive_signal(int fd, char *name, int id) {
|
||||
|
||||
ssize_t ret = read(fd, &uwsgi_signal, 1);
|
||||
|
||||
if (ret == 0) {
|
||||
if (ret == 0) {
|
||||
goto destroy;
|
||||
}
|
||||
else if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
uwsgi_error("[uwsgi-signal] read()");
|
||||
}
|
||||
else if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
uwsgi_error("[uwsgi-signal] read()");
|
||||
goto destroy;
|
||||
}
|
||||
else if (ret > 0) {
|
||||
}
|
||||
else if (ret > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to %s %d\n", uwsgi_signal, name, id);
|
||||
uwsgi_log_verbose("master sent signal %d to %s %d\n", uwsgi_signal, name, id);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on %s %d\n", uwsgi_signal, name, id);
|
||||
}
|
||||
}
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on %s %d\n", uwsgi_signal, name, id);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
destroy:
|
||||
// better to kill the whole worker...
|
||||
uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: i will kill myself !!!\n", name, id);
|
||||
uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: i will kill myself !!!\n", name, id);
|
||||
end_me(0);
|
||||
|
||||
}
|
||||
|
||||
+10
-1
@@ -174,6 +174,7 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) {
|
||||
struct sockaddr_in uws_addr;
|
||||
char *udp_port;
|
||||
int bcast = 1;
|
||||
int reuse = 1;
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
struct ip_mreq mc;
|
||||
@@ -231,6 +232,10 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
if (multicast) {
|
||||
// if multicast is enabled remember to bind to INADDR_ANY
|
||||
@@ -265,6 +270,10 @@ int bind_to_udp(char *socket_name, int multicast, int broadcast) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
|
||||
if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_TTL, &uwsgi.multicast_ttl, sizeof(uwsgi.multicast_ttl))) {
|
||||
uwsgi_error("setsockopt()");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -595,7 +604,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
|
||||
if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr)) != 0) {
|
||||
if (errno == EADDRINUSE) {
|
||||
uwsgi_log("probably another instance of uWSGI is running on the same address.\n");
|
||||
uwsgi_log("probably another instance of uWSGI is running on the same address (%s).\n", socket_name);
|
||||
}
|
||||
uwsgi_error("bind()");
|
||||
uwsgi_nuclear_blast();
|
||||
|
||||
+162
-6
@@ -1193,7 +1193,7 @@ char *uwsgi_str_contains(char *str, int slen, char what) {
|
||||
}
|
||||
|
||||
// fast compare 2 sized strings
|
||||
inline int uwsgi_strncmp(char *src, int slen, char *dst, int dlen) {
|
||||
int uwsgi_strncmp(char *src, int slen, char *dst, int dlen) {
|
||||
|
||||
if (slen != dlen)
|
||||
return 1;
|
||||
@@ -1203,7 +1203,7 @@ inline int uwsgi_strncmp(char *src, int slen, char *dst, int dlen) {
|
||||
}
|
||||
|
||||
// fast sized check of initial part of a string
|
||||
inline int uwsgi_starts_with(char *src, int slen, char *dst, int dlen) {
|
||||
int uwsgi_starts_with(char *src, int slen, char *dst, int dlen) {
|
||||
|
||||
if (slen < dlen)
|
||||
return -1;
|
||||
@@ -1212,7 +1212,7 @@ inline int uwsgi_starts_with(char *src, int slen, char *dst, int dlen) {
|
||||
}
|
||||
|
||||
// unsized check
|
||||
inline int uwsgi_startswith(char *src, char *what, int wlen) {
|
||||
int uwsgi_startswith(char *src, char *what, int wlen) {
|
||||
|
||||
int i;
|
||||
|
||||
@@ -2149,18 +2149,20 @@ int uwsgi_waitfd_event(int fd, int timeout, int event) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void *uwsgi_malloc(size_t size) {
|
||||
void *uwsgi_malloc(size_t size) {
|
||||
|
||||
char *ptr = malloc(size);
|
||||
if (ptr == NULL) {
|
||||
uwsgi_error("malloc()");
|
||||
uwsgi_log("!!! tried memory allocation of %llu bytes !!!\n", (unsigned long long) size);
|
||||
uwsgi_backtrace(uwsgi.backtrace_depth);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void *uwsgi_calloc(size_t size) {
|
||||
void *uwsgi_calloc(size_t size) {
|
||||
|
||||
char *ptr = uwsgi_malloc(size);
|
||||
memset(ptr, 0, size);
|
||||
@@ -2531,6 +2533,18 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
memcpy(buffer, sym_start_ptr, sym_end_ptr - sym_start_ptr);
|
||||
|
||||
}
|
||||
#ifdef UWSGI_ELF
|
||||
else if (!strncmp("section://", url, 10)) {
|
||||
size_t s_len = 0;
|
||||
buffer = uwsgi_elf_section(uwsgi.binary_path, url+10, &s_len);
|
||||
if (!buffer) {
|
||||
uwsgi_log("unable to find section %s in %s\n", url+10, uwsgi.binary_path);
|
||||
exit(1);
|
||||
}
|
||||
*size = s_len;
|
||||
if (add_zero) *size += 1;
|
||||
}
|
||||
#endif
|
||||
// fallback to file
|
||||
else {
|
||||
fd = open(url, O_RDONLY);
|
||||
@@ -4373,7 +4387,7 @@ SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ci
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
#endif
|
||||
|
||||
if (SSL_CTX_use_certificate_file(ctx, crt, SSL_FILETYPE_PEM) <= 0) {
|
||||
if (SSL_CTX_use_certificate_chain_file(ctx, crt) <= 0) {
|
||||
uwsgi_log("unable to assign ssl certificate %s\n", crt);
|
||||
exit(1);
|
||||
}
|
||||
@@ -4738,3 +4752,145 @@ void uwsgi_set_cpu_affinity() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ELF
|
||||
#if defined(__linux__)
|
||||
#include <elf.h>
|
||||
#endif
|
||||
char *uwsgi_elf_section(char *filename, char *s, size_t *len) {
|
||||
struct stat st;
|
||||
char *output = NULL;
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open(filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st)) {
|
||||
uwsgi_error("stat()");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (st.st_size < EI_NIDENT) {
|
||||
uwsgi_log("invalid elf file: %s\n", filename);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *addr = mmap(NULL, st.st_size , PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
uwsgi_error("mmap()");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr[0] != ELFMAG0) goto clear;
|
||||
if (addr[1] != ELFMAG1) goto clear;
|
||||
if (addr[2] != ELFMAG2) goto clear;
|
||||
if (addr[3] != ELFMAG3) goto clear;
|
||||
|
||||
if (addr[4] == ELFCLASS32) {
|
||||
// elf header
|
||||
Elf32_Ehdr *elfh = (Elf32_Ehdr *) addr;
|
||||
// first section
|
||||
Elf32_Shdr *sections = ((Elf32_Shdr *) (addr + elfh->e_shoff));
|
||||
// number of sections
|
||||
int ns = elfh->e_shnum;
|
||||
// the names table
|
||||
Elf32_Shdr *table = §ions[elfh->e_shstrndx];
|
||||
// string table session pointer
|
||||
char *names = addr + table->sh_offset;
|
||||
Elf32_Shdr *ss = NULL; int i;
|
||||
for(i=0;i<ns;i++) {
|
||||
char *name = names + sections[i].sh_name;
|
||||
if (!strcmp(name, s)) {
|
||||
ss = §ions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss) {
|
||||
*len = ss->sh_size;
|
||||
output = uwsgi_concat2n(addr + ss->sh_offset, ss->sh_size, "", 0);
|
||||
}
|
||||
}
|
||||
else if (addr[4] == ELFCLASS64) {
|
||||
// elf header
|
||||
Elf64_Ehdr *elfh = (Elf64_Ehdr *) addr;
|
||||
// first section
|
||||
Elf64_Shdr *sections = ((Elf64_Shdr *) (addr + elfh->e_shoff));
|
||||
// number of sections
|
||||
int ns = elfh->e_shnum;
|
||||
// the names table
|
||||
Elf64_Shdr *table = §ions[elfh->e_shstrndx];
|
||||
// string table session pointer
|
||||
char *names = addr + table->sh_offset;
|
||||
Elf64_Shdr *ss = NULL; int i;
|
||||
for(i=0;i<ns;i++) {
|
||||
char *name = names + sections[i].sh_name;
|
||||
if (!strcmp(name, s)) {
|
||||
ss = §ions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss) {
|
||||
*len = ss->sh_size;
|
||||
output = uwsgi_concat2n(addr + ss->sh_offset, ss->sh_size, "", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
clear:
|
||||
close(fd);
|
||||
munmap(addr, st.st_size);
|
||||
return output;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *uwsgi_thread_run(void *arg) {
|
||||
struct uwsgi_thread *ut = (struct uwsgi_thread *) arg;
|
||||
// block all signals
|
||||
sigset_t smask;
|
||||
sigfillset(&smask);
|
||||
pthread_sigmask(SIG_BLOCK, &smask, NULL);
|
||||
|
||||
ut->queue = event_queue_init();
|
||||
event_queue_add_fd_read(ut->queue, ut->pipe[1]);
|
||||
|
||||
ut->func(ut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_thread *uwsgi_thread_new(void (*func)(struct uwsgi_thread *)) {
|
||||
|
||||
struct uwsgi_thread *ut = uwsgi_malloc(sizeof(struct uwsgi_thread));
|
||||
|
||||
#if defined(SOCK_SEQPACKET) && defined(__linux__)
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, ut->pipe)) {
|
||||
#else
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ut->pipe)) {
|
||||
#endif
|
||||
free(ut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uwsgi_socket_nb(ut->pipe[0]);
|
||||
uwsgi_socket_nb(ut->pipe[1]);
|
||||
|
||||
ut->func = func;
|
||||
|
||||
if (pthread_create(&ut->tid, NULL, uwsgi_thread_run, ut)) {
|
||||
uwsgi_error("pthread_create()");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return ut;
|
||||
error:
|
||||
close(ut->pipe[0]);
|
||||
close(ut->pipe[1]);
|
||||
free(ut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+76
-59
@@ -302,6 +302,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"stats-server", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER},
|
||||
#ifdef UWSGI_MULTICAST
|
||||
{"multicast", required_argument, 0, "subscribe to specified multicast group", uwsgi_opt_set_str, &uwsgi.multicast_group, UWSGI_OPT_MASTER},
|
||||
{"multicast-ttl", required_argument, 0, "set multicast ttl", uwsgi_opt_set_int, &uwsgi.multicast_ttl, 0},
|
||||
{"cluster", required_argument, 0, "join specified uWSGI cluster", uwsgi_opt_set_str, &uwsgi.cluster, UWSGI_OPT_MASTER},
|
||||
{"cluster-nodes", required_argument, 0, "get nodes list from the specified cluster", uwsgi_opt_true, &uwsgi.cluster_nodes, UWSGI_OPT_MASTER | UWSGI_OPT_CLUSTER},
|
||||
{"cluster-reload", required_argument, 0, "send a reload message to the cluster", uwsgi_opt_cluster_reload, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
@@ -352,6 +353,13 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
#ifdef UWSGI_PCRE
|
||||
{"log-drain", required_argument, 0, "drain (do not show) log lines matching the specified regexp", uwsgi_opt_add_regexp_list, &uwsgi.log_drain_rules, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
|
||||
#endif
|
||||
#ifdef UWSGI_ALARM
|
||||
{"alarm", required_argument, 0, "create a new alarm, syntax: <alarm> <plugin:args>", uwsgi_opt_add_string_list, &uwsgi.alarm_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
|
||||
{"alarm-freq", required_argument, 0, "tune the anti-loop alam system (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.alarm_freq, 0},
|
||||
{"log-alarm", required_argument, 0, "raise the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
|
||||
{"alarm-list", no_argument, 0, "list enabled alarms", uwsgi_opt_true, &uwsgi.alarms_list, 0},
|
||||
{"alarms-list", no_argument, 0, "list enabled alarms", uwsgi_opt_true, &uwsgi.alarms_list, 0},
|
||||
#endif
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
{"log-zeromq", required_argument, 0, "send logs to a zeromq server", uwsgi_opt_set_logger, "zeromq", UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
|
||||
#endif
|
||||
@@ -480,6 +488,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"plugins-list", no_argument, 0, "list enabled plugins", uwsgi_opt_true, &uwsgi.plugins_list, 0},
|
||||
{"plugin-list", no_argument, 0, "list enabled plugins", uwsgi_opt_true, &uwsgi.plugins_list, 0},
|
||||
{"autoload", no_argument, 0, "try to automatically load plugins when unknown options are found", uwsgi_opt_true, &uwsgi.autoload, UWSGI_OPT_IMMEDIATE},
|
||||
{"dlopen", required_argument, 0, "blindly load a shared library", uwsgi_opt_load_dl, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
{"allowed-modifiers", required_argument, 0, "comma separated list of allowed modifiers", uwsgi_opt_set_str, &uwsgi.allowed_modifiers, 0},
|
||||
{"remap-modifier", required_argument, 0, "remap request modifier from one id to another", uwsgi_opt_set_str, &uwsgi.remap_modifier, 0},
|
||||
|
||||
@@ -660,8 +669,21 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
#endif
|
||||
*tmp = 0;
|
||||
}
|
||||
if (uwsgi_get_last_char(magic_table['d'], '/'))
|
||||
magic_table['c'] = uwsgi_get_last_char(magic_table['d'], '/') + 1;
|
||||
if (uwsgi_get_last_char(magic_table['d'], '/')) {
|
||||
magic_table['c'] = uwsgi_str(uwsgi_get_last_char(magic_table['d'], '/') + 1);
|
||||
if (magic_table['c'][strlen(magic_table['c']) - 1] == '/') {
|
||||
magic_table['c'][strlen(magic_table['c']) - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int base = '0';
|
||||
char *to_split = uwsgi_str(magic_table['d']);
|
||||
char *p = strtok(to_split,"/");
|
||||
while(p && base <= '9') {
|
||||
magic_table[base] = p;
|
||||
base++;
|
||||
p = strtok(NULL, "/");
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
*tmp = '/';
|
||||
@@ -1203,7 +1225,7 @@ static void vacuum(void) {
|
||||
}
|
||||
}
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->family == AF_UNIX) {
|
||||
if (uwsgi_sock->family == AF_UNIX && uwsgi_sock->name[0] != '@') {
|
||||
if (unlink(uwsgi_sock->name)) {
|
||||
uwsgi_error("unlink()");
|
||||
}
|
||||
@@ -1515,6 +1537,18 @@ static void clocks_list(void) {
|
||||
uwsgi_log("--- end of clocks list ---\n\n");
|
||||
}
|
||||
|
||||
#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");
|
||||
}
|
||||
#endif
|
||||
|
||||
static time_t uwsgi_unix_seconds() {
|
||||
return time(NULL);
|
||||
}
|
||||
@@ -1522,7 +1556,7 @@ static time_t uwsgi_unix_seconds() {
|
||||
static uint64_t uwsgi_unix_microseconds() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
return ((uint64_t)tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
}
|
||||
|
||||
static struct uwsgi_clock uwsgi_unix_clock = {
|
||||
@@ -1729,6 +1763,13 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
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);
|
||||
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
// register embedded alarms
|
||||
uwsgi_register_embedded_alarms();
|
||||
#endif
|
||||
|
||||
|
||||
/* uWSGI IS CONFIGURED !!! */
|
||||
|
||||
if (uwsgi.dump_options) {
|
||||
@@ -1768,6 +1809,11 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
if (uwsgi.clock_list)
|
||||
clocks_list();
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
if (uwsgi.alarms_list)
|
||||
alarms_list();
|
||||
#endif
|
||||
|
||||
// set the clock
|
||||
if (uwsgi.requested_clock)
|
||||
uwsgi_set_clock(uwsgi.requested_clock);
|
||||
@@ -2026,34 +2072,6 @@ int uwsgi_start(void *v_argv) {
|
||||
pthread_mutex_init(&uwsgi.static_offload_thread_lock, NULL);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
|
||||
// TODO rewrite to use uwsgi.max_fd
|
||||
if (uwsgi.async > 1) {
|
||||
if (!getrlimit(RLIMIT_NOFILE, &uwsgi.rl)) {
|
||||
if ((unsigned long) uwsgi.rl.rlim_cur < (unsigned long) uwsgi.async) {
|
||||
uwsgi_log("- your current max open files limit is %lu, this is lower than requested async cores !!! -\n", (unsigned long) uwsgi.rl.rlim_cur);
|
||||
if (uwsgi.rl.rlim_cur < uwsgi.rl.rlim_max && (unsigned long) uwsgi.rl.rlim_max > (unsigned long) uwsgi.async) {
|
||||
unsigned long tmp_nofile = (unsigned long) uwsgi.rl.rlim_cur;
|
||||
uwsgi.rl.rlim_cur = uwsgi.async;
|
||||
if (!setrlimit(RLIMIT_NOFILE, &uwsgi.rl)) {
|
||||
uwsgi_log("max open files limit reset to %lu\n", (unsigned long) uwsgi.rl.rlim_cur);
|
||||
uwsgi.async = uwsgi.rl.rlim_cur;
|
||||
}
|
||||
else {
|
||||
uwsgi.async = (int) tmp_nofile;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi.async = uwsgi.rl.rlim_cur;
|
||||
}
|
||||
|
||||
uwsgi_log("- async cores set to %d -\n", uwsgi.async);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.requested_max_fd) {
|
||||
uwsgi.rl.rlim_cur = uwsgi.requested_max_fd;
|
||||
uwsgi.rl.rlim_max = uwsgi.requested_max_fd;
|
||||
@@ -2064,11 +2082,24 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE, &uwsgi.rl)) {
|
||||
uwsgi.max_fd = uwsgi.rl.rlim_cur;
|
||||
uwsgi_log_initial("detected max file descriptor number: %d\n", (int) uwsgi.max_fd);
|
||||
uwsgi_log_initial("detected max file descriptor number: %lu\n", (unsigned long) uwsgi.max_fd);
|
||||
}
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
uwsgi_log("async fd table size: %d\n", uwsgi.max_fd);
|
||||
if ((unsigned long) uwsgi.max_fd < (unsigned long) uwsgi.async) {
|
||||
uwsgi_log("- your current max open files limit is %lu, this is lower than requested async cores !!! -\n", (unsigned long) uwsgi.max_fd);
|
||||
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.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);
|
||||
uwsgi.async_waiting_fd_table = malloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
|
||||
if (!uwsgi.async_waiting_fd_table) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -2386,30 +2417,7 @@ next:
|
||||
|
||||
|
||||
if (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();
|
||||
masterpid = uwsgi.mypid;
|
||||
|
||||
uwsgi.workers[0].pid = masterpid;
|
||||
|
||||
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile);
|
||||
}
|
||||
|
||||
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile(uwsgi.pidfile2);
|
||||
}
|
||||
masterpid = uwsgi_daemonize2();
|
||||
}
|
||||
|
||||
if (uwsgi.no_server) {
|
||||
@@ -2421,9 +2429,12 @@ next:
|
||||
if (!uwsgi.master_process && uwsgi.numproc == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
if (!uwsgi.single_interpreter && uwsgi.numproc > 0) {
|
||||
uwsgi_log("*** uWSGI is running in multiple interpreter mode ***\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for request plugins, and eventually print a warning
|
||||
int rp_available = 0;
|
||||
@@ -2917,7 +2928,7 @@ void uwsgi_stdin_sendto(char *socket_name, uint8_t modifier1, uint8_t modifier2)
|
||||
#endif
|
||||
ptr += rlen;
|
||||
delta -= rlen;
|
||||
if (delta <= 0)
|
||||
if (delta == 0)
|
||||
break;
|
||||
rlen = read(0, ptr, delta);
|
||||
}
|
||||
@@ -3320,6 +3331,12 @@ void uwsgi_opt_pidfile_signal(char *opt, char *pidfile, void *sig) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void uwsgi_opt_load_dl(char *opt, char *value, void *none) {
|
||||
if (!dlopen(value, RTLD_NOW | RTLD_GLOBAL)) {
|
||||
uwsgi_log( "%s\n", dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_opt_load_plugin(char *opt, char *value, void *none) {
|
||||
|
||||
char *p = strtok(uwsgi_concat2(value, ""), ",");
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_alarm_curl_config {
|
||||
int first;
|
||||
char *arg;
|
||||
char *subject;
|
||||
char *to;
|
||||
};
|
||||
|
||||
struct uwsgi_alarm_curl_opt {
|
||||
char *name;
|
||||
CURLoption option;
|
||||
void (*func)(CURL *, CURLoption, char *, struct uwsgi_alarm_curl_config*);
|
||||
};
|
||||
|
||||
|
||||
static void uwsgi_alarm_curl_to(CURL *curl, CURLoption option, char *arg, struct uwsgi_alarm_curl_config *uacc) {
|
||||
uacc->to = arg;
|
||||
struct curl_slist *list = NULL;
|
||||
char *items = uwsgi_str(arg);
|
||||
char *ctx = NULL;
|
||||
char *p = strtok_r(items, ",", &ctx);
|
||||
while(p) {
|
||||
list = curl_slist_append(list, p);
|
||||
p = strtok_r(NULL, ",", &ctx);
|
||||
}
|
||||
curl_easy_setopt(curl, option, list);
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_curl_ssl(CURL *curl, CURLoption option, char *arg, struct uwsgi_alarm_curl_config *uacc) {
|
||||
curl_easy_setopt(curl, option, (long)CURLUSESSL_ALL);
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_curl_int(CURL *curl, CURLoption option, char *arg, struct uwsgi_alarm_curl_config *uacc) {
|
||||
curl_easy_setopt(curl, option, atoi(arg));
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_curl_set_subject(CURL *curl, CURLoption option, char *arg, struct uwsgi_alarm_curl_config *uacc) {
|
||||
uacc->subject = arg;
|
||||
}
|
||||
|
||||
static struct uwsgi_alarm_curl_opt uaco[] = {
|
||||
{"url", CURLOPT_URL, NULL},
|
||||
{"mail_to", CURLOPT_MAIL_RCPT, uwsgi_alarm_curl_to },
|
||||
{"mail_from", CURLOPT_MAIL_FROM, NULL},
|
||||
{"subject", 0, uwsgi_alarm_curl_set_subject},
|
||||
{"ssl", CURLOPT_USE_SSL, uwsgi_alarm_curl_ssl},
|
||||
{"auth_user", CURLOPT_USERNAME, NULL},
|
||||
{"auth_pass", CURLOPT_PASSWORD, NULL},
|
||||
{"method", CURLOPT_CUSTOMREQUEST, NULL},
|
||||
{"timeout", CURLOPT_TIMEOUT, uwsgi_alarm_curl_int},
|
||||
{"conn_timeout", CURLOPT_CONNECTTIMEOUT, uwsgi_alarm_curl_int},
|
||||
{NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static void uwsgi_alarm_curl_setopt(CURL *curl, char *opt, struct uwsgi_alarm_curl_config *uacc) {
|
||||
struct uwsgi_alarm_curl_opt *o = uaco;
|
||||
char *equal = strchr(opt,'=');
|
||||
if (!equal) {
|
||||
if (!uacc->first) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, opt);
|
||||
uacc->first = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
uacc->first = 1;
|
||||
*equal = 0;
|
||||
while(o->name) {
|
||||
if (!strcmp(o->name, opt)) {
|
||||
if (o->func) {
|
||||
o->func(curl, o->option, equal+1, uacc);
|
||||
}
|
||||
else {
|
||||
curl_easy_setopt(curl, o->option, equal+1);
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
o++;
|
||||
}
|
||||
end:
|
||||
*equal = '=';
|
||||
}
|
||||
|
||||
static size_t uwsgi_alarm_curl_read_callback(void *ptr, size_t size, size_t nmemb, void *userp) {
|
||||
struct uwsgi_thread *ut = (struct uwsgi_thread *) userp;
|
||||
size_t full_size = size * nmemb;
|
||||
size_t remains = ut->len - ut->pos;
|
||||
struct uwsgi_alarm_curl_config *uacc = ut->data;
|
||||
|
||||
if (remains == 0) return 0;
|
||||
|
||||
if (ut->custom0 == 0) {
|
||||
size_t newline = 0;
|
||||
size_t required = 1;
|
||||
char *addr = ptr;
|
||||
if (uacc->to) required += 4 + strlen(uacc->to) + 1;
|
||||
if (uacc->subject) required += 9 + strlen(uacc->subject) + 1;
|
||||
if (required > full_size) goto skip;
|
||||
|
||||
|
||||
if (uacc->to) {
|
||||
memcpy(addr, "To: ", 4); addr+=4;
|
||||
memcpy(addr, uacc->to, strlen(uacc->to)); addr += strlen(uacc->to);
|
||||
*addr ++= '\n';
|
||||
newline = 1;
|
||||
}
|
||||
|
||||
if (uacc->subject) {
|
||||
memcpy(addr, "Subject: ", 9); addr+=9;
|
||||
memcpy(addr, uacc->subject, strlen(uacc->subject)); addr += strlen(uacc->subject);
|
||||
*addr ++= '\n';
|
||||
newline = 1;
|
||||
}
|
||||
skip:
|
||||
if (newline > 0) {
|
||||
*addr = '\n';
|
||||
}
|
||||
ut->custom0 = 1;
|
||||
return required;
|
||||
}
|
||||
|
||||
if (full_size < remains) {
|
||||
remains = full_size;
|
||||
}
|
||||
|
||||
memcpy(ptr, ut->buf + ut->pos, remains);
|
||||
ut->pos += remains;
|
||||
|
||||
return remains;
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_curl_loop(struct uwsgi_thread *ut) {
|
||||
int interesting_fd;
|
||||
ut->buf = uwsgi_malloc(uwsgi.log_master_bufsize);
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
// ARGH !!!
|
||||
if (!curl) return;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, uwsgi_alarm_curl_read_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, ut);
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
struct curl_slist *expect = NULL; expect = curl_slist_append(expect, "Expect:");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
|
||||
|
||||
struct uwsgi_alarm_curl_config *uacc = (struct uwsgi_alarm_curl_config *) ut->data;
|
||||
char *opts = uwsgi_str(uacc->arg);
|
||||
|
||||
// fill curl options
|
||||
char *ctx = NULL;
|
||||
char *p = strtok_r(opts, ";", &ctx);
|
||||
while(p) {
|
||||
uwsgi_alarm_curl_setopt(curl, uwsgi_str(p), uacc);
|
||||
p = strtok_r(NULL, ";", &ctx);
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
|
||||
if (ret <= 0) continue;
|
||||
if (interesting_fd != ut->pipe[1]) continue;
|
||||
ssize_t rlen = read(ut->pipe[1], ut->buf, uwsgi.log_master_bufsize);
|
||||
if (rlen <= 0) continue;
|
||||
ut->pos = 0;
|
||||
ut->len = (size_t) rlen;
|
||||
ut->custom0 = 0;
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) ut->len);
|
||||
CURLcode res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
uwsgi_log_alarm("-curl] curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_curl_init(struct uwsgi_alarm_instance *uai) {
|
||||
struct uwsgi_thread *ut = uwsgi_thread_new(uwsgi_alarm_curl_loop);
|
||||
if (!ut) return;
|
||||
uai->data_ptr = ut;
|
||||
struct uwsgi_alarm_curl_config *uacc = uwsgi_calloc(sizeof(struct uwsgi_alarm_curl_config));
|
||||
uacc->arg = uai->arg;
|
||||
ut->data = uacc;
|
||||
}
|
||||
|
||||
// pipe the message into the thread;
|
||||
static void uwsgi_alarm_curl_func(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
struct uwsgi_thread *ut = (struct uwsgi_thread *) uai->data_ptr;
|
||||
ut->rlen = write(ut->pipe[0], msg, len);
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_curl_load(void) {
|
||||
uwsgi_register_alarm("curl", uwsgi_alarm_curl_init, uwsgi_alarm_curl_func);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin alarm_curl_plugin = {
|
||||
.name = "alarm_curl",
|
||||
.on_load = uwsgi_alarm_curl_load,
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='alarm_curl'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lcurl']
|
||||
GCC_LIST = ['alarm_curl_plugin']
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
void uwsgi_alarm_xmpp_loop(struct uwsgi_thread *);
|
||||
|
||||
static void uwsgi_alarm_xmpp_init(struct uwsgi_alarm_instance *uai) {
|
||||
|
||||
struct uwsgi_thread *ut = uwsgi_thread_new(uwsgi_alarm_xmpp_loop);
|
||||
if (!ut) return;
|
||||
uai->data_ptr = ut;
|
||||
ut->data = uai->arg;
|
||||
}
|
||||
|
||||
// pipe the message into the thread;
|
||||
static void uwsgi_alarm_xmpp_func(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
|
||||
struct uwsgi_thread *ut = (struct uwsgi_thread *) uai->data_ptr;
|
||||
ut->rlen = write(ut->pipe[0], msg, len);
|
||||
}
|
||||
|
||||
static void uwsgi_alarm_xmpp_load(void) {
|
||||
uwsgi_register_alarm("xmpp", uwsgi_alarm_xmpp_init, uwsgi_alarm_xmpp_func);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin alarm_xmpp_plugin = {
|
||||
.name = "alarm_xmpp",
|
||||
.on_load = uwsgi_alarm_xmpp_load,
|
||||
};
|
||||
@@ -0,0 +1,139 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <gloox/client.h>
|
||||
#include <gloox/message.h>
|
||||
#include <gloox/connectionlistener.h>
|
||||
#include <gloox/connectiontcpclient.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
using namespace gloox;
|
||||
|
||||
class Jabbo : public ConnectionListener{
|
||||
|
||||
public:
|
||||
|
||||
Jabbo(struct uwsgi_thread *ut, char *jab_username, char *jab_password, char *dests) {
|
||||
|
||||
u_thread = ut;
|
||||
dest = NULL;
|
||||
|
||||
char *ctx = NULL;
|
||||
char *p = strtok_r(dests, ",", &ctx);
|
||||
while(p) {
|
||||
uwsgi_string_new_list(&dest, p);
|
||||
p = strtok_r(NULL, ",", &ctx);
|
||||
}
|
||||
|
||||
JID jid(jab_username);
|
||||
client = new Client( jid, jab_password );
|
||||
client->registerConnectionListener(this);
|
||||
u_connected = 0;
|
||||
client->connect(false);
|
||||
fd = static_cast<ConnectionTCPClient*>( client->connectionImpl() )->socket();
|
||||
}
|
||||
|
||||
~Jabbo() {
|
||||
delete client;
|
||||
}
|
||||
|
||||
void send(char *buf, size_t len) {
|
||||
struct uwsgi_string_list *usl = dest;
|
||||
while(usl) {
|
||||
JID jid(usl->value);
|
||||
std::string text(buf, len);
|
||||
Message msg(Message::Chat, jid, text);
|
||||
client->send(msg);
|
||||
usl = usl->next;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void onConnect() {
|
||||
event_queue_add_fd_read(u_thread->queue, fd);
|
||||
u_connected = 1;
|
||||
}
|
||||
|
||||
virtual void onDisconnect(ConnectionError e) {
|
||||
if (fd >= 0) {
|
||||
event_queue_del_fd(u_thread->queue, fd, event_queue_read());
|
||||
}
|
||||
sleep(1);
|
||||
u_connected = 0;
|
||||
client->connect(false);
|
||||
fd = static_cast<ConnectionTCPClient*>( client->connectionImpl() )->socket();
|
||||
}
|
||||
|
||||
virtual bool onTLSConnect(const CertInfo& info) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Client* client;
|
||||
int fd;
|
||||
int u_connected;
|
||||
struct uwsgi_thread *u_thread;
|
||||
struct uwsgi_string_list *dest;
|
||||
};
|
||||
|
||||
|
||||
extern "C" void uwsgi_alarm_xmpp_loop(struct uwsgi_thread *ut) {
|
||||
|
||||
int interesting_fd;
|
||||
|
||||
ut->buf = (char *) uwsgi_malloc(uwsgi.log_master_bufsize);
|
||||
|
||||
char *xmpp_username = (char *) "";
|
||||
char *xmpp_password = (char *) "";
|
||||
char *xmpp_dests = (char *) "";
|
||||
|
||||
// 0 -> username, 1 -> password, 2-> dest list
|
||||
int opt_state = 0;
|
||||
// fill xmpp options
|
||||
char *ctx = NULL;
|
||||
char *opts = uwsgi_str((char *)ut->data);
|
||||
char *p = strtok_r(opts, ";", &ctx);
|
||||
while(p) {
|
||||
switch(opt_state) {
|
||||
case 0:
|
||||
xmpp_username = p;
|
||||
opt_state = 1;
|
||||
break;
|
||||
case 1:
|
||||
xmpp_password = p;
|
||||
opt_state = 2;
|
||||
break;
|
||||
case 2:
|
||||
xmpp_dests = p;
|
||||
opt_state = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
p = strtok_r(NULL, ";", &ctx);
|
||||
}
|
||||
|
||||
Jabbo j(ut, xmpp_username, xmpp_password, xmpp_dests);
|
||||
|
||||
int timeout = 0;
|
||||
|
||||
for(;;) {
|
||||
if (j.u_connected) {
|
||||
timeout = -1;
|
||||
}
|
||||
else {
|
||||
timeout = 0;
|
||||
}
|
||||
int ret = event_queue_wait(ut->queue, timeout, &interesting_fd);
|
||||
if (ret < 0) continue;
|
||||
|
||||
if (ret > 0 && interesting_fd == ut->pipe[1]) {
|
||||
ssize_t rlen = read(ut->pipe[1], ut->buf, uwsgi.log_master_bufsize);
|
||||
if (rlen <= 0) continue;
|
||||
if (j.u_connected) {
|
||||
j.send(ut->buf, rlen);
|
||||
}
|
||||
}
|
||||
else if (ret == 0 || (ret > 0 && j.fd > -1 && interesting_fd == j.fd)) {
|
||||
j.client->recv();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='alarm_xmpp'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lgloox']
|
||||
GCC_LIST = ['alarm_xmpp_plugin', 'gloox.cc']
|
||||
+216
-145
@@ -2,22 +2,37 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct carbon_server_list {
|
||||
char *value; // server address
|
||||
int healthy;
|
||||
int errors;
|
||||
struct carbon_server_list *next;
|
||||
};
|
||||
|
||||
struct uwsgi_carbon {
|
||||
struct uwsgi_string_list *servers;
|
||||
struct carbon_server_list *servers_data;
|
||||
int freq;
|
||||
int timeout;
|
||||
char *id;
|
||||
int no_workers;
|
||||
unsigned long long *last_busyness_values;
|
||||
unsigned long long *current_busyness_values;
|
||||
int need_retry;
|
||||
time_t last_update;
|
||||
time_t next_retry;
|
||||
int max_retries;
|
||||
int retry_delay;
|
||||
} u_carbon;
|
||||
|
||||
struct uwsgi_option carbon_options[] = {
|
||||
{"carbon", required_argument, 0, "push statistics to the specified carbon server", uwsgi_opt_add_string_list, &u_carbon.servers, UWSGI_OPT_MASTER},
|
||||
{"carbon-timeout", required_argument, 0, "set carbon connection timeout", uwsgi_opt_set_int, &u_carbon.timeout, 0},
|
||||
{"carbon-freq", required_argument, 0, "set carbon push frequency", uwsgi_opt_set_int, &u_carbon.freq, 0},
|
||||
{"carbon-timeout", required_argument, 0, "set carbon connection timeout in seconds (default 3)", uwsgi_opt_set_int, &u_carbon.timeout, 0},
|
||||
{"carbon-freq", required_argument, 0, "set carbon push frequency in seconds (default 60)", uwsgi_opt_set_int, &u_carbon.freq, 0},
|
||||
{"carbon-id", required_argument, 0, "set carbon id", uwsgi_opt_set_str, &u_carbon.id, 0},
|
||||
{"carbon-no-workers", no_argument, 0, "disable generation of single worker metrics", uwsgi_opt_true, &u_carbon.no_workers, 0},
|
||||
{"carbon-max-retry", required_argument, 0, "set maximum number of retries in case of connection errors (default 1)", uwsgi_opt_set_int, &u_carbon.max_retries, 0},
|
||||
{"carbon-retry-delay", required_argument, 0, "set connection retry delay in seconds (default 7)", uwsgi_opt_set_int, &u_carbon.retry_delay, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
};
|
||||
@@ -31,12 +46,23 @@ void carbon_post_init() {
|
||||
if (!u_carbon.servers) return;
|
||||
|
||||
while(usl) {
|
||||
uwsgi_log("added carbon server %s\n", usl->value);
|
||||
struct carbon_server_list *u_server = uwsgi_calloc(sizeof(struct carbon_server_list));
|
||||
u_server->value = usl->value;
|
||||
u_server->healthy = 1;
|
||||
u_server->errors = 0;
|
||||
if (u_carbon.servers_data) {
|
||||
u_server->next = u_carbon.servers_data;
|
||||
}
|
||||
u_carbon.servers_data = u_server;
|
||||
|
||||
uwsgi_log("[carbon] added server %s\n", usl->value);
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
if (u_carbon.freq < 1) u_carbon.freq = 60;
|
||||
if (u_carbon.timeout < 1) u_carbon.timeout = 3;
|
||||
if (u_carbon.max_retries <= 0) u_carbon.max_retries = 1;
|
||||
if (u_carbon.retry_delay <= 0) u_carbon.retry_delay = 7;
|
||||
if (!u_carbon.id) {
|
||||
u_carbon.id = uwsgi_str(uwsgi.sockets->name);
|
||||
|
||||
@@ -53,153 +79,198 @@ void carbon_post_init() {
|
||||
u_carbon.current_busyness_values = uwsgi_calloc(sizeof(unsigned long long) * uwsgi.numproc);
|
||||
}
|
||||
|
||||
// set next update to now()+retry_delay, this way we will have first flush just after start
|
||||
u_carbon.last_update = uwsgi_now() - u_carbon.freq + u_carbon.retry_delay;
|
||||
|
||||
uwsgi_log("[carbon] carbon plugin started, %is frequency, %is timeout, max retries %i, retry delay %is",
|
||||
u_carbon.freq, u_carbon.timeout, u_carbon.max_retries, u_carbon.retry_delay);
|
||||
}
|
||||
|
||||
int carbon_write(int *fd, char *fmt,...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
char ptr[4096];
|
||||
int rlen;
|
||||
|
||||
rlen = vsnprintf(ptr, 4096, fmt, ap);
|
||||
|
||||
if (rlen < 1) return 0;
|
||||
|
||||
if (write(*fd, ptr, rlen) <= 0) {
|
||||
uwsgi_error("write()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void carbon_push_stats(int retry_cycle) {
|
||||
struct carbon_server_list *usl = u_carbon.servers_data;
|
||||
int i;
|
||||
int fd;
|
||||
int wok;
|
||||
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i];
|
||||
u_carbon.last_busyness_values[i] = uwsgi.workers[i+1].running_time;
|
||||
}
|
||||
|
||||
u_carbon.need_retry = 0;
|
||||
while(usl) {
|
||||
if (retry_cycle && usl->healthy)
|
||||
// skip healthy servers during retry cycle
|
||||
goto nxt;
|
||||
|
||||
if (retry_cycle && usl->healthy == 0)
|
||||
uwsgi_log("[carbon] Retrying failed server at %s (%d)\n", usl->value, usl->errors);
|
||||
|
||||
if (!retry_cycle) {
|
||||
usl->healthy = 1;
|
||||
usl->errors = 0;
|
||||
}
|
||||
|
||||
fd = uwsgi_connect(usl->value, u_carbon.timeout, 0);
|
||||
if (fd < 0) {
|
||||
uwsgi_log("[carbon] Could not connect to carbon server at %s\n", usl->value);
|
||||
if (usl->errors < u_carbon.max_retries) {
|
||||
u_carbon.need_retry = 1;
|
||||
u_carbon.next_retry = uwsgi_now() + u_carbon.retry_delay;
|
||||
} else {
|
||||
uwsgi_log("[carbon] Maximum number of retries for %s (1)\n",
|
||||
usl->value, u_carbon.max_retries);
|
||||
usl->healthy = 0;
|
||||
usl->errors = 0;
|
||||
}
|
||||
usl->healthy = 0;
|
||||
usl->errors++;
|
||||
goto nxt;
|
||||
}
|
||||
// put the socket in non-blocking mode
|
||||
uwsgi_socket_nb(fd);
|
||||
|
||||
unsigned long long total_rss = 0;
|
||||
unsigned long long total_vsz = 0;
|
||||
unsigned long long total_tx = 0;
|
||||
unsigned long long total_avg_rt = 0; // total avg_rt
|
||||
unsigned long long avg_rt = 0; // per worker avg_rt reported to carbon
|
||||
unsigned long long active_workers = 0; // number of workers used to calculate total avg_rt
|
||||
unsigned long long total_busyness = 0;
|
||||
unsigned long long total_avg_busyness = 0;
|
||||
unsigned long long worker_busyness = 0;
|
||||
unsigned long long total_harakiri = 0;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.workers[0].requests, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
total_tx += uwsgi.workers[i].tx;
|
||||
if (uwsgi.workers[i].cheaped) {
|
||||
// also if worker is cheaped than we report its average response time as zero, sending last value might be confusing
|
||||
avg_rt = 0;
|
||||
worker_busyness = 0;
|
||||
}
|
||||
else {
|
||||
// global average response time is calculated from active/idle workers, cheaped workers are excluded, otherwise it is not accurate
|
||||
avg_rt = uwsgi.workers[i].avg_response_time;
|
||||
active_workers++;
|
||||
total_avg_rt += uwsgi.workers[i].avg_response_time;
|
||||
|
||||
// calculate worker busyness
|
||||
worker_busyness = ((u_carbon.current_busyness_values[i-1]*100) / (u_carbon.freq*1000000));
|
||||
if (worker_busyness > 100) worker_busyness = 100;
|
||||
total_busyness += worker_busyness;
|
||||
|
||||
// only running workers are counted in total memory stats
|
||||
total_rss += uwsgi.workers[i].rss_size;
|
||||
total_vsz += uwsgi.workers[i].vsz_size;
|
||||
|
||||
total_harakiri += uwsgi.workers[i].harakiri_count/2;
|
||||
}
|
||||
|
||||
//skip per worker metrics when disabled
|
||||
if (u_carbon.no_workers) continue;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].requests, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].rss_size, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].vsz_size, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) avg_rt, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].tx, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) worker_busyness, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].harakiri_count/2, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
}
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_rss, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_vsz, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) (active_workers ? total_avg_rt / active_workers : 0), (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_tx, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
if (active_workers > 0) {
|
||||
total_avg_busyness = total_busyness / active_workers;
|
||||
if (total_avg_busyness > 100) total_avg_busyness = 100;
|
||||
} else {
|
||||
total_avg_busyness = 0;
|
||||
}
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_avg_busyness, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.active_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) active_workers, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
if (uwsgi.cheaper) {
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.cheaped_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.numproc - active_workers, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
}
|
||||
|
||||
wok = carbon_write(&fd, "uwsgi.%s.%s.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) uwsgi.current_time);
|
||||
if (!wok) goto clear;
|
||||
|
||||
usl->healthy = 1;
|
||||
usl->errors = 0;
|
||||
|
||||
clear:
|
||||
close(fd);
|
||||
nxt:
|
||||
usl = usl->next;
|
||||
}
|
||||
if (!retry_cycle) u_carbon.last_update = uwsgi_now();
|
||||
if (u_carbon.need_retry)
|
||||
// timeouts and retries might cause additional lags in carbon cycles, we will adjust timer to fix that
|
||||
u_carbon.last_update -= u_carbon.timeout;
|
||||
}
|
||||
|
||||
void carbon_master_cycle() {
|
||||
|
||||
static time_t last_update = 0;
|
||||
char ptr[4096];
|
||||
int rlen, i;
|
||||
int fd;
|
||||
struct uwsgi_string_list *usl = u_carbon.servers;
|
||||
if (!u_carbon.servers) return;
|
||||
|
||||
if (!u_carbon.servers) return ;
|
||||
|
||||
if (last_update == 0) last_update = uwsgi_now();
|
||||
|
||||
// update
|
||||
if (uwsgi.current_time - last_update >= u_carbon.freq || uwsgi.cleaning) {
|
||||
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i];
|
||||
u_carbon.last_busyness_values[i] = uwsgi.workers[i+1].running_time;
|
||||
}
|
||||
|
||||
while(usl) {
|
||||
fd = uwsgi_connect(usl->value, u_carbon.timeout, 0);
|
||||
if (fd < 0) goto nxt;
|
||||
// put the socket in non-blocking mode
|
||||
uwsgi_socket_nb(fd);
|
||||
|
||||
unsigned long long total_rss = 0;
|
||||
unsigned long long total_vsz = 0;
|
||||
unsigned long long total_tx = 0;
|
||||
unsigned long long total_avg_rt = 0; // total avg_rt
|
||||
unsigned long long avg_rt = 0; // per worker avg_rt reported to carbon
|
||||
unsigned long long active_workers = 0; // number of workers used to calculate total avg_rt
|
||||
unsigned long long total_busyness = 0;
|
||||
unsigned long long total_avg_busyness = 0;
|
||||
unsigned long long worker_busyness = 0;
|
||||
unsigned long long total_harakiri = 0;
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) uwsgi.workers[0].requests, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
total_tx += uwsgi.workers[i].tx;
|
||||
if (uwsgi.workers[i].cheaped) {
|
||||
// also if worker is cheaped than we report its average response time as zero, sending last value might be confusing
|
||||
avg_rt = 0;
|
||||
worker_busyness = 0;
|
||||
}
|
||||
else {
|
||||
// global average response time is calcucalted from active/idle workers, cheaped workers are excluded, otherwise it is not accurate
|
||||
avg_rt = uwsgi.workers[i].avg_response_time;
|
||||
active_workers++;
|
||||
total_avg_rt += uwsgi.workers[i].avg_response_time;
|
||||
|
||||
// calculate worker busyness
|
||||
worker_busyness = ((u_carbon.current_busyness_values[i-1]*100) / (u_carbon.freq*1000000));
|
||||
if (worker_busyness > 100) worker_busyness = 100;
|
||||
total_busyness += worker_busyness;
|
||||
|
||||
// only running workers are counted in total memory stats
|
||||
total_rss += uwsgi.workers[i].rss_size;
|
||||
total_vsz += uwsgi.workers[i].vsz_size;
|
||||
|
||||
total_harakiri += uwsgi.workers[i].harakiri_count/2;
|
||||
}
|
||||
|
||||
//skip per worker metrics when disabled
|
||||
if (u_carbon.no_workers) continue;
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].requests, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].rss_size, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].vsz_size, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) avg_rt, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].tx, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) worker_busyness, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].harakiri_count/2, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_rss, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_vsz, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) (active_workers ? total_avg_rt / active_workers : 0), (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_tx, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
if (active_workers > 0) {
|
||||
total_avg_busyness = total_busyness / active_workers;
|
||||
if (total_avg_busyness > 100) total_avg_busyness = 100;
|
||||
} else {
|
||||
total_avg_busyness = 0;
|
||||
}
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_avg_busyness, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.active_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) active_workers, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
if (uwsgi.cheaper) {
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.cheaped_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) uwsgi.numproc - active_workers, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
}
|
||||
|
||||
rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_harakiri, (unsigned long long ) uwsgi.current_time);
|
||||
if (rlen < 1) goto clear;
|
||||
if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;}
|
||||
|
||||
clear:
|
||||
close(fd);
|
||||
nxt:
|
||||
usl = usl->next;
|
||||
}
|
||||
last_update = uwsgi_now();
|
||||
if (uwsgi.current_time - u_carbon.last_update >= u_carbon.freq || uwsgi.cleaning) {
|
||||
// update
|
||||
u_carbon.need_retry = 0;
|
||||
carbon_push_stats(0);
|
||||
} else if (u_carbon.need_retry && (uwsgi.current_time >= u_carbon.next_retry)) {
|
||||
// retry failed servers
|
||||
carbon_push_stats(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ time_t uwsgi_monotonic_seconds() {
|
||||
uint64_t uwsgi_monotonic_microseconds() {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
|
||||
return ((uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ time_t uwsgi_realtime_seconds() {
|
||||
uint64_t uwsgi_realtime_microseconds() {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return (ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
|
||||
return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -89,7 +89,9 @@ struct corerouter_session {
|
||||
int instance_fd;
|
||||
int instance_stopped;
|
||||
int status;
|
||||
|
||||
uint8_t h_pos;
|
||||
|
||||
uint16_t pos;
|
||||
|
||||
struct uwsgi_gateway_socket *ugs;
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
#include "client/dbclient.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_instance *ui;
|
||||
|
||||
// one for each mongodb imperial monitor
|
||||
struct uwsgi_emperor_mongodb_state {
|
||||
char *address;
|
||||
char *collection;
|
||||
char *json;
|
||||
};
|
||||
|
||||
|
||||
extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues) {
|
||||
|
||||
struct uwsgi_emperor_mongodb_state *uems = (struct uwsgi_emperor_mongodb_state *) ues->data;
|
||||
|
||||
try {
|
||||
|
||||
// requested fields
|
||||
mongo::BSONObj p = BSON( "name" << 1 << "config" << 1 << "ts" << 1 << "uid" << 1 << "gid" << 1 );
|
||||
mongo::BSONObj q = mongo::fromjson(uems->json);
|
||||
// the connection object (will be automatically destroyed at each cycle)
|
||||
mongo::DBClientConnection c;
|
||||
// set the socket timeout
|
||||
c.setSoTimeout(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
// connect
|
||||
c.connect(uems->address);
|
||||
|
||||
// run the query
|
||||
std::auto_ptr<mongo::DBClientCursor> cursor = c.query(uems->collection, q, 0, 0, &p);
|
||||
while( cursor->more() ) {
|
||||
mongo::BSONObj p = cursor->next();
|
||||
|
||||
// checking for an empty string is not required, but we reduce the load
|
||||
// in case of badly strctured databases
|
||||
const char *name = p.getStringField("name");
|
||||
if (strlen(name) == 0) continue;
|
||||
|
||||
const char *config = p.getStringField("config");
|
||||
|
||||
time_t vassal_ts = 0;
|
||||
// ts must be a Date object !!!
|
||||
mongo::BSONElement ts = p.getField("ts");
|
||||
if (ts.type() == mongo::Date) {
|
||||
vassal_ts = ts.date();
|
||||
}
|
||||
|
||||
uid_t vassal_uid = 0;
|
||||
gid_t vassal_gid = 0;
|
||||
// check for tyrant mode
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
int tmp_uid = p.getIntField("uid");
|
||||
int tmp_gid = p.getIntField("gid");
|
||||
if (tmp_uid < 0) tmp_uid = 0;
|
||||
if (tmp_gid < 0) tmp_gid = 0;
|
||||
vassal_uid = tmp_uid;
|
||||
vassal_gid = tmp_gid;
|
||||
}
|
||||
|
||||
uwsgi_emperor_simple_do(ues, (char *) name, (char *) config, vassal_ts/1000, vassal_uid, vassal_gid);
|
||||
}
|
||||
|
||||
|
||||
// now check for removed instances
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
|
||||
while (c_ui) {
|
||||
if (c_ui->scanner == ues) {
|
||||
mongo::BSONObjBuilder b;
|
||||
b.appendElements(q);
|
||||
b.append("name", c_ui->name);
|
||||
mongo::BSONObj q2 = b.obj();
|
||||
cursor = c.query(uems->collection, q2, 0, 0, &p);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("JSON: %s\n", q2.toString().c_str());
|
||||
#endif
|
||||
if (!cursor->more()) {
|
||||
emperor_stop(c_ui);
|
||||
}
|
||||
}
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch ( mongo::DBException &e ) {
|
||||
uwsgi_log("[emperor-mongodb] ERROR(%s/%s): %s\n", uems->address, uems->collection, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// setup a new mongodb imperial monitor
|
||||
extern "C" void uwsgi_imperial_monitor_mongodb_init(struct uwsgi_emperor_scanner *ues) {
|
||||
|
||||
// allocate a new state
|
||||
ues->data = uwsgi_calloc(sizeof(struct uwsgi_emperor_mongodb_state));
|
||||
size_t arg_len = strlen(ues->arg);
|
||||
struct uwsgi_emperor_mongodb_state *uems = (struct uwsgi_emperor_mongodb_state *) ues->data;
|
||||
|
||||
// parse args/ set defaults
|
||||
uems->address = (char *) "127.0.0.1:27017";
|
||||
uems->collection = (char *) "uwsgi.emperor.vassals";
|
||||
uems->json = (char *) "";
|
||||
if (arg_len > 10) {
|
||||
uems->address = uwsgi_str(ues->arg+10);
|
||||
char *comma = strchr(uems->address, ',');
|
||||
if (!comma) goto done;
|
||||
*comma = 0;
|
||||
uems->collection = comma+1;
|
||||
comma = strchr(uems->collection, ',');
|
||||
if (!comma) goto done;
|
||||
*comma = 0;
|
||||
uems->json = comma+1;
|
||||
}
|
||||
done:
|
||||
uwsgi_log("[emperor] enabled emperor MongoDB monitor for %s on collection %s\n", uems->address, uems->collection);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *);
|
||||
void uwsgi_imperial_monitor_mongodb_init(struct uwsgi_emperor_scanner *);
|
||||
|
||||
void emperor_mongodb_init(void) {
|
||||
uwsgi_register_imperial_monitor("mongodb", uwsgi_imperial_monitor_mongodb_init, uwsgi_imperial_monitor_mongodb);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin emperor_mongodb_plugin = {
|
||||
|
||||
.name = "emperor_mongodb",
|
||||
.on_load = emperor_mongodb_init,
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
NAME='emperor_mongodb'
|
||||
|
||||
CFLAGS = ['-I/usr/include/mongo','-I/usr/local/include/mongo']
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lmongoclient', '-lboost_thread','-lboost_filesystem']
|
||||
|
||||
GCC_LIST = ['plugin', 'emperor_mongodb.cc']
|
||||
@@ -7,7 +7,6 @@ extern struct uwsgi_instance *ui;
|
||||
void uwsgi_imperial_monitor_pg_init(struct uwsgi_emperor_scanner *);
|
||||
void uwsgi_imperial_monitor_pg(struct uwsgi_emperor_scanner *);
|
||||
void emperor_pg_init(void);
|
||||
void emperor_pg_do(struct uwsgi_emperor_scanner *, char *, char *, time_t, uid_t, gid_t);
|
||||
|
||||
void emperor_pg_init(void) {
|
||||
uwsgi_register_imperial_monitor("pg", uwsgi_imperial_monitor_pg_init, uwsgi_imperial_monitor_pg);
|
||||
@@ -17,39 +16,6 @@ void uwsgi_imperial_monitor_pg_init(struct uwsgi_emperor_scanner *ues) {
|
||||
uwsgi_log("[emperor] enabled emperor PostgreSQL monitor\n");
|
||||
}
|
||||
|
||||
void emperor_pg_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;
|
||||
|
||||
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(config), uid, gid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_imperial_monitor_pg(struct uwsgi_emperor_scanner *ues) {
|
||||
|
||||
PGconn *conn = NULL;
|
||||
@@ -102,7 +68,7 @@ void uwsgi_imperial_monitor_pg(struct uwsgi_emperor_scanner *ues) {
|
||||
vassal_uid = uwsgi_str_num(q_uid, strlen(q_uid));
|
||||
vassal_gid = uwsgi_str_num(q_gid, strlen(q_gid));
|
||||
}
|
||||
emperor_pg_do(ues, name, config, uwsgi_str_num(ts, len), vassal_uid, vassal_gid);
|
||||
uwsgi_emperor_simple_do(ues, name, config, uwsgi_str_num(ts, len), vassal_uid, vassal_gid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,4 +4,6 @@ CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
REQUIRES = ['corerouter']
|
||||
|
||||
GCC_LIST = ['fastrouter', 'fr_events']
|
||||
|
||||
@@ -15,7 +15,7 @@ VALUE uwsgi_fiber_request() {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
inline static void fiber_schedule_to_req() {
|
||||
static inline void fiber_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
@@ -33,7 +33,7 @@ inline static void fiber_schedule_to_req() {
|
||||
|
||||
}
|
||||
|
||||
inline static void fiber_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
static inline void fiber_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
rb_fiber_yield(0, NULL);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
import os
|
||||
|
||||
NAME='fiber'
|
||||
|
||||
try:
|
||||
RUBYPATH = os.environ['UWSGICONFIG_RUBYPATH']
|
||||
except:
|
||||
RUBYPATH = 'ruby'
|
||||
|
||||
NAME='fiber'
|
||||
CFLAGS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['CFLAGS']\"").read().rstrip().split()
|
||||
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
CFLAGS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print RbConfig::CONFIG['CFLAGS']\"").read().rstrip().split()
|
||||
CFLAGS.append('-DRUBY19')
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
rbconfig = 'RbConfig'
|
||||
|
||||
includedir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['rubyhdrdir']\"").read().rstrip()
|
||||
includedir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['rubyhdrdir']\"" % rbconfig).read().rstrip()
|
||||
if includedir == 'nil':
|
||||
includedir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['archdir']\"").read().rstrip()
|
||||
includedir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['archdir']\"" % rbconfig).read().rstrip()
|
||||
CFLAGS.append('-I' + includedir)
|
||||
else:
|
||||
CFLAGS.append('-I' + includedir)
|
||||
archdir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['archdir']\"").read().rstrip()
|
||||
arch = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['arch']\"").read().rstrip()
|
||||
archdir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['archdir']\"" % rbconfig).read().rstrip()
|
||||
arch = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['arch']\"" % rbconfig).read().rstrip()
|
||||
CFLAGS.append('-I' + archdir)
|
||||
CFLAGS.append('-I' + archdir + '/' + arch)
|
||||
CFLAGS.append('-I' + includedir + '/' + arch)
|
||||
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ PyObject *py_uwsgi_greenlet_request(PyObject * self, PyObject *args) {
|
||||
|
||||
PyMethodDef uwsgi_greenlet_request_method[] = {{"uwsgi_greenlet_request", py_uwsgi_greenlet_request, METH_VARARGS, ""}};
|
||||
|
||||
inline static void greenlet_schedule_to_req() {
|
||||
static inline void greenlet_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
@@ -45,7 +45,7 @@ inline static void greenlet_schedule_to_req() {
|
||||
|
||||
}
|
||||
|
||||
inline static void greenlet_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
static inline void greenlet_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyGreenlet_Switch(ugl.main, NULL, NULL);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
+5
-5
@@ -506,7 +506,8 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
goto choose_node;
|
||||
}
|
||||
|
||||
len = cs->recv(&uhttp.cr, cs, hs->buffer + cs->h_pos, UMAX16 - cs->h_pos);
|
||||
|
||||
len = cs->recv(&uhttp.cr, cs, hs->buffer + cs->pos, UMAX16 - cs->pos);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(ucr->queue, cs->fd);
|
||||
#endif
|
||||
@@ -517,10 +518,9 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
break;
|
||||
}
|
||||
|
||||
cs->h_pos += len;
|
||||
cs->pos += len;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
//uwsgi_log("%d %d %d\n", j, *cs->ptr, cs->rnrn);
|
||||
if (*hs->ptr == '\r' && (hs->rnrn == 0 || hs->rnrn == 2)) {
|
||||
hs->rnrn++;
|
||||
}
|
||||
@@ -531,6 +531,7 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
hs->rnrn = 2;
|
||||
}
|
||||
else if (*hs->ptr == '\n' && hs->rnrn == 3) {
|
||||
|
||||
hs->ptr++;
|
||||
cs->post_remains = len - (j + 1);
|
||||
hs->iov_len = http_parse(hs);
|
||||
@@ -597,7 +598,6 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
}
|
||||
|
||||
|
||||
|
||||
cs->pass_fd = is_unix(cs->instance_address, cs->instance_address_len);
|
||||
|
||||
cs->instance_fd = uwsgi_connectn(cs->instance_address, cs->instance_address_len, 0, 1);
|
||||
@@ -620,6 +620,7 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se
|
||||
else {
|
||||
hs->rnrn = 0;
|
||||
}
|
||||
|
||||
hs->ptr++;
|
||||
}
|
||||
|
||||
@@ -767,7 +768,6 @@ To have a reliable implementation, we need to reset a bunch of values
|
||||
hs->ptr = hs->buffer;
|
||||
hs->rnrn = 0;
|
||||
cs->pos = 0;
|
||||
cs->h_pos = 0;
|
||||
hs->received_body = 0;
|
||||
cs->post_cl = 0;
|
||||
cs->instance_fd = -1;
|
||||
|
||||
@@ -4,4 +4,6 @@ CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
REQUIRES = ['corerouter']
|
||||
|
||||
GCC_LIST = ['http']
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_mongodb_header {
|
||||
int32_t len;
|
||||
int32_t request_id;
|
||||
int32_t response_id;
|
||||
int32_t opcode;
|
||||
};
|
||||
|
||||
struct uwsgi_mongodb_state {
|
||||
int fd;
|
||||
char *address;
|
||||
int32_t base_len;
|
||||
struct uwsgi_mongodb_header header;
|
||||
int32_t flags;
|
||||
char *collection;
|
||||
|
||||
|
||||
int32_t bson_base_len;
|
||||
int32_t bson_len;
|
||||
|
||||
int64_t ts;
|
||||
|
||||
int32_t bson_node_len;
|
||||
char *bson_node;
|
||||
int32_t bson_msg_len;
|
||||
struct iovec iovec[13];
|
||||
};
|
||||
|
||||
ssize_t uwsgi_mongodb_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
struct uwsgi_mongodb_state *ums = NULL;
|
||||
|
||||
if (!ul->configured) {
|
||||
|
||||
ul->data = uwsgi_calloc(sizeof(struct uwsgi_mongodb_state));
|
||||
ums = (struct uwsgi_mongodb_state *) ul->data;
|
||||
|
||||
// full default
|
||||
if (ul->arg == NULL) {
|
||||
ums->address = uwsgi_str("127.0.0.1:27017");
|
||||
ums->collection = "uwsgi.logs";
|
||||
ums->bson_node = uwsgi.hostname;
|
||||
ums->bson_node_len = uwsgi.hostname_len;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ums->address = uwsgi_str(ul->arg);
|
||||
char *collection = strchr(ums->address, ',');
|
||||
// default to uwsgi.logs
|
||||
if (!collection) {
|
||||
ums->collection = "uwsgi.logs";
|
||||
ums->bson_node = uwsgi.hostname;
|
||||
ums->bson_node_len = uwsgi.hostname_len;
|
||||
goto done;
|
||||
}
|
||||
*collection = 0;
|
||||
ums->collection = collection+1;
|
||||
|
||||
char *node = strchr(ums->collection, ',');
|
||||
// default to hostname
|
||||
if (!node) {
|
||||
ums->bson_node = uwsgi.hostname;
|
||||
ums->bson_node_len = uwsgi.hostname_len;
|
||||
goto done;
|
||||
}
|
||||
*node = 0;
|
||||
ums->bson_node = node+1;
|
||||
ums->bson_node_len = strlen(ums->bson_node)+1;
|
||||
|
||||
done:
|
||||
ums->fd = -1;
|
||||
// header
|
||||
ums->iovec[0].iov_base = &ums->header;
|
||||
ums->iovec[0].iov_len = sizeof(struct uwsgi_mongodb_header);
|
||||
// OPCODE INSERT
|
||||
ums->header.opcode = 2002;
|
||||
// flags
|
||||
ums->iovec[1].iov_base = &ums->flags;
|
||||
ums->iovec[1].iov_len = sizeof(int32_t);
|
||||
// collection name
|
||||
ums->iovec[2].iov_base = ums->collection;
|
||||
ums->iovec[2].iov_len = strlen(ums->collection)+1;
|
||||
// BSON len
|
||||
ums->iovec[3].iov_base = &ums->bson_len;
|
||||
ums->iovec[3].iov_len = sizeof(int32_t);
|
||||
// BSON node
|
||||
ums->iovec[4].iov_base = "\x02node\0";
|
||||
ums->iovec[4].iov_len = 6;
|
||||
ums->iovec[5].iov_base = &ums->bson_node_len;
|
||||
ums->iovec[5].iov_len = sizeof(int32_t);
|
||||
ums->iovec[6].iov_base = ums->bson_node;
|
||||
ums->iovec[6].iov_len = ums->bson_node_len;
|
||||
|
||||
// BSON timestamp (ts)
|
||||
ums->iovec[7].iov_base = "\x09ts\0";
|
||||
ums->iovec[7].iov_len = 4;
|
||||
ums->iovec[8].iov_base = &ums->ts;
|
||||
ums->iovec[8].iov_len = sizeof(int64_t);
|
||||
|
||||
|
||||
// BSON msg
|
||||
ums->iovec[9].iov_base = "\2msg\0";
|
||||
ums->iovec[9].iov_len = 5;
|
||||
ums->iovec[10].iov_base = &ums->bson_msg_len;
|
||||
ums->iovec[10].iov_len = sizeof(int32_t);
|
||||
// iov 11 is reset at each cycle
|
||||
// ...
|
||||
// BSON end (msg_zero + bson_zero);
|
||||
ums->iovec[12].iov_base = "\0\0";
|
||||
ums->iovec[12].iov_len = 2;
|
||||
|
||||
ums->bson_base_len = ums->iovec[3].iov_len + ums->iovec[4].iov_len + ums->iovec[5].iov_len + ums->iovec[6].iov_len +
|
||||
ums->iovec[7].iov_len + ums->iovec[8].iov_len + ums->iovec[9].iov_len + ums->iovec[10].iov_len +
|
||||
ums->iovec[12].iov_len;
|
||||
|
||||
ums->base_len = ums->iovec[0].iov_len + ums->iovec[1].iov_len + ums->iovec[2].iov_len + ums->bson_base_len;
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
ums = (struct uwsgi_mongodb_state *) ul->data;
|
||||
|
||||
if (ums->fd == -1) {
|
||||
ums->fd = uwsgi_connect(ums->address, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
}
|
||||
|
||||
if (ums->fd == -1) return -1;
|
||||
|
||||
// fix the packet
|
||||
ums->bson_msg_len = len+1;
|
||||
ums->bson_len = ums->bson_base_len + len;
|
||||
ums->header.len = ums->base_len + len;
|
||||
ums->header.request_id++;
|
||||
|
||||
// get milliseconds time
|
||||
ums->ts = uwsgi_micros()/1000;
|
||||
|
||||
ums->iovec[11].iov_base = message;
|
||||
ums->iovec[11].iov_len = len;
|
||||
|
||||
ssize_t ret = writev(ums->fd, ums->iovec, 13);
|
||||
if (ret <= 0) {
|
||||
close(ums->fd);
|
||||
ums->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uwsgi_mongodblog_register() {
|
||||
uwsgi_register_logger("mongodblog", uwsgi_mongodb_logger);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin mongodblog_plugin = {
|
||||
|
||||
.name = "mongodblog",
|
||||
.on_load = uwsgi_mongodblog_register,
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='mongodblog'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['mongodblog_plugin']
|
||||
@@ -208,7 +208,7 @@ static int sapi_uwsgi_send_headers(sapi_headers_struct *sapi_headers)
|
||||
static int sapi_uwsgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
|
||||
{
|
||||
uint read_bytes = 0;
|
||||
size_t len;
|
||||
ssize_t len;
|
||||
int fd = -1;
|
||||
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
|
||||
|
||||
@@ -483,7 +483,9 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
|
||||
|
||||
PyObject *tmp_callable;
|
||||
PyObject *applications;
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
|
||||
#endif
|
||||
|
||||
char *module = (char *) arg1;
|
||||
|
||||
@@ -506,8 +508,10 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
applications = PyDict_GetItemString(uwsgi_dict, "applications");
|
||||
if (applications && PyDict_Check(applications)) return applications;
|
||||
#endif
|
||||
|
||||
applications = PyDict_GetItemString(wsgi_dict, "applications");
|
||||
if (applications && PyDict_Check(applications)) return applications;
|
||||
|
||||
@@ -282,6 +282,7 @@ realstuff:
|
||||
if (uwsgi.has_threads)
|
||||
PyGILState_Ensure();
|
||||
// no need to worry about freeing memory
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
|
||||
if (uwsgi_dict) {
|
||||
PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit");
|
||||
@@ -289,6 +290,7 @@ realstuff:
|
||||
python_call(ae, PyTuple_New(0), 0, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// this part is a 1:1 copy of mod_wsgi 3.x
|
||||
// it is required to fix some atexit bug with python 3
|
||||
@@ -528,8 +530,6 @@ next:
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
PyDoc_STRVAR(uwsgi_py_doc, "uWSGI api module.");
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PYTHREE
|
||||
static PyModuleDef uwsgi_module3 = {
|
||||
@@ -544,7 +544,6 @@ PyObject *init_uwsgi3(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
void init_uwsgi_embedded_module() {
|
||||
PyObject *new_uwsgi_module, *zero;
|
||||
int i;
|
||||
@@ -1050,6 +1049,11 @@ void uwsgi_python_init_apps() {
|
||||
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
// lazy ?
|
||||
if (uwsgi.mywid > 0) {
|
||||
UWSGI_GET_GIL;
|
||||
}
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
// prepare for stack suspend/resume
|
||||
if (uwsgi.async > 1) {
|
||||
@@ -1160,6 +1164,7 @@ next:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
|
||||
if (uwsgi_dict) {
|
||||
up.after_req_hook = PyDict_GetItemString(uwsgi_dict, "after_req_hook");
|
||||
@@ -1169,6 +1174,12 @@ next:
|
||||
Py_INCREF(up.after_req_hook_args);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// lazy ?
|
||||
if (uwsgi.mywid > 0) {
|
||||
UWSGI_RELEASE_GIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
int wait_for_specific_signal = 0;
|
||||
uint8_t uwsgi_signal = 0;
|
||||
uint8_t received_signal;
|
||||
int received_signal;
|
||||
|
||||
wsgi_req->signal_received = -1;
|
||||
|
||||
@@ -30,6 +30,11 @@ PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
||||
received_signal = uwsgi_signal_wait(-1);
|
||||
}
|
||||
|
||||
if (received_signal < 0) {
|
||||
UWSGI_GET_GIL;
|
||||
return PyErr_Format(PyExc_SystemError, "error waiting for signal");
|
||||
}
|
||||
|
||||
wsgi_req->signal_received = received_signal;
|
||||
|
||||
UWSGI_GET_GIL;
|
||||
|
||||
@@ -152,14 +152,14 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
if (uwsgi_waitfd(self->wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data: Content-Length %llu received %llu", (unsigned long long) self->wsgi_req->post_cl, (unsigned long long) self->wsgi_req->post_cl - remains);
|
||||
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data: Content-Length %llu requested %llu received %llu", (unsigned long long) self->wsgi_req->post_cl, (unsigned long long) remains + tmp_pos, (unsigned long long) tmp_pos);
|
||||
}
|
||||
|
||||
rlen = read(self->wsgi_req->poll.fd, tmp_buf+tmp_pos, remains);
|
||||
if (rlen <= 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data: Content-Length %llu received %llu", (unsigned long long) self->wsgi_req->post_cl, (unsigned long long) self->wsgi_req->post_cl - remains);
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data: Content-Length %llu requested %llu received %llu", (unsigned long long) self->wsgi_req->post_cl, (unsigned long long) remains + tmp_pos, (unsigned long long) tmp_pos);
|
||||
}
|
||||
tmp_pos += rlen;
|
||||
remains -= rlen;
|
||||
@@ -510,7 +510,9 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
// this object must be freed/cleared always
|
||||
#ifdef UWSGI_ASYNC
|
||||
end:
|
||||
#endif
|
||||
if (wsgi_req->async_input) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
|
||||
+13
-2
@@ -488,6 +488,7 @@ VALUE rack_uwsgi_add_file_monitor(VALUE *class, VALUE rbsignum, VALUE rbfilename
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
VALUE uwsgi_ruby_wait_fd_read(VALUE *class, VALUE arg1, VALUE arg2) {
|
||||
|
||||
Check_Type(arg1, T_FIXNUM);
|
||||
@@ -522,6 +523,7 @@ VALUE uwsgi_ruby_wait_fd_write(VALUE *class, VALUE arg1, VALUE arg2) {
|
||||
|
||||
return Qtrue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -535,6 +537,7 @@ VALUE uwsgi_ruby_async_connect(VALUE *class, VALUE arg) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) {
|
||||
|
||||
Check_Type(arg, T_FIXNUM);
|
||||
@@ -548,6 +551,7 @@ VALUE uwsgi_ruby_async_sleep(VALUE *class, VALUE arg) {
|
||||
|
||||
return Qtrue;
|
||||
}
|
||||
#endif
|
||||
|
||||
VALUE uwsgi_ruby_masterpid(VALUE *class) {
|
||||
|
||||
@@ -573,7 +577,7 @@ VALUE uwsgi_ruby_signal_wait(int argc, VALUE *argv, VALUE *class) {
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
int wait_for_specific_signal = 0;
|
||||
uint8_t uwsgi_signal = 0;
|
||||
uint8_t received_signal;
|
||||
int received_signal;
|
||||
|
||||
wsgi_req->signal_received = -1;
|
||||
|
||||
@@ -590,7 +594,12 @@ VALUE uwsgi_ruby_signal_wait(int argc, VALUE *argv, VALUE *class) {
|
||||
received_signal = uwsgi_signal_wait(-1);
|
||||
}
|
||||
|
||||
wsgi_req->signal_received = received_signal;
|
||||
if (received_signal < 0) {
|
||||
rb_raise(rb_eRuntimeError, "unable to call rpc function");
|
||||
}
|
||||
else {
|
||||
wsgi_req->signal_received = received_signal;
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
@@ -868,9 +877,11 @@ void uwsgi_rack_init_api() {
|
||||
VALUE rb_uwsgi_embedded = rb_define_module("UWSGI");
|
||||
uwsgi_rack_api("suspend", uwsgi_ruby_suspend, 0);
|
||||
uwsgi_rack_api("masterpid", uwsgi_ruby_masterpid, 0);
|
||||
#ifdef UWSGI_ASYNC
|
||||
uwsgi_rack_api("async_sleep", uwsgi_ruby_async_sleep, 1);
|
||||
uwsgi_rack_api("wait_fd_read", uwsgi_ruby_wait_fd_read, 2);
|
||||
uwsgi_rack_api("wait_fd_write", uwsgi_ruby_wait_fd_write, 2);
|
||||
#endif
|
||||
uwsgi_rack_api("async_connect", uwsgi_ruby_async_connect, 1);
|
||||
uwsgi_rack_api("signal", uwsgi_ruby_signal, -1);
|
||||
uwsgi_rack_api("register_signal", uwsgi_ruby_register_signal, 3);
|
||||
|
||||
+100
-58
@@ -79,6 +79,14 @@ VALUE rb_uwsgi_io_gets(VALUE obj, VALUE args) {
|
||||
struct wsgi_request *wsgi_req;
|
||||
VALUE line;
|
||||
Data_Get_Struct(obj, struct wsgi_request, wsgi_req);
|
||||
char linebuf[4096];
|
||||
|
||||
if (wsgi_req->async_post) {
|
||||
if (fgets(linebuf, 4096, (FILE *) wsgi_req->async_post) == NULL) {
|
||||
return Qnil;
|
||||
}
|
||||
return rb_str_new2(linebuf);
|
||||
}
|
||||
|
||||
// return a line of body
|
||||
for(i=wsgi_req->buf_pos;i<wsgi_req->post_cl;i++) {
|
||||
@@ -100,12 +108,18 @@ VALUE rb_uwsgi_io_gets(VALUE obj, VALUE args) {
|
||||
|
||||
VALUE rb_uwsgi_io_each(VALUE obj, VALUE args) {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
Data_Get_Struct(obj, struct wsgi_request, wsgi_req);
|
||||
if (!rb_block_given_p())
|
||||
rb_raise(rb_eArgError, "Expected block on rack.input 'each' method");
|
||||
|
||||
// yield strings chunks
|
||||
rb_raise(rb_eRuntimeError, "rack.input::each is not implemented (req %p)\n", wsgi_req);
|
||||
|
||||
for(;;) {
|
||||
VALUE chunk = rb_uwsgi_io_gets(obj, Qnil);
|
||||
if (chunk == Qnil) {
|
||||
return Qnil;
|
||||
}
|
||||
rb_yield(chunk);
|
||||
}
|
||||
// never here
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
@@ -114,13 +128,65 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) {
|
||||
struct wsgi_request *wsgi_req;
|
||||
Data_Get_Struct(obj, struct wsgi_request, wsgi_req);
|
||||
VALUE chunk;
|
||||
unsigned int chunk_size;
|
||||
long chunk_size;
|
||||
|
||||
if (!wsgi_req->post_cl || wsgi_req->buf_pos >= wsgi_req->post_cl) {
|
||||
/*
|
||||
When EOF is reached, this method returns nil if length is given and not nil, or "" if length is not given or is nil.
|
||||
If buffer is given, then the read data will be placed into buffer instead of a newly created String object.
|
||||
*/
|
||||
|
||||
// --- disk buffering ---
|
||||
|
||||
if (wsgi_req->async_post) {
|
||||
// 0 size, read the whole body from the file...
|
||||
if (RARRAY_LEN(args) == 0) {
|
||||
char *tmp_chunk = uwsgi_malloc(wsgi_req->post_cl);
|
||||
size_t rlen = fread(tmp_chunk, 1, wsgi_req->post_cl, (FILE *) wsgi_req->async_post);
|
||||
if (rlen == 0) {
|
||||
free(tmp_chunk);
|
||||
return rb_str_new("", 0);
|
||||
}
|
||||
// return a new string
|
||||
chunk = rb_str_new(tmp_chunk, rlen);
|
||||
free(tmp_chunk);
|
||||
return chunk;
|
||||
}
|
||||
// size specified
|
||||
else if (RARRAY_LEN(args) > 0) {
|
||||
if (RARRAY_PTR(args)[0] == Qnil) {
|
||||
chunk_size = wsgi_req->post_cl;
|
||||
}
|
||||
else {
|
||||
chunk_size = NUM2LONG(RARRAY_PTR(args)[0]);
|
||||
// hack to tolerate broken middlewares
|
||||
if (chunk_size <= 0) {
|
||||
chunk_size = wsgi_req->post_cl;
|
||||
}
|
||||
}
|
||||
char *tmp_chunk = uwsgi_malloc(chunk_size);
|
||||
size_t rlen = fread(tmp_chunk, 1, chunk_size, (FILE *) wsgi_req->async_post);
|
||||
// error, return Qnil
|
||||
if (rlen == 0) {
|
||||
free(tmp_chunk);
|
||||
return Qnil;
|
||||
}
|
||||
// push in the specified buffer
|
||||
if (RARRAY_LEN(args) > 1) {
|
||||
rb_str_cat(RARRAY_PTR(args)[1], tmp_chunk, rlen);
|
||||
}
|
||||
// return a new string
|
||||
chunk = rb_str_new(tmp_chunk, rlen);
|
||||
free(tmp_chunk);
|
||||
return chunk;
|
||||
}
|
||||
// never happend...
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
// --- memory buffering ---
|
||||
|
||||
// first check for virtual EOF
|
||||
if (!wsgi_req->post_cl || wsgi_req->buf_pos >= wsgi_req->post_cl) {
|
||||
if (RARRAY_LEN(args) > 0) {
|
||||
if (RARRAY_PTR(args)[0] == Qnil) {
|
||||
return rb_str_new("", 0);
|
||||
@@ -137,14 +203,21 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) {
|
||||
return chunk;
|
||||
}
|
||||
else if (RARRAY_LEN(args) > 0) {
|
||||
chunk_size = NUM2UINT(RARRAY_PTR(args)[0]);
|
||||
if (RARRAY_PTR(args)[0] == Qnil) {
|
||||
chunk_size = wsgi_req->post_cl;
|
||||
}
|
||||
else {
|
||||
chunk_size = NUM2LONG(RARRAY_PTR(args)[0]);
|
||||
// hack to tolerate broken middlewares
|
||||
if (chunk_size <= 0) {
|
||||
chunk_size = wsgi_req->post_cl;
|
||||
}
|
||||
}
|
||||
if (wsgi_req->buf_pos+chunk_size > wsgi_req->post_cl) {
|
||||
chunk_size = wsgi_req->post_cl-wsgi_req->buf_pos;
|
||||
}
|
||||
if (RARRAY_LEN(args) > 1) {
|
||||
rb_str_cat(RARRAY_PTR(args)[1], wsgi_req->post_buffering_buf+wsgi_req->buf_pos, chunk_size);
|
||||
wsgi_req->buf_pos+=chunk_size;
|
||||
return RARRAY_PTR(args)[1];
|
||||
}
|
||||
chunk = rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, chunk_size);
|
||||
wsgi_req->buf_pos+=chunk_size;
|
||||
@@ -163,8 +236,14 @@ VALUE rb_uwsgi_io_rewind(VALUE obj, VALUE args) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
wsgi_req->buf_pos = 0;
|
||||
|
||||
// buffered to disk ?
|
||||
if (wsgi_req->async_post) {
|
||||
rewind((FILE *) wsgi_req->async_post);
|
||||
}
|
||||
// or memory ???
|
||||
else {
|
||||
wsgi_req->buf_pos = 0;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
@@ -673,6 +752,11 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
if (!ur.call) {
|
||||
internal_server_error(wsgi_req, "Ruby application not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Standard RACK request */
|
||||
if (!wsgi_req->uh.pktsize) {
|
||||
uwsgi_log("Invalid RACK request. skip.\n");
|
||||
@@ -748,12 +832,7 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
VALUE dws_wr = Data_Wrap_Struct(ur.rb_uwsgi_io_class, 0, 0, wsgi_req);
|
||||
|
||||
if (wsgi_req->async_post) {
|
||||
rb_hash_aset(env, rb_str_new2("rack.input"), rb_funcall( rb_const_get(rb_cObject, rb_intern("IO")), rb_intern("new"), 2, INT2NUM(fileno((FILE*)wsgi_req->async_post)), rb_str_new("r",1) ));
|
||||
}
|
||||
else {
|
||||
rb_hash_aset(env, rb_str_new2("rack.input"), rb_funcall(ur.rb_uwsgi_io_class, rb_intern("new"), 1, dws_wr ));
|
||||
}
|
||||
rb_hash_aset(env, rb_str_new2("rack.input"), rb_funcall(ur.rb_uwsgi_io_class, rb_intern("new"), 1, dws_wr ));
|
||||
|
||||
rb_hash_aset(env, rb_str_new2("rack.errors"), rb_funcall( rb_const_get(rb_cObject, rb_intern("IO")), rb_intern("new"), 2, INT2NUM(2), rb_str_new("w",1) ));
|
||||
|
||||
@@ -909,44 +988,6 @@ void uwsgi_rack_resume(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("RESUMING RUBY\n");
|
||||
}
|
||||
|
||||
#ifdef RUBY19
|
||||
VALUE uwsgi_call_block(VALUE body, VALUE block) {
|
||||
|
||||
return rb_funcall(block, rb_intern("call"), 1, body );
|
||||
}
|
||||
|
||||
VALUE uwsgi_rack_patch_body_proxy_each(int argc, VALUE *argv, VALUE self) {
|
||||
|
||||
VALUE block = Qnil;
|
||||
rb_scan_args(argc, argv, "0&", &block);
|
||||
|
||||
if(!RTEST(block)) {
|
||||
rb_raise(rb_eArgError, "a block is required");
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE original_body = rb_iv_get(self, "@body");
|
||||
if (original_body != Qnil) {
|
||||
return rb_block_call(original_body, rb_intern("each"), 0, 0, uwsgi_call_block, block);
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE uwsgi_rack_patch_body_proxy(VALUE foo) {
|
||||
|
||||
VALUE rack = rb_const_get(rb_cObject, rb_intern("Rack"));
|
||||
VALUE rack_body_proxy = rb_const_get(rack, rb_intern("BodyProxy"));
|
||||
|
||||
if (!rb_respond_to(rack_body_proxy, rb_intern("each"))) {
|
||||
rb_define_method(rack_body_proxy, "each", uwsgi_rack_patch_body_proxy_each, -1);
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
#endif
|
||||
|
||||
VALUE init_rack_app( VALUE script ) {
|
||||
|
||||
int error;
|
||||
@@ -963,9 +1004,10 @@ VALUE init_rack_app( VALUE script ) {
|
||||
VALUE rack = rb_const_get(rb_cObject, rb_intern("Rack"));
|
||||
|
||||
#ifdef RUBY19
|
||||
VALUE ret = rb_protect(uwsgi_rack_patch_body_proxy, rack, &error);
|
||||
if (!error && ret != Qnil) {
|
||||
uwsgi_log("Rack::BodyProxy successfully patched for ruby 1.9.x\n");
|
||||
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
|
||||
|
||||
|
||||
@@ -4,4 +4,6 @@ CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
REQUIRES = ['corerouter']
|
||||
|
||||
GCC_LIST = ['rawrouter', 'rr_events']
|
||||
|
||||
@@ -10,7 +10,7 @@ struct uwsgi_redislog_state {
|
||||
char msgsize[11];
|
||||
struct iovec iovec[7];
|
||||
char response[8];
|
||||
} uredislog;
|
||||
};
|
||||
|
||||
static char *uwsgi_redis_logger_build_command(char *src) {
|
||||
ssize_t len = 4096;
|
||||
@@ -53,95 +53,102 @@ static char *uwsgi_redis_logger_build_command(char *src) {
|
||||
ssize_t uwsgi_redis_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
ssize_t ret,ret2;
|
||||
struct uwsgi_redislog_state *uredislog = NULL;
|
||||
|
||||
if (!ul->configured) {
|
||||
|
||||
if (!ul->data) {
|
||||
ul->data = uwsgi_calloc(sizeof(struct uwsgi_redislog_state));
|
||||
uredislog = (struct uwsgi_redislog_state *) ul->data;
|
||||
}
|
||||
|
||||
if (ul->arg != NULL) {
|
||||
char *logarg = uwsgi_str(ul->arg);
|
||||
char *comma1 = strchr(logarg, ',');
|
||||
if (!comma1) {
|
||||
uredislog.address = logarg;
|
||||
uredislog->address = logarg;
|
||||
goto done;
|
||||
}
|
||||
*comma1 = 0;
|
||||
uredislog.address = logarg;
|
||||
uredislog->address = logarg;
|
||||
comma1++;
|
||||
if (*comma1 == 0) goto done;
|
||||
|
||||
char *comma2 = strchr(comma1,',');
|
||||
if (!comma2) {
|
||||
uredislog.command = uwsgi_redis_logger_build_command(comma1);
|
||||
uredislog->command = uwsgi_redis_logger_build_command(comma1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
*comma2 = 0;
|
||||
uredislog.command = uwsgi_redis_logger_build_command(comma1);
|
||||
uredislog->command = uwsgi_redis_logger_build_command(comma1);
|
||||
comma2++;
|
||||
if (*comma2 == 0) goto done;
|
||||
|
||||
uredislog.prefix = comma2;
|
||||
uredislog->prefix = comma2;
|
||||
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (!uredislog.address) uredislog.address = uwsgi_str("127.0.0.1:6379");
|
||||
if (!uredislog.command) uredislog.command = "*3\r\n$7\r\npublish\r\n$5\r\nuwsgi\r\n";
|
||||
if (!uredislog.prefix) uredislog.prefix = "";
|
||||
if (!uredislog->address) uredislog->address = uwsgi_str("127.0.0.1:6379");
|
||||
if (!uredislog->command) uredislog->command = "*3\r\n$7\r\npublish\r\n$5\r\nuwsgi\r\n";
|
||||
if (!uredislog->prefix) uredislog->prefix = "";
|
||||
|
||||
uredislog.fd = -1;
|
||||
uredislog->fd = -1;
|
||||
|
||||
uredislog.iovec[0].iov_base = uredislog.command;
|
||||
uredislog.iovec[0].iov_len = strlen(uredislog.command);
|
||||
uredislog.iovec[1].iov_base = "$";
|
||||
uredislog.iovec[1].iov_len = 1;
|
||||
uredislog->iovec[0].iov_base = uredislog->command;
|
||||
uredislog->iovec[0].iov_len = strlen(uredislog->command);
|
||||
uredislog->iovec[1].iov_base = "$";
|
||||
uredislog->iovec[1].iov_len = 1;
|
||||
|
||||
uredislog.iovec[2].iov_base = uredislog.msgsize;
|
||||
uredislog->iovec[2].iov_base = uredislog->msgsize;
|
||||
|
||||
uredislog.iovec[3].iov_base = "\r\n";
|
||||
uredislog.iovec[3].iov_len = 2;
|
||||
uredislog->iovec[3].iov_base = "\r\n";
|
||||
uredislog->iovec[3].iov_len = 2;
|
||||
|
||||
uredislog.iovec[4].iov_base = uredislog.prefix;
|
||||
uredislog.iovec[4].iov_len = strlen(uredislog.prefix);
|
||||
uredislog->iovec[4].iov_base = uredislog->prefix;
|
||||
uredislog->iovec[4].iov_len = strlen(uredislog->prefix);
|
||||
|
||||
uredislog.iovec[6].iov_base = "\r\n";
|
||||
uredislog.iovec[6].iov_len = 2;
|
||||
uredislog->iovec[6].iov_base = "\r\n";
|
||||
uredislog->iovec[6].iov_len = 2;
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
if (uredislog.fd == -1) {
|
||||
uredislog.fd = uwsgi_connect(uredislog.address, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
uredislog = (struct uwsgi_redislog_state *) ul->data;
|
||||
if (uredislog->fd == -1) {
|
||||
uredislog->fd = uwsgi_connect(uredislog->address, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
}
|
||||
|
||||
if (uredislog.fd == -1) return -1;
|
||||
if (uredislog->fd == -1) return -1;
|
||||
|
||||
// drop newline
|
||||
if (message[len-1] == '\n') len--;
|
||||
|
||||
uwsgi_num2str2(len + uredislog.iovec[4].iov_len, uredislog.msgsize);
|
||||
uredislog.iovec[2].iov_len = strlen(uredislog.msgsize);
|
||||
uwsgi_num2str2(len + uredislog->iovec[4].iov_len, uredislog->msgsize);
|
||||
uredislog->iovec[2].iov_len = strlen(uredislog->msgsize);
|
||||
|
||||
uredislog.iovec[5].iov_base = message;
|
||||
uredislog.iovec[5].iov_len = len;
|
||||
uredislog->iovec[5].iov_base = message;
|
||||
uredislog->iovec[5].iov_len = len;
|
||||
|
||||
ret = writev(uredislog.fd, uredislog.iovec, 7);
|
||||
ret = writev(uredislog->fd, uredislog->iovec, 7);
|
||||
if (ret <= 0) {
|
||||
close(uredislog.fd);
|
||||
uredislog.fd = -1;
|
||||
close(uredislog->fd);
|
||||
uredislog->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
again:
|
||||
// read til a \n is found (ugly but fast)
|
||||
ret2 = read(uredislog.fd, uredislog.response, 8);
|
||||
ret2 = read(uredislog->fd, uredislog->response, 8);
|
||||
if (ret2 <= 0) {
|
||||
close(uredislog.fd);
|
||||
uredislog.fd = -1;
|
||||
close(uredislog->fd);
|
||||
uredislog->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!memchr(uredislog.response, '\n', ret2)) {
|
||||
if (!memchr(uredislog->response, '\n', ret2)) {
|
||||
goto again;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ PyObject *py_uwsgi_stackless_request(PyObject * self, PyObject *args) {
|
||||
|
||||
PyMethodDef uwsgi_stackless_request_method[] = {{"uwsgi_stackless_request", py_uwsgi_stackless_request, METH_VARARGS, ""}};
|
||||
|
||||
inline static void stackless_schedule_to_req() {
|
||||
static inline static void stackless_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
@@ -47,7 +47,7 @@ inline static void stackless_schedule_to_req() {
|
||||
|
||||
}
|
||||
|
||||
inline static void stackless_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
static inline static void stackless_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyStackless_Schedule(Py_None, 1);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
@@ -32,7 +32,7 @@ void u_green_request() {
|
||||
uwsgi.wsgi_req->suspended = 0;
|
||||
}
|
||||
|
||||
inline static void u_green_schedule_to_req() {
|
||||
static inline void u_green_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
@@ -58,7 +58,7 @@ inline static void u_green_schedule_to_req() {
|
||||
|
||||
}
|
||||
|
||||
inline static void u_green_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
static inline void u_green_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->suspend) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->suspend(wsgi_req);
|
||||
|
||||
@@ -15,13 +15,16 @@ extern "C" {
|
||||
#define uwsgi_log_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log(x);
|
||||
#define uwsgi_error_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_log_initial if (!uwsgi.no_initial_output) uwsgi_log
|
||||
#ifdef UWSGI_ALARM
|
||||
#define uwsgi_log_alarm(x, ...) uwsgi_log("[uwsgi-alarm" x, __VA_ARGS__)
|
||||
#endif
|
||||
#define uwsgi_fatal_error(x) uwsgi_error(x); exit(1);
|
||||
#define uwsgi_error_open(x) uwsgi_log("open(\"%s\"): %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_req_error(x) if (wsgi_req->uri_len > 0 && wsgi_req->method_len > 0 && wsgi_req->remote_addr_len > 0) uwsgi_log_verbose("%s: %s [%s line %d] during %.*s %.*s (%.*s)\n", x, strerror(errno), __FILE__, __LINE__,\
|
||||
wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr); else uwsgi_log_verbose("%s %s [%s line %d] \n",x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
|
||||
#define uwsgi_rawlog(x) if (write(2, x, strlen(x)) != strlen(x)) uwsgi_error("write()")
|
||||
#define uwsgi_str(x) uwsgi_concat2(x, "")
|
||||
#define uwsgi_str(x) uwsgi_concat2(x, (char *)"")
|
||||
|
||||
#define uwsgi_notify(x) if (uwsgi.notify) uwsgi.notify(x)
|
||||
#define uwsgi_notify_ready() uwsgi.shared->ready = 1 ; if (uwsgi.notify_ready) uwsgi.notify_ready()
|
||||
@@ -34,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))
|
||||
#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 ushared uwsgi.shared
|
||||
|
||||
@@ -73,10 +76,6 @@ extern char UWSGI_EMBED_CONFIG;
|
||||
extern char UWSGI_EMBED_CONFIG_END;
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#define inline
|
||||
#endif
|
||||
|
||||
#define UDEP(pname) extern struct uwsgi_plugin pname##_plugin;
|
||||
|
||||
#define ULEP(pname)\
|
||||
@@ -842,6 +841,46 @@ struct uwsgi_router {
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
struct uwsgi_alarm;
|
||||
struct uwsgi_alarm_instance {
|
||||
char *name;
|
||||
char *arg;
|
||||
void *data_ptr;
|
||||
uint8_t data8;
|
||||
uint16_t data16;
|
||||
uint32_t data32;
|
||||
uint64_t data64;
|
||||
|
||||
time_t last_run;
|
||||
|
||||
char *last_msg;
|
||||
size_t last_msg_size;
|
||||
|
||||
struct uwsgi_alarm *alarm;
|
||||
struct uwsgi_alarm_instance *next;
|
||||
};
|
||||
|
||||
struct uwsgi_alarm {
|
||||
char *name;
|
||||
void (*init)(struct uwsgi_alarm_instance *);
|
||||
void (*func)(struct uwsgi_alarm_instance *, char *, size_t);
|
||||
struct uwsgi_alarm *next;
|
||||
};
|
||||
|
||||
struct uwsgi_alarm_ll {
|
||||
struct uwsgi_alarm_instance *alarm;
|
||||
struct uwsgi_alarm_ll *next;
|
||||
};
|
||||
|
||||
struct uwsgi_alarm_log {
|
||||
pcre *pattern;
|
||||
pcre_extra *pattern_extra;
|
||||
struct uwsgi_alarm_ll *alarms;
|
||||
struct uwsgi_alarm_log *next;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct __attribute__ ((packed)) uwsgi_header {
|
||||
uint8_t modifier1;
|
||||
uint16_t pktsize;
|
||||
@@ -1286,6 +1325,9 @@ struct uwsgi_server {
|
||||
int loggers_list;
|
||||
int loop_list;
|
||||
int clock_list;
|
||||
#ifdef UWSGI_ALARM
|
||||
int alarms_list;
|
||||
#endif
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
|
||||
@@ -1403,6 +1445,15 @@ struct uwsgi_server {
|
||||
struct uwsgi_regexp_list *log_drain_rules;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
int alarm_freq;
|
||||
struct uwsgi_string_list *alarm_list;
|
||||
struct uwsgi_string_list *alarm_logs_list;
|
||||
struct uwsgi_alarm *alarms;
|
||||
struct uwsgi_alarm_instance *alarm_instances;
|
||||
struct uwsgi_alarm_log *alarm_logs;
|
||||
#endif
|
||||
|
||||
int threaded_logger;
|
||||
pthread_mutex_t threaded_logger_lock;
|
||||
|
||||
@@ -1497,6 +1548,7 @@ struct uwsgi_server {
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
int multicast_ttl;
|
||||
char *multicast_group;
|
||||
#endif
|
||||
|
||||
@@ -2179,7 +2231,7 @@ struct wsgi_request *find_wsgi_req_by_id(int);
|
||||
void async_add_fd_write(struct wsgi_request *, int, int);
|
||||
void async_add_fd_read(struct wsgi_request *, int, int);
|
||||
|
||||
inline struct wsgi_request *next_wsgi_req(struct wsgi_request *);
|
||||
struct wsgi_request *next_wsgi_req(struct wsgi_request *);
|
||||
|
||||
|
||||
void async_add_timeout(struct wsgi_request *, int);
|
||||
@@ -2240,8 +2292,8 @@ void uwsgi_opt_ldap_dump_ldif(char *, char *, void *);
|
||||
void uwsgi_ldap_config(char *);
|
||||
#endif
|
||||
|
||||
inline int uwsgi_strncmp(char *, int, char *, int);
|
||||
inline int uwsgi_startswith(char *, char *, int);
|
||||
int uwsgi_strncmp(char *, int, char *, int);
|
||||
int uwsgi_startswith(char *, char *, int);
|
||||
|
||||
|
||||
char *uwsgi_concat(int, ...);
|
||||
@@ -2321,9 +2373,8 @@ char *uwsgi_cache_get(char *, uint16_t, uint64_t *);
|
||||
uint32_t uwsgi_cache_exists(char *, uint16_t);
|
||||
|
||||
|
||||
inline void *uwsgi_malloc(size_t);
|
||||
inline void *uwsgi_calloc(size_t);
|
||||
|
||||
void *uwsgi_malloc(size_t);
|
||||
void *uwsgi_calloc(size_t);
|
||||
|
||||
|
||||
int event_queue_init(void);
|
||||
@@ -2538,14 +2589,8 @@ struct rb_root
|
||||
void rb_insert_color(struct rb_node *, struct rb_root *);
|
||||
void rb_erase(struct rb_node *, struct rb_root *);
|
||||
|
||||
#ifdef __clang__
|
||||
void rb_link_node(struct rb_node *, struct rb_node *,
|
||||
struct rb_node **);
|
||||
#else
|
||||
inline void rb_link_node(struct rb_node *, struct rb_node *,
|
||||
struct rb_node **);
|
||||
#endif
|
||||
|
||||
|
||||
struct uwsgi_rb_timer {
|
||||
|
||||
@@ -2584,8 +2629,8 @@ struct uwsgi_async_request {
|
||||
struct uwsgi_async_request *next;
|
||||
};
|
||||
|
||||
inline int event_queue_read(void);
|
||||
inline int event_queue_write(void);
|
||||
int event_queue_read(void);
|
||||
int event_queue_write(void);
|
||||
|
||||
void uwsgi_help(char *opt, char *val, void *);
|
||||
|
||||
@@ -2610,7 +2655,7 @@ int uwsgi_amqp_consume_queue(int, char *, char *, char *, char *, char *, char *
|
||||
char *uwsgi_amqp_consume(int, uint64_t *, char **);
|
||||
|
||||
int uwsgi_file_serve(struct wsgi_request *, char *, uint16_t, char *, uint16_t, int);
|
||||
inline int uwsgi_starts_with(char *, int, char *, int);
|
||||
int uwsgi_starts_with(char *, int, char *, int);
|
||||
|
||||
#ifdef __sun__
|
||||
time_t timegm(struct tm *);
|
||||
@@ -2841,7 +2886,7 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
|
||||
|
||||
ssize_t uwsgi_mule_get_msg(int, int, char *, size_t, int);
|
||||
|
||||
uint8_t uwsgi_signal_wait(int);
|
||||
int uwsgi_signal_wait(int);
|
||||
struct uwsgi_app *uwsgi_add_app(int, uint8_t, char *, int, void *, void *);
|
||||
int uwsgi_signal_send(int, uint8_t);
|
||||
int uwsgi_remote_signal_send(char *, uint8_t);
|
||||
@@ -2923,6 +2968,7 @@ void uwsgi_opt_add_socket(char *, char *, void *);
|
||||
void uwsgi_opt_add_lazy_socket(char *, char *, void *);
|
||||
void uwsgi_opt_add_cron(char *, char *, void *);
|
||||
void uwsgi_opt_load_plugin(char *, char *, void *);
|
||||
void uwsgi_opt_load_dl(char *, char *, void *);
|
||||
void uwsgi_opt_load(char *, char *, void *);
|
||||
void uwsgi_opt_cluster_log(char *, char *, void *);
|
||||
void uwsgi_opt_cluster_reload(char *, char *, void *);
|
||||
@@ -3147,6 +3193,7 @@ void uwsgi_logvar_add(struct wsgi_request *, char *, uint8_t, char *, uint8_t);
|
||||
struct uwsgi_emperor_scanner {
|
||||
char *arg;
|
||||
int fd;
|
||||
void *data;
|
||||
void (*event_func)(struct uwsgi_emperor_scanner *);
|
||||
struct uwsgi_imperial_monitor *monitor;
|
||||
struct uwsgi_emperor_scanner *next;
|
||||
@@ -3247,6 +3294,41 @@ ssize_t uwsgi_pipe_sized(int, int, size_t, int);
|
||||
int uwsgi_buffer_send(struct uwsgi_buffer *, int);
|
||||
void uwsgi_master_cleanup_hooks(void);
|
||||
|
||||
pid_t uwsgi_daemonize2();
|
||||
|
||||
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *, char *, char *, time_t, uid_t, gid_t);
|
||||
|
||||
#if defined(__linux__)
|
||||
#define UWSGI_ELF
|
||||
char *uwsgi_elf_section(char *, char *, size_t *);
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ALARM
|
||||
void uwsgi_alarm_log_check(char *, size_t);
|
||||
void uwsgi_alarm_run(struct uwsgi_alarm_instance *, char *, size_t);
|
||||
void uwsgi_alarm_log_run(struct uwsgi_alarm_log *, char *, size_t);
|
||||
void uwsgi_register_alarm(char *, void (*)(struct uwsgi_alarm_instance *), void (*)(struct uwsgi_alarm_instance *, char *, size_t));
|
||||
void uwsgi_register_embedded_alarms();
|
||||
void uwsgi_alarms_init();
|
||||
#endif
|
||||
|
||||
struct uwsgi_thread {
|
||||
pthread_t tid;
|
||||
int pipe[2];
|
||||
int queue;
|
||||
ssize_t rlen;
|
||||
void *data;
|
||||
char *buf;
|
||||
off_t pos;
|
||||
size_t len;
|
||||
uint64_t custom0;
|
||||
uint64_t custom1;
|
||||
uint64_t custom2;
|
||||
uint64_t custom3;
|
||||
void (*func)(struct uwsgi_thread *);
|
||||
};
|
||||
struct uwsgi_thread *uwsgi_thread_new(void (*)(struct uwsgi_thread *));
|
||||
|
||||
void uwsgi_check_emperor(void);
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
int uwsgi_init(int, char **, char **);
|
||||
|
||||
+39
-2
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '1.3-rc3'
|
||||
uwsgi_version = '1.3'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -42,6 +42,7 @@ report['filemonitor'] = False
|
||||
report['udp'] = False
|
||||
report['pcre'] = False
|
||||
report['routing'] = False
|
||||
report['alarm'] = False
|
||||
report['capabilities'] = False
|
||||
report['async'] = False
|
||||
report['minterpreters'] = False
|
||||
@@ -725,7 +726,7 @@ class uConf(object):
|
||||
report['pcre'] = True
|
||||
|
||||
if self.get('routing'):
|
||||
if self.get('pcre') == 'auto':
|
||||
if self.get('routing') == 'auto':
|
||||
if has_pcre:
|
||||
self.gcc_list.append('core/routing')
|
||||
self.cflags.append("-DUWSGI_ROUTING")
|
||||
@@ -735,6 +736,17 @@ class uConf(object):
|
||||
self.cflags.append("-DUWSGI_ROUTING")
|
||||
report['routing'] = True
|
||||
|
||||
if self.get('alarm'):
|
||||
if self.get('alarm') == 'auto':
|
||||
if has_pcre:
|
||||
self.gcc_list.append('core/alarm')
|
||||
self.cflags.append("-DUWSGI_ALARM")
|
||||
report['alarm'] = True
|
||||
else:
|
||||
self.gcc_list.append('core/alarm')
|
||||
self.cflags.append("-DUWSGI_ALARM")
|
||||
report['alarm'] = True
|
||||
|
||||
|
||||
if self.has_include('sys/capability.h') and uwsgi_os == 'Linux':
|
||||
self.cflags.append("-DUWSGI_CAP")
|
||||
@@ -1020,6 +1032,8 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
import uwsgiplugin as up
|
||||
reload(up)
|
||||
|
||||
requires = []
|
||||
|
||||
p_cflags = cflags[:]
|
||||
p_ldflags = ldflags[:]
|
||||
|
||||
@@ -1027,6 +1041,11 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
p_ldflags += up.LDFLAGS
|
||||
p_libs = up.LIBS
|
||||
|
||||
try:
|
||||
requires = up.REQUIRES
|
||||
except:
|
||||
pass
|
||||
|
||||
p_cflags.insert(0, '-I.')
|
||||
|
||||
if name is None:
|
||||
@@ -1090,6 +1109,11 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
p_cflags.remove('-pie')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
#for ofile in up.OBJ_LIST:
|
||||
# gcc_list.insert(0,ofile)
|
||||
@@ -1102,6 +1126,17 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
print("*** unable to build %s plugin ***" % name)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
if requires:
|
||||
f = open('.uwsgi_plugin_section', 'w')
|
||||
for rp in requires:
|
||||
f.write("requires=%s\n" % rp)
|
||||
f.close()
|
||||
os.system("objcopy %s.so --add-section uwsgi=.uwsgi_plugin_section %s.so" % (plugin_dest, plugin_dest))
|
||||
os.unlink('.uwsgi_plugin_section')
|
||||
except:
|
||||
pass
|
||||
|
||||
print("*** %s plugin built and available in %s ***" % (name, plugin_dest + '.so'))
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -1167,6 +1202,8 @@ if __name__ == "__main__":
|
||||
os.system("rm -f lib/*.o")
|
||||
os.system("rm -f plugins/*/*.o")
|
||||
os.system("rm -f build/*.o")
|
||||
elif cmd == '--check':
|
||||
os.system("cppcheck --max-configs=1000 --enable=all -q core/ plugins/ proto/ lib/ apache2/")
|
||||
|
||||
else:
|
||||
print("unknown uwsgiconfig command")
|
||||
|
||||
Reference in New Issue
Block a user