Compare commits

...
70 Commits
Author SHA1 Message Date
roberto@debian32 2d731532be various erlang fixes 2011-11-03 09:09:17 +01:00
roberto@debian32 d545cd5be0 added @erlang decorator 2011-11-02 20:48:11 +01:00
roberto@debian32 261d05d67e added @mulemsg decorator 2011-11-02 19:55:11 +01:00
roberto@debian32 639995785a fixed pyerl 2011-11-02 14:41:32 +01:00
roberto@debian32 817e076cae uwsgidecorators is installed when run under pip/easy_install 2011-11-02 14:20:51 +01:00
roberto@debian32 713370f343 completed regexp support in subscription system 2011-11-01 08:33:52 +01:00
roberto@debian32 5594503a56 pcre support in subscription system 2011-10-31 09:11:02 +01:00
roberto@debian32 d57e5d46fb fixed subscriptions removal in http plugin 2011-10-31 07:56:01 +01:00
roberto@debian32 ee2db5fabd a bunch of subscription optimizations 2011-10-30 13:10:26 +01:00
roberto@debian32 0c4cd6f378 ported http plugin to new subscription system 2011-10-30 11:36:53 +01:00
roberto@debian32 8c32b9665c re-implementation of subscription system 2011-10-30 11:30:53 +01:00
roberto@colossus 7405a01654 ready for next -rc ? 2011-10-28 17:53:16 +02:00
roberto@colossus 5d27691b4b fixed log rotation 2011-10-28 16:49:26 +02:00
roberto@debian32 19bbcfbf4c added @mule decorator 2011-10-28 16:22:39 +02:00
roberto@debian32 fa1064db87 added --umask 2011-10-28 16:10:26 +02:00
roberto@colossus 850ac69ca1 fixed master reloading 2011-10-28 11:35:18 +02:00
roberto@debian32 943edeb30c fixed a typo in subscribe-to and incresed slots to 64 2011-10-28 08:11:51 +02:00
roberto@debian32 01815a354b added a centos init script in contrib 2011-10-27 13:54:29 +02:00
roberto@debian32 2f4412aca1 allows .json as a valid vassal extension 2011-10-27 13:52:11 +02:00
roberto@oneiric64 2782bb7594 fixed 64bit support in rrdtool 2011-10-27 12:44:01 +02:00
roberto@debian32 074c1298d5 procname-prefix-spaced 2011-10-27 10:08:38 +02:00
roberto@debian32 55a7911611 added rrdtool plugin 2011-10-27 09:26:59 +02:00
roberto@debian32 013ad3044d added @mulefuc decorators 2011-10-26 10:51:03 +02:00
roberto@debian32 dcf4217b9d greatly improved uwsgi.mule_msg() 2011-10-26 10:13:20 +02:00
roberto@debian32 876dfc31a9 dynamic buffer_size and timeout for mule_get_msg 2011-10-26 06:43:07 +02:00
roberto@debian32 fd03bdbe00 improved mule and farm signal handling 2011-10-26 06:30:42 +02:00
roberto@debian32 83612649d5 mule_get_msg can manage signals 2011-10-26 06:11:07 +02:00
roberto@debian32 3c4db7e97e timerfd_create workaround 2011-10-26 05:45:06 +02:00
roberto@colossus 088c70efdc fixed locking 2011-10-25 18:05:52 +02:00
roberto@debian32 2b19029dd0 multiple mule_msg() 2011-10-25 17:46:41 +02:00
roberto@debian32 4fb5a84378 improved multi-mule support 2011-10-25 17:35:52 +02:00
roberto@debian32 b3107d9a25 another mule fix 2011-10-25 17:03:13 +02:00
roberto@debian32 bf32988f3e applied riccardo magliocchetti patch for .json support 2011-10-25 16:44:33 +02:00
roberto@debian32 1bf3dd7bf4 fixed mule patch message 2011-10-24 18:52:41 +02:00
roberto@debian32 07fd84f89f ported symimporter/symzipimporter to python3 2011-10-24 16:35:59 +02:00
roberto@debian32 3a8db4a97a fixed unlocking 2011-10-24 15:56:17 +02:00
roberto@debian32 aea30a26f5 added --mules <n> 2011-10-24 10:40:29 +02:00
roberto@gambit 8f5d1cdae7 Added tag 1.0-rc4 for changeset 24f7e260ea34 2011-10-24 10:05:02 +02:00
roberto@gambit 53913357e0 fixed strtok usage 2011-10-24 10:04:25 +02:00
roberto@debian32 098416f444 uWSGI 1.0-rc3 2011-10-24 09:42:41 +02:00
roberto@debian32 c98cb09c7c Added tag 1.0-rc3 for changeset 4e4e781ef89a 2011-10-24 09:42:27 +02:00
roberto@debian32 bb1ef28d69 updated decorators with @farm([name]) 2011-10-23 19:59:53 +02:00
roberto@debian32 1d5b05265d initial farm implementation 2011-10-23 19:18:31 +02:00
roberto@debian32 d9fef3c30e a little hack for psgi loader waiting for a truly agnostic init_uwsgi_app 2011-10-23 12:14:53 +02:00
roberto@debian32 e5dfb9efc3 improved get_memusage 2011-10-23 12:04:02 +02:00
roberto@debian32 02bab15e86 perl threading improvements 2011-10-23 11:49:25 +02:00
roberto@debian32 6f4ddead09 Added tag 1.0-rc2 for changeset 7a4e021ea7ba 2011-10-23 08:37:03 +02:00
roberto@gambit b361248ff6 fixed add_exported_opts 2011-10-23 08:35:15 +02:00
roberto@debian32 e9c42ceaa5 support for multiple values in options 2011-10-22 18:32:32 +02:00
roberto@debian32 5d7029744a PATH_INFO is correctly escaped in http modes 2011-10-22 09:35:01 +02:00
roberto@gambit 1084a3afa8 fixed mule patch loading 2011-10-20 10:38:59 +02:00
roberto@gambit ed254bffee fixed mule process name 2011-10-20 10:20:44 +02:00
roberto@djangocloud 733784d7dd another procname fix... 2011-10-19 16:13:10 +10:00
roberto@djangocloud cb5b26bcb4 another bunch of procname fixes 2011-10-19 14:26:07 +10:00
roberto@djangocloud 0065152bb1 daemons throttling subsystem 2011-10-18 18:53:22 +10:00
roberto@djangocloud 03266203fd another fix for environ 2011-10-18 18:30:13 +10:00
roberto@djangocloud 4a5f68f9d8 fixed environ 2011-10-18 18:12:39 +10:00
roberto@djangocloud 83e31a1c27 another setprocname fix 2011-10-18 16:20:33 +10:00
roberto@djangocloud 0efed5ef9c various emperor procname fixes 2011-10-18 16:15:06 +10:00
roberto@djangocloud cdfef1281d fixed another spooler compilation bug 2011-10-18 15:12:59 +10:00
roberto@debian32 e00907e142 --spooler-harakiri 2011-10-17 19:07:12 +02:00
roberto@app1 6dcbcf39e3 fixed compilation when spooler is disabled 2011-10-17 03:16:55 -05:00
roberto@debian32 044579a8e0 more verbose annihilation report 2011-10-16 11:16:13 +02:00
roberto@debian32 d2b52b4663 added uwsgi.setprocname() 2011-10-16 10:37:26 +02:00
roberto@debian32 7f75b2c02c added --procname and --procname-master 2011-10-16 10:18:45 +02:00
roberto@freebsd64 24a3f671e5 freebsd setproctitle 2011-10-16 10:06:08 +02:00
roberto@debian32 875100e3c8 check for mules before nuke 2011-10-16 09:58:37 +02:00
roberto@mrspurr 34bc7c0cfd check for procname 2011-10-16 09:54:35 +02:00
roberto@debian32 b39a10ff7c procname initial management 2011-10-16 09:45:41 +02:00
roberto@debian32 02331904de uWSGI 1.0-rc1 2011-10-15 08:47:00 +02:00
41 changed files with 2296 additions and 841 deletions
+4
View File
@@ -32,3 +32,7 @@ f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
6aa667612019fcff8e68af9469f73aff6fa378a8 0.9.9-rc2
376ffd8f190623e5e2521fe9fa64bf03c31e71be 0.9.9
7048ae11cfc8453c6bb599af3c0dfacd7ebae43c 1.0-rc1
7a4e021ea7ba2953e474326612c3bb82d6817f0e 1.0-rc2
4e4e781ef89ac33e71a7e92741d54549240ed156 1.0-rc3
24f7e260ea345c2cd73e2fd8191dddbd1b039062 1.0-rc4
+1
View File
@@ -1,4 +1,5 @@
import sys
import uwsgi
print("i am the bootstrap for uwsgi.SymbolsImporter")
sys.meta_path.insert(0, uwsgi.SymbolsImporter())
+1 -1
View File
@@ -27,7 +27,7 @@ plugins =
bin_name = uwsgi
append_version =
plugin_dir = .
embedded_plugins = python, ping, cache, nagios, rpc, fastrouter, http, ugreen
embedded_plugins = python, ping, cache, nagios, rrdtool, rpc, fastrouter, http, ugreen
as_shared_library = false
locking = auto
-299
View File
@@ -94,157 +94,6 @@ void uwsgi_init_cache() {
uwsgi_log("*** Cache subsystem initialized: %dMB preallocated ***\n", ((sizeof(uint64_t) * UMAX16) + (sizeof(uint64_t) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items)) / (1024 * 1024));
}
struct uwsgi_subscriber_name *uwsgi_get_subscriber(struct uwsgi_dict *udict, char *key, uint16_t keylen) {
uint64_t ovl;
struct uwsgi_subscriber *usub;
struct uwsgi_subscriber_name *ret = NULL;
usub = (struct uwsgi_subscriber *) uwsgi_dict_get(udict, key, keylen, &ovl);
if (usub == NULL || !ovl) return NULL;
if (!usub->nodes) return NULL;
if (usub && ovl) {
ret = &usub->names[usub->current];
// dead node
if (ret->len == 0) {
if (usub->current == usub->nodes-1) {
usub->nodes--;
}
// retry with another node (if available)
if (usub->nodes > 0) {
usub->current++;
if (usub->current >= usub->nodes) usub->current = 0;
return uwsgi_get_subscriber(udict, key, keylen);
}
}
if (usub->nodes > 1) {
usub->current++;
if (usub->current >= usub->nodes) usub->current = 0;
}
}
return ret;
}
void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *usr) {
char *ptr;
uint64_t vallen = 0;
struct uwsgi_subscriber *usub, nusub;
int found = 0;
int i;
ptr = uwsgi_dict_get(udict, usr->key, usr->keylen, &vallen);
if (ptr && vallen) {
usub = (struct uwsgi_subscriber *) ptr;
for(i=0;i<(int)usub->nodes;i++) {
if (!uwsgi_strncmp(usub->names[i].name, usub->names[i].len, usr->address, usr->address_len)) {
found = 1;
break;
}
}
if (!found) {
found = usub->nodes;
// check for unallocated slot
for(i=0;i<(int)usub->nodes;i++) {
if (usub->names[i].len == 0) {
found = i;
break;
}
}
usub->names[found].len = usr->address_len;
usub->names[found].modifier1 = usr->modifier1;
usub->names[found].modifier2 = usr->modifier2;
memcpy(usub->names[found].name, usr->address, usr->address_len);
if (found == (int) usub->nodes) {
usub->nodes++;
}
uwsgi_log("[uwsgi-subscription] %.*s => new node: %.*s\n", usr->keylen, usr->key, usr->address_len, usr->address);
udict->count++;
}
return;
}
else {
nusub.nodes = 1;
nusub.current = 0;
memcpy(nusub.names[0].name, usr->address, usr->address_len);
nusub.names[0].len = usr->address_len;
nusub.names[0].modifier1 = usr->modifier1;
nusub.names[0].modifier2 = usr->modifier2;
uwsgi_dict_set(udict, usr->key, usr->keylen, (char *) &nusub, sizeof(struct uwsgi_subscriber));
uwsgi_log("[uwsgi-subscription] new pool: %.*s\n", usr->keylen, usr->key);
uwsgi_log("[uwsgi-subscription] %.*s => new node: %.*s\n", usr->keylen, usr->key, usr->address_len, usr->address);
udict->count++;
}
}
struct uwsgi_dict *uwsgi_dict_create(uint64_t items, uint64_t blocksize) {
int i;
struct uwsgi_dict *udict = (struct uwsgi_dict *) mmap(NULL, sizeof(uint64_t) * UMAX16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!udict) {
uwsgi_error("mmap()");
exit(1);
}
if (!blocksize) blocksize = 4096;
if (blocksize % uwsgi.page_size != 0) {
uwsgi_log("invalid shared dictionary blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) udict->blocksize, uwsgi.page_size);
exit(1);
}
udict->blocksize = blocksize;
udict->max_items = items;
udict->hashtable = (uint64_t *) mmap(NULL, sizeof(uint64_t) * UMAX16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!udict->hashtable) {
uwsgi_error("mmap()");
exit(1);
}
memset(udict->hashtable, 0, sizeof(uint64_t) * UMAX16);
udict->unused_stack = (uint64_t *) mmap(NULL, sizeof(uint64_t) * udict->max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!udict->unused_stack) {
uwsgi_error("mmap()");
exit(1);
}
memset(udict->unused_stack, 0, sizeof(uint64_t) * udict->max_items);
udict->items = (struct uwsgi_dict_item *) mmap(NULL, sizeof(struct uwsgi_dict_item) * udict->max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!udict->items) {
uwsgi_error("mmap()");
exit(1);
}
udict->data = mmap(NULL, udict->blocksize * udict->max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!udict->data) {
uwsgi_error("mmap()");
exit(1);
}
for(i=0;i< (int) udict->max_items;i++) {
memset(&udict->items[i], 0, sizeof(struct uwsgi_dict_item));
}
udict->first_available_item = 1;
udict->unused_stack_ptr = 0;
udict->lock = uwsgi_mmap_shared_lock();
uwsgi_lock_init(udict->lock);
return udict;
}
uint32_t djb33x_hash(char *key, int keylen) {
register uint32_t hash = 5381;
@@ -258,89 +107,6 @@ uint32_t djb33x_hash(char *key, int keylen) {
}
inline uint64_t uwsgi_dict_get_index(struct uwsgi_dict *udict, char *key, uint16_t keylen) {
uint32_t hash = djb33x_hash(key, keylen);
int hash_key = hash % 0xffff;
uint64_t slot = udict->hashtable[hash_key];
struct uwsgi_dict_item *udi;
udi = &udict->items[slot];
// first round
if (udi->djbhash != hash) goto cycle;
if (udi->keysize != keylen) goto cycle;
if (memcmp(udi->key, key, keylen)) goto cycle;
return slot;
cycle:
while(udi->next) {
slot = udi->next;
udi = &udict->items[slot];
if (udi->djbhash != hash) continue;
if (udi->keysize != keylen) continue;
if (!memcmp(udi->key, key, keylen)) return slot;
}
return 0;
}
char *uwsgi_dict_get(struct uwsgi_dict *udict, char *key, uint16_t keylen, uint64_t *valsize) {
uint64_t index = uwsgi_dict_get_index(udict, key, keylen);
if (index) {
*valsize = udict->items[index].valsize;
udict->items[index].hits++;
return udict->data+(index*udict->blocksize);
}
return NULL;
}
int uwsgi_dict_del(struct uwsgi_dict *udict, char *key, uint16_t keylen) {
uint64_t index = 0;
struct uwsgi_dict_item *udi;
int ret = -1;
index = uwsgi_dict_get_index(udict, key, keylen);
if (index) {
udi = &udict->items[index] ;
udi->keysize = 0;
udi->valsize = 0;
udict->unused_stack_ptr++;
udict->unused_stack[udict->unused_stack_ptr] = index;
// try to return to initial condition...
if (index == udict->first_available_item-1) {
udict->first_available_item--;
}
ret = 0;
// relink collisioned entry
if (udi->prev) {
udict->items[udi->prev].next = udi->next;
}
if (udi->next) {
udict->items[udi->next].prev = udi->prev;
}
if (!udi->prev && !udi->next) {
// reset hashtable entry
udict->hashtable[udi->djbhash % 0xffff] = 0;
}
udi->djbhash = 0;
udi->prev = 0;
udi->next = 0;
}
return ret;
}
inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
uint32_t hash = djb33x_hash(key, keylen);
@@ -534,71 +300,6 @@ end:
}
int uwsgi_dict_set(struct uwsgi_dict *udict, char *key, uint16_t keylen, char *val, uint64_t vallen) {
uint64_t index = 0, last_index = 0 ;
struct uwsgi_dict_item *udi, *udii;
int ret = -1;
int slot;
if (!keylen || !vallen) return -1;
if (keylen > UWSGI_CACHE_MAX_KEY_SIZE) return -1;
if (udict->first_available_item >= udict->max_items && !udict->unused_stack_ptr) {
uwsgi_log("*** DANGER dictionary %p is FULL !!! ***\n", udict);
goto end;
}
index = uwsgi_dict_get_index(udict, key, keylen);
if (!index) {
if (udict->unused_stack_ptr) {
index = udict->unused_stack[udict->unused_stack_ptr];
udict->unused_stack_ptr--;
}
else {
index = udict->first_available_item;
if (udict->first_available_item < udict->max_items) {
udict->first_available_item++;
}
}
udi = &udict->items[index] ;
udi->djbhash = djb33x_hash(key, keylen);
udi->hits = 0;
memcpy(udi->key, key, keylen);
memcpy(udict->data+(index*udict->blocksize), val, vallen);
// set this as late as possibile (to reduce races risk)
udi->valsize = vallen;
udi->keysize = keylen;
ret = 0;
// now put the value in the 16bit hashtable
slot = udi->djbhash % 0xffff;
if (udict->hashtable[slot] == 0) {
udict->hashtable[slot] = index;
}
else {
// append to first available next
last_index = udict->hashtable[slot];
udii = &udict->items[ last_index ];
while(udii->next) {
last_index = udii->next;
udii = &udict->items[ last_index ];
}
udii->next = index;
udi->prev = last_index;
}
}
end:
return ret;
}
/* THIS PART IS HEAVILY OPTIMIZED: PERFORMANCE NOT ELEGANCE !!! */
void *cache_thread_loop(void *fd_ptr) {
+99
View File
@@ -0,0 +1,99 @@
#!/bin/bash
# uwsgi - Use uwsgi to run python and wsgi web apps.
#
# chkconfig: - 85 15
# description: Use uwsgi to run python and wsgi web apps.
# processname: uwsgi
# author: Roman Vasilyev
# Source function library.
. /etc/rc.d/init.d/functions
PATH=/opt/uwsgi:/sbin:/bin:/usr/sbin:/usr/bin
prog=/usr/sbin/uwsgi
OWNER=nginx
NAME=uwsgi
DESC=uwsgi
#DAEMON_OPTS="-s 127.0.0.1:9001 -M 4 -t 30 -A 4 -p 4 -d /var/log/uwsgi.log --pidfile /var/run/$NAME.pid --pythonpath $PYTHONPATH --module $MODULE"
DAEMON_OPTS="-s 127.0.0.1:9001 -M 4 -t 30 -A 4 -p 16 -b 32768 -d /var/log/$NAME.log --pidfile /var/run/$NAME.pid --uid $OWNER"
[ -f /etc/sysconfig/uwsgi ] && . /etc/sysconfig/uwsgi
lockfile=/var/lock/subsys/uwsgi
start () {
echo -n "Starting $DESC: "
daemon $prog $DAEMON_OPTS
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop () {
echo -n "Stopping $DESC: "
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
reload () {
echo "Reloading $NAME"
killproc $prog -HUP
RETVAL=$?
echo
}
force-reload () {
echo "Reloading $NAME"
killproc $prog -TERM
RETVAL=$?
echo
}
restart () {
stop
start
}
rh_status () {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|force-reload)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
status)
rh_status
;;
*)
echo "Usage: $0 {start|stop|restart|reload|force-reload|status}" >&2
exit 2
;;
esac
exit 0
+18 -14
View File
@@ -179,7 +179,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
struct uwsgi_instance *c_ui = ui;
struct uwsgi_instance *n_ui = NULL;
pid_t pid;
char **argv;
char **vassal_argv;
char *uef;
char **uenvs;
int counter;
@@ -340,9 +340,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
uct = uct->next;
}
argv = uwsgi_malloc(sizeof(char *) * counter);
vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
// set args
argv[0] = uwsgi.binary_path;
vassal_argv[0] = uwsgi.binary_path;
if (uwsgi.emperor_broodlord) {
colon = strchr(name, ':');
@@ -351,29 +351,31 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
}
}
if (!strcmp(name + (strlen(name) - 4), ".xml"))
argv[1] = "--xml";
vassal_argv[1] = "--xml";
if (!strcmp(name + (strlen(name) - 4), ".ini"))
argv[1] = "--ini";
vassal_argv[1] = "--ini";
if (!strcmp(name + (strlen(name) - 4), ".yml"))
argv[1] = "--yaml";
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 5), ".yaml"))
argv[1] = "--yaml";
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 3), ".js"))
argv[1] = "--json";
vassal_argv[1] = "--json";
if (!strcmp(name + (strlen(name) - 5), ".json"))
vassal_argv[1] = "--json";
if (colon) {
colon[0] = ':';
}
argv[2] = name;
vassal_argv[2] = name;
counter = 3;
uct = uwsgi.vassals_templates;
while(uct) {
argv[counter] = "--inherit";
argv[counter+1] = uct->filename;
vassal_argv[counter] = "--inherit";
vassal_argv[counter+1] = uct->filename;
counter+=2;
uct = uct->next;
}
argv[counter] = NULL;
vassal_argv[counter] = NULL;
// close all of the unneded fd
for(i=3;i<sysconf(_SC_OPEN_MAX);i++) {
@@ -392,7 +394,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
}
// start !!!
if (execvp(argv[0], argv)) {
if (execvp(vassal_argv[0], vassal_argv)) {
uwsgi_error("execvp()");
}
uwsgi_log("is the uwsgi binary in your system PATH ?\n");
@@ -660,7 +662,8 @@ reconnect:
!strcmp(de->d_name + (strlen(de->d_name) - 4), ".ini") ||
!strcmp(de->d_name + (strlen(de->d_name) - 4), ".yml") ||
!strcmp(de->d_name + (strlen(de->d_name) - 5), ".yaml") ||
!strcmp(de->d_name + (strlen(de->d_name) - 3), ".js")
!strcmp(de->d_name + (strlen(de->d_name) - 3), ".js") ||
!strcmp(de->d_name + (strlen(de->d_name) - 5), ".json")
) {
@@ -707,6 +710,7 @@ reconnect:
!strcmp(g.gl_pathv[i] + (strlen(g.gl_pathv[i]) - 4), ".ini") ||
!strcmp(g.gl_pathv[i] + (strlen(g.gl_pathv[i]) - 4), ".yml") ||
!strcmp(g.gl_pathv[i] + (strlen(g.gl_pathv[i]) - 3), ".js") ||
!strcmp(g.gl_pathv[i] + (strlen(g.gl_pathv[i]) - 5), ".json") ||
!strcmp(g.gl_pathv[i] + (strlen(g.gl_pathv[i]) - 5), ".yaml")
) {
+2
View File
@@ -693,6 +693,8 @@ static int timerfd_create (clockid_t __clock_id, int __flags) {
return syscall(283, __clock_id, __flags);
#elif defined(__i386__)
return syscall(322, __clock_id, __flags);
#else
return -1;
#endif
}
+5 -5
View File
@@ -47,7 +47,7 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
}
}
gw_pid = fork();
gw_pid = uwsgi_fork(name);
if (gw_pid < 0) {
uwsgi_error("fork()");
return NULL;
@@ -90,7 +90,7 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
ug->loop = loop;
ug->num = num;
uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) ug->pid);
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) ug->pid);
uwsgi.gateways_cnt++;
@@ -103,7 +103,7 @@ void gateway_respawn(int id) {
pid_t gw_pid;
struct uwsgi_gateway *ug = &uwsgi.gateways[id];
gw_pid = fork();
gw_pid = uwsgi_fork(ug->name);
if (gw_pid < 0) {
uwsgi_error("fork()");
return;
@@ -124,10 +124,10 @@ void gateway_respawn(int id) {
ug->pid = gw_pid;
ug->respawns++;
if (ug->respawns == 1) {
uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
else {
uwsgi_log( "respawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
uwsgi_log( "respawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
}
+4 -4
View File
@@ -77,10 +77,10 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
add_exported_option((char *)key, (char *) json_string_value(config_value), 0);
}
else if (json_is_true(config_value)) {
add_exported_option((char *)key, (char *) "1", 0);
add_exported_option((char *)key, strdup("1"), 0);
}
else if (json_is_false(config_value) || json_is_null(config_value)) {
add_exported_option((char *)key, (char *) "0", 0);
add_exported_option((char *)key, strdup("0"), 0);
}
else if (json_is_integer(config_value)) {
add_exported_option((char *)key, uwsgi_num2str(json_integer_value(config_value)), 0);
@@ -92,10 +92,10 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
add_exported_option((char *)key, (char *) json_string_value(config_array_item), 0);
}
else if (json_is_true(config_array_item)) {
add_exported_option((char *)key, (char *) "1", 0);
add_exported_option((char *)key, strdup("1"), 0);
}
else if (json_is_false(config_array_item) || json_is_null(config_array_item)) {
add_exported_option((char *)key, (char *) "0", 0);
add_exported_option((char *)key, strdup("0"), 0);
}
else if (json_is_integer(config_array_item)) {
add_exported_option((char *)key, uwsgi_num2str(json_integer_value(config_array_item)), 0);
+18 -17
View File
@@ -129,22 +129,22 @@ void log_request(struct wsgi_request *wsgi_req) {
rlen = writev(2, logvec, logvecpos+1);
}
void get_memusage() {
void get_memusage(uint64_t *rss, uint64_t *vsz) {
#ifdef UNBIT
uwsgi.workers[uwsgi.mywid].vsz_size = syscall(356);
*vsz = syscall(356);
#elif defined(__linux__)
FILE *procfile;
int i;
procfile = fopen("/proc/self/stat", "r");
if (procfile) {
i = fscanf(procfile, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %llu %lld", (unsigned long long *) &uwsgi.workers[uwsgi.mywid].vsz_size, (unsigned long long *) &uwsgi.workers[uwsgi.mywid].rss_size);
i = fscanf(procfile, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %llu %lld", (unsigned long long *) vsz, (unsigned long long *) rss);
if (i != 2) {
uwsgi_log( "warning: invalid record in /proc/self/stat\n");
}
fclose(procfile);
}
uwsgi.workers[uwsgi.mywid].rss_size = uwsgi.workers[uwsgi.mywid].rss_size * uwsgi.page_size;
*rss = *rss * uwsgi.page_size;
#elif defined (__sun__)
psinfo_t info;
int procfd;
@@ -152,8 +152,8 @@ void get_memusage() {
procfd = open("/proc/self/psinfo", O_RDONLY);
if (procfd >= 0) {
if ( read(procfd, (char *) &info, sizeof(info)) > 0) {
uwsgi.workers[uwsgi.mywid].rss_size = (uint64_t) info.pr_rssize * 1024;
uwsgi.workers[uwsgi.mywid].vsz_size = (uint64_t) info.pr_size * 1024;
*rss = (uint64_t) info.pr_rssize * 1024;
*vsz = (uint64_t) info.pr_size * 1024;
}
close(procfd);
}
@@ -164,8 +164,8 @@ void get_memusage() {
mach_msg_type_number_t t_size = sizeof(struct task_basic_info);
if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t) & t_info, &t_size) == KERN_SUCCESS) {
uwsgi.workers[uwsgi.mywid].rss_size = t_info.resident_size;
uwsgi.workers[uwsgi.mywid].vsz_size = t_info.virtual_size;
*rss = t_info.resident_size;
*vsz = t_info.virtual_size;
}
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
kvm_t *kv;
@@ -184,8 +184,8 @@ void get_memusage() {
struct kinfo_proc *kproc;
kproc = kvm_getprocs(kv, KERN_PROC_PID, uwsgi.mypid, &cnt);
if (kproc && cnt > 0) {
uwsgi.workers[uwsgi.mywid].vsz_size = kproc->ki_size;
uwsgi.workers[uwsgi.mywid].rss_size = kproc->ki_rssize * uwsgi.page_size;
*vsz = kproc->ki_size;
*rss = kproc->ki_rssize * uwsgi.page_size;
}
#elif defined(__NetBSD__) || defined(__OpenBSD__)
struct kinfo_proc2 *kproc2;
@@ -193,11 +193,11 @@ void get_memusage() {
kproc2 = kvm_getproc2(kv, KERN_PROC_PID, uwsgi.mypid, sizeof(struct kinfo_proc2), &cnt);
if (kproc2 && cnt > 0) {
#ifdef __OpenBSD__
uwsgi.workers[uwsgi.mywid].vsz_size = (kproc2->p_vm_dsize + kproc2->p_vm_ssize + kproc2->p_vm_tsize) * uwsgi.page_size;
*vsz = (kproc2->p_vm_dsize + kproc2->p_vm_ssize + kproc2->p_vm_tsize) * uwsgi.page_size;
#else
uwsgi.workers[uwsgi.mywid].vsz_size = kproc2->p_vm_msize * uwsgi.page_size;
*vsz = kproc2->p_vm_msize * uwsgi.page_size;
#endif
uwsgi.workers[uwsgi.mywid].rss_size = kproc2->p_vm_rssize * uwsgi.page_size;
*rss = kproc2->p_vm_rssize * uwsgi.page_size;
}
#endif
@@ -207,13 +207,14 @@ void get_memusage() {
area_info ai;
int32 cookie;
uwsgi.workers[uwsgi.mywid].vsz_size = 0;
uwsgi.workers[uwsgi.mywid].rss_size = 0;
*vsz = 0;
*rss = 0;
while(get_next_area_info(0, &cookie, &ai) == B_OK) {
uwsgi.workers[uwsgi.mywid].vsz_size += ai.ram_size;
*vsz += ai.ram_size;
if ( (ai.protection & B_WRITE_AREA) != 0) {
uwsgi.workers[uwsgi.mywid].rss_size += ai.ram_size;
*rss += ai.ram_size;
}
}
#endif
}
+85 -10
View File
@@ -294,6 +294,18 @@ int master_loop(char **argv, char **environ) {
struct uwsgi_rb_timer *min_timeout;
struct rb_root *rb_timers = uwsgi_init_rb_timer();
if (uwsgi.procname_master) {
uwsgi_set_processname(uwsgi.procname_master);
}
else if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else if (uwsgi.auto_procname) {
uwsgi_set_processname("uWSGI master");
}
uwsgi.current_time = time(NULL);
uwsgi_unix_signal(SIGHUP, grace_them_all);
@@ -495,9 +507,10 @@ int master_loop(char **argv, char **environ) {
}
// first subscription
for(i=0;i<uwsgi.subscriptions_cnt;i++) {
uwsgi_log("requested subscription for %s\n", uwsgi.subscriptions[i]);
uwsgi_subscribe(uwsgi.subscriptions[i]);
struct uwsgi_string_list *subscriptions = uwsgi.subscriptions;
while(subscriptions) {
uwsgi_subscribe(subscriptions->value);
subscriptions = subscriptions->next;
}
// sync the cache store if needed
@@ -530,6 +543,17 @@ int master_loop(char **argv, char **environ) {
for (;;) {
//uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc);
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->master_cycle) {
uwsgi.gp[i]->master_cycle();
}
}
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->master_cycle) {
uwsgi.p[i]->master_cycle();
}
}
if (uwsgi.to_outworld) {
//uwsgi_log("%d/%d\n", uwsgi.lazy_respawned, uwsgi.numproc);
if (uwsgi.lazy_respawned >= uwsgi.numproc) {
@@ -661,8 +685,8 @@ healthy:
if ((uwsgi.cheap || ready_to_die >= uwsgi.numproc) && uwsgi.to_hell) {
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt+uwsgi.mules_cnt);i++) {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
}
@@ -670,8 +694,8 @@ healthy:
exit(0);
}
if ( (uwsgi.cheap || ready_to_reload >= uwsgi.numproc) && uwsgi.to_heaven) {
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt+uwsgi.mules_cnt);i++) {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
}
@@ -690,6 +714,7 @@ healthy:
uwsgi_log( "closing all non-uwsgi socket fds > 2 (_SC_OPEN_MAX = %ld)...\n", sysconf(_SC_OPEN_MAX));
for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
int found = 0;
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
if (i == uwsgi_sock->fd) {
@@ -707,6 +732,13 @@ healthy:
}
}
}
if (uwsgi.original_log_fd > -1) {
if (i == uwsgi.original_log_fd) {
dup2(uwsgi.original_log_fd, 1);
dup2(1, 2);
}
}
if (!found) {
#ifdef __APPLE__
fcntl(i, F_SETFD, FD_CLOEXEC);
@@ -1364,6 +1396,15 @@ healthy:
}
}
}
#ifdef UWSGI_SPOOLER
if (uwsgi.shared->spooler_pid > 0 && uwsgi.shared->spooler_harakiri > 0) {
if (uwsgi.shared->spooler_harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uwsgi.shared->spooler_pid);
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi.shared->spooler_harakiri = 0;
}
}
#endif
#ifdef UWSGI_UDP
// check for cluster nodes
@@ -1375,9 +1416,11 @@ healthy:
}
// resubscribe every 10 cycles
if (uwsgi.subscriptions_cnt > 0 && ((uwsgi.master_cycles % 10) == 0 || uwsgi.master_cycles == 1)) {
for(i=0;i<uwsgi.subscriptions_cnt;i++) {
uwsgi_subscribe(uwsgi.subscriptions[i]);
if (uwsgi.subscriptions && ((uwsgi.master_cycles % 10) == 0 || uwsgi.master_cycles == 1)) {
struct uwsgi_string_list *subscriptions = uwsgi.subscriptions;
while(subscriptions) {
uwsgi_subscribe(subscriptions->value);
subscriptions = subscriptions->next;
}
}
@@ -1488,6 +1531,37 @@ healthy:
uwsgi.mywid = find_worker_id(diedpid);
if (uwsgi.mywid <= 0) {
// check spooler, mules, gateways and daemons
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
if (diedpid == uwsgi.shared->spooler_pid) {
uwsgi_log("spooler (pid: %d) annihilated\n", (int) diedpid);
goto next;
}
}
#endif
for(i=0;i<uwsgi.mules_cnt;i++) {
if (uwsgi.mules[i].pid == diedpid) {
uwsgi_log("mule %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
for(i=0;i<uwsgi.gateways_cnt;i++) {
if (uwsgi.gateways[i].pid == diedpid) {
uwsgi_log("gateway %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
for(i=0;i<uwsgi.shared->daemons_cnt;i++) {
if (uwsgi.shared->daemons[i].pid == diedpid) {
uwsgi_log("daemon %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
if (WIFEXITED(waitpid_status)) {
uwsgi_log("subprocess %d exited with code %d\n", (int) diedpid, WEXITSTATUS(waitpid_status));
}
@@ -1497,6 +1571,7 @@ healthy:
else if (WIFSTOPPED(waitpid_status)) {
uwsgi_log("subprocess %d stopped\n", (int) diedpid);
}
next:
continue;
}
else {
+15 -3
View File
@@ -59,8 +59,10 @@ void uwsgi_fixup_fds(int wid, int muleid) {
#endif
if (uwsgi.shared->mule_signal_pipe[0] != -1) close(uwsgi.shared->mule_signal_pipe[0]);
if (muleid == 0) {
if (uwsgi.shared->mule_signal_pipe[1] != -1) close(uwsgi.shared->mule_signal_pipe[1]);
if (uwsgi.shared->mule_queue_pipe[1] != -1) close(uwsgi.shared->mule_queue_pipe[1]);
}
for(i=0;i<uwsgi.mules_cnt;i++) {
@@ -71,6 +73,15 @@ void uwsgi_fixup_fds(int wid, int muleid) {
}
}
for(i=0;i<uwsgi.farms_cnt;i++) {
if (uwsgi.farms[i].signal_pipe[0] != -1) close(uwsgi.farms[i].signal_pipe[0]);
if (muleid == 0) {
if (uwsgi.farms[i].signal_pipe[1] != -1) close(uwsgi.farms[i].signal_pipe[1]);
if (uwsgi.farms[i].queue_pipe[1] != -1) close(uwsgi.farms[i].queue_pipe[1]);
}
}
}
@@ -81,7 +92,7 @@ int uwsgi_respawn_worker(int wid) {
int respawns = uwsgi.workers[wid].respawn_count;
int i;
pid_t pid = fork();
pid_t pid = uwsgi_fork(uwsgi.workers[wid].name);
if (pid == 0) {
signal(SIGWINCH, worker_wakeup);
@@ -90,8 +101,9 @@ int uwsgi_respawn_worker(int wid) {
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
uwsgi.workers[uwsgi.mywid].harakiri = 0;
uwsgi.workers[uwsgi.mywid].requests = 0;
uwsgi.workers[uwsgi.mywid].failed_requests = 0;
// do not reset worker counters on reload !!!
//uwsgi.workers[uwsgi.mywid].requests = 0;
//uwsgi.workers[uwsgi.mywid].failed_requests = 0;
uwsgi.workers[uwsgi.mywid].respawn_count++;
uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
+130 -10
View File
@@ -16,7 +16,7 @@ void uwsgi_mule(int id) {
int i;
pid_t pid = fork();
pid_t pid = uwsgi_fork(uwsgi.mules[id-1].name);
if (pid == 0) {
uwsgi.muleid = id;
// avoid race conditions
@@ -44,10 +44,10 @@ void uwsgi_mule(int id) {
if (uwsgi.mules[id-1].patch) {
uwsgi_log("loading patch %s\n", uwsgi.mules[id-1].patch);
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->mule) {
if (uwsgi.p[i]->mule(uwsgi.mules[id-1].patch) == 1) {
// never here
break;
}
}
@@ -63,6 +63,64 @@ void uwsgi_mule(int id) {
}
}
int uwsgi_farm_has_mule(struct uwsgi_farm *farm, int muleid) {
struct uwsgi_mule_farm *umf = farm->mules;
while(umf) {
if (umf->mule->id == muleid) {
return 1;
}
umf = umf->next;
}
return 0;
}
int farm_has_signaled(int fd) {
int i;
for(i=0;i<uwsgi.farms_cnt;i++) {
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
while(umf) {
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].signal_pipe[1] == fd) {
return 1;
}
umf = umf->next;
}
}
return 0;
}
int farm_has_msg(int fd) {
int i;
for(i=0;i<uwsgi.farms_cnt;i++) {
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
while(umf) {
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].queue_pipe[1] == fd) {
return 1;
}
umf = umf->next;
}
}
return 0;
}
void uwsgi_mule_add_farm_to_queue(int queue) {
int i;
for(i=0;i<uwsgi.farms_cnt;i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
event_queue_add_fd_read(queue, uwsgi.farms[i].signal_pipe[1]);
event_queue_add_fd_read(queue, uwsgi.farms[i].queue_pipe[1]);
}
}
}
void uwsgi_mule_handler() {
ssize_t len;
@@ -78,6 +136,9 @@ void uwsgi_mule_handler() {
event_queue_add_fd_read(mule_queue, uwsgi.signal_socket);
event_queue_add_fd_read(mule_queue, uwsgi.my_signal_socket);
event_queue_add_fd_read(mule_queue, uwsgi.mules[uwsgi.muleid-1].queue_pipe[1]);
event_queue_add_fd_read(mule_queue, uwsgi.shared->mule_queue_pipe[1]);
uwsgi_mule_add_farm_to_queue(mule_queue);
for(;;) {
rlen = event_queue_wait(mule_queue, -1, &interesting_fd);
@@ -85,7 +146,7 @@ void uwsgi_mule_handler() {
continue;
}
if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket) {
if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket || farm_has_signaled(interesting_fd)) {
len = read(interesting_fd, &uwsgi_signal, 1);
if (len <= 0) {
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
@@ -95,21 +156,80 @@ void uwsgi_mule_handler() {
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.mywid);
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
}
}
else if (interesting_fd == uwsgi.mules[uwsgi.muleid-1].queue_pipe[1]) {
len = read(uwsgi.mules[uwsgi.muleid-1].queue_pipe[1], message, 65536);
else if (interesting_fd == uwsgi.mules[uwsgi.muleid-1].queue_pipe[1] || interesting_fd == uwsgi.shared->mule_queue_pipe[1] || farm_has_msg(interesting_fd)) {
len = read(interesting_fd, message, 65536);
if (len < 0) {
uwsgi_error("read()");
}
else if (len == 0) {
exit(1);
}
else {
uwsgi_log("*** mule %d received a %d bytes message\n", uwsgi.muleid, len);
int i,found = 0;
for(i=0;i<0xff;i++) {
if (uwsgi.p[i]->mule_msg) {
if (uwsgi.p[i]->mule_msg(message, len)) {
found = 1;
break;
}
}
}
if (!found)
uwsgi_log("*** mule %d received a %d bytes message ***\n", uwsgi.muleid, len);
}
}
}
}
struct uwsgi_mule *get_mule_by_id(int id) {
int i;
for(i=0;i<uwsgi.mules_cnt;i++) {
if (uwsgi.mules[i].id == id) {
return &uwsgi.mules[i];
}
}
return NULL;
}
struct uwsgi_farm *get_farm_by_name(char *name) {
int i;
for(i=0;i<uwsgi.farms_cnt;i++) {
if (!strcmp(uwsgi.farms[i].name, name)) {
return &uwsgi.farms[i];
}
}
return NULL;
}
struct uwsgi_mule_farm *uwsgi_mule_farm_new(struct uwsgi_mule_farm **umf, struct uwsgi_mule *um) {
struct uwsgi_mule_farm *uwsgi_mf = *umf, *old_umf;
if (!uwsgi_mf) {
*umf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
uwsgi_mf = *umf;
}
else {
while(uwsgi_mf) {
old_umf = uwsgi_mf;
uwsgi_mf = uwsgi_mf->next;
}
uwsgi_mf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
old_umf->next = uwsgi_mf;
}
uwsgi_mf->mule = um;
uwsgi_mf->next = NULL;
return uwsgi_mf;
}
+26 -26
View File
@@ -95,7 +95,7 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
char buffer[0xffff];
char *argv[0xff] ;
int argc;
int argc = 0;
uint16_t ret;
ei_x_buff xr;
@@ -103,19 +103,20 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
ei_get_type(x->buff, &x->index, &etype, &esize);
#ifdef UWSGI_DEBUG
uwsgi_log("%d %c %c %c\n", etype, etype, ERL_SMALL_TUPLE_EXT, ERL_LARGE_TUPLE_EXT);
#endif
if (etype != ERL_SMALL_TUPLE_EXT && etype != ERL_LARGE_TUPLE_EXT) return;
uwsgi_log("decode tuple\n");
ei_decode_tuple_header(x->buff, &x->index, &arity);
#ifdef UWSGI_DEBUG
uwsgi_log("rpc arity %d\n", arity);
#endif
if (arity != 3) return ;
ei_get_type(x->buff, &x->index, &etype, &esize);
uwsgi_log("%d %c\n", etype, etype);
if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ;
gen_call = uwsgi_malloc(esize);
@@ -127,7 +128,9 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
ei_decode_string(x->buff, &x->index, gen_call);
}
#ifdef UWSGI_DEBUG
uwsgi_log("gen call = %s\n", gen_call);
#endif
ei_get_type(x->buff, &x->index, &etype, &esize);
@@ -138,13 +141,10 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
ei_get_type(x->buff, &x->index, &etype, &esize);
ei_skip_term(x->buff, &x->index);
uwsgi_log("skip0 %d %c\n", etype, etype);
ei_get_type(x->buff, &x->index, &etype, &esize);
uwsgi_log("skip1 %d %c\n", etype, etype);
ei_decode_ref(x->buff, &x->index, &eref);
ei_get_type(x->buff, &x->index, &etype, &esize);
uwsgi_log("%d %c\n", etype, etype);
module = uwsgi_malloc(esize);
@@ -157,17 +157,16 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
ei_get_type(x->buff, &x->index, &etype, &esize);
uwsgi_log("%d %c\n", etype, etype);
if (etype != ERL_SMALL_TUPLE_EXT) return ;
ei_decode_tuple_header(x->buff, &x->index, &arity);
#ifdef UWSGI_DEBUG
uwsgi_log("arity: %d\n", arity);
#endif
if (arity != 5) return ;
ei_get_type(x->buff, &x->index, &etype, &esize);
uwsgi_log("%d %c\n", etype, etype);
char *method = uwsgi_malloc(esize);
@@ -181,7 +180,6 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
if (strcmp(method, "call")) return;
ei_get_type(x->buff, &x->index, &etype, &esize);
uwsgi_log("%d %c\n", etype, etype);
if (etype != ERL_ATOM_EXT && etype != ERL_STRING_EXT) return ;
@@ -207,7 +205,9 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
ei_decode_string(x->buff, &x->index, call);
}
#ifdef UWSGI_DEBUG
uwsgi_log("RPC %s %s\n", module, call);
#endif
ei_get_type(x->buff, &x->index, &etype, &esize);
@@ -224,7 +224,9 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) {
ret = uwsgi_rpc(call, argc, argv, buffer);
#ifdef UWSGI_DEBUG
uwsgi_log("buffer: %.*s\n", ret, buffer);
#endif
ei_x_new_with_version(&xr);
@@ -247,7 +249,6 @@ void erlang_loop() {
int fd;
int eversion;
int i;
ei_x_buff x, xr;
@@ -286,7 +287,7 @@ void erlang_loop() {
if (em.msgtype == ERL_TICK)
continue;
uwsgi_log("From: %s To: %s RegName: %s\n", em.from.node, em.to.node, em.toname);
uwsgi_log("[erlang] message From: %s To (process): %s\n", em.from.node, em.toname);
@@ -300,20 +301,18 @@ void erlang_loop() {
uwsgi_erlang_rpc(fd, &em.from, &x);
}
else {
int uep = -1;
for(i=0;i<uerl.uep_cnt;i++) {
if (!strcmp(uerl.uep[i].name, em.toname)) {
uep = i;
struct uwsgi_erlang_process *uep = uerl.uep;
while(uep) {
if (!strcmp(uep->name, em.toname)) {
if (uep->plugin) {
uep->plugin(uep->func, &x);
}
break;
}
uep = uep->next;
}
if (uep > -1) {
if (uerl.uep[uep].plugin) {
uerl.uep[uep].plugin( uerl.uep[uep].func, &x );
}
}
else {
if (!uep) {
uwsgi_log("!!! unregistered erlang process requested, dumping it !!!\n");
dump_eterm(&x);
}
@@ -366,7 +365,6 @@ int erlang_init() {
if (uerl.name) {
uwsgi.master_process = 1;
host = strchr(uerl.name, '@');
@@ -422,10 +420,11 @@ int erlang_init() {
uwsgi_log("Erlang C-Node %s registered on port %d\n", ei_thisnodename(&uerl.cnode), ntohs(sin.sin_port));
if (register_fat_gateway("erlang", erlang_loop) == NULL) {
if (register_fat_gateway("uWSGI erlang c-node", erlang_loop) == NULL) {
uwsgi_log("unable to register the erlang gateway\n");
exit(1);
}
}
return 0;
@@ -435,7 +434,8 @@ int erlang_opt(int i, char *optarg) {
switch(i) {
case LONG_ARGS_ERLANG:
uerl.name = optarg;
uwsgi.master_process = 1;
uerl.name = optarg;
return 1;
case LONG_ARGS_ERLANG_COOKIE:
uerl.cookie = optarg;
+3 -4
View File
@@ -1,7 +1,5 @@
#include <ei.h>
#define MAX_UWSGI_ERLANG_PROCESSES 64
#define LONG_ARGS_ERLANG 17012
#define LONG_ARGS_ERLANG_COOKIE 17013
@@ -12,6 +10,8 @@ struct uwsgi_erlang_process {
char name[0xff];
void (*plugin)(void *, ei_x_buff *);
void *func;
struct uwsgi_erlang_process *next;
};
struct uwsgi_erlang {
@@ -24,7 +24,6 @@ struct uwsgi_erlang {
void *lock;
struct uwsgi_erlang_process uep[MAX_UWSGI_ERLANG_PROCESSES];
int uep_cnt;
struct uwsgi_erlang_process *uep;
};
+55 -28
View File
@@ -28,6 +28,8 @@
#define FASTROUTER_STATUS_RESPONSE 4
#define add_timeout(x) uwsgi_add_rb_timer(ufr.timeouts, time(NULL)+ufr.socket_timeout, x)
#define add_check_timeout(x) uwsgi_add_rb_timer(ufr.timeouts, time(NULL)+x, NULL)
#define del_check_timeout(x) rb_erase(&x->rbt, ufr.timeouts);
#define del_timeout(x) rb_erase(&x->timeout->rbt, ufr.timeouts); free(x->timeout);
struct uwsgi_fastrouter_socket {
@@ -54,7 +56,8 @@ struct uwsgi_fastrouter {
int base_len;
char *subscription_server;
struct uwsgi_dict *subscription_dict;
struct uwsgi_subscribe_slot *subscriptions;
int subscription_regexp;
int socket_timeout;
@@ -64,6 +67,8 @@ struct uwsgi_fastrouter {
struct rb_root *timeouts;
struct uwsgi_rb_timer *subscriptions_check;
int cheap;
int i_am_cheap;
} ufr;
@@ -105,6 +110,7 @@ struct option fastrouter_options[] = {
{"fastrouter-cheap", no_argument, &ufr.cheap, 1},
{"fastrouter-subscription-server", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER},
{"fastrouter-subscription-slot", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT},
{"fastrouter-subscription-use-regexp", no_argument, &ufr.subscription_regexp, 1},
{"fastrouter-timeout", required_argument, 0, LONG_ARGS_FASTROUTER_TIMEOUT},
{0, 0, 0, 0},
};
@@ -136,7 +142,6 @@ struct fastrouter_session {
int status;
struct uwsgi_header uh;
uint8_t h_pos;
char buffer[0xffff];
uint16_t pos;
char *hostname;
@@ -147,27 +152,47 @@ struct fastrouter_session {
char *instance_address;
uint64_t instance_address_len;
struct uwsgi_subscriber_name *un;
struct uwsgi_subscribe_node *un;
int pass_fd;
struct uwsgi_rb_timer *timeout;
int instance_failed;
uint8_t modifier1;
char buffer[0xffff];
};
static void close_session(struct fastrouter_session **fr_table, struct fastrouter_session *fr_session) {
// check timeout expired
if (fr_session == NULL) {
if (ufr.subscription_server) {
//time_t current_time = time(NULL);
uwsgi_log("checking for node health\n");
struct uwsgi_subscribe_slot *slot = ufr.subscriptions;
while(slot) {
struct uwsgi_subscribe_node *node = slot->nodes;
while(node) {
uwsgi_log("%.*s (hits: %llu) %.*s\n", slot->keylen, slot->key, slot->hits, node->len, node->name);
node = node->next;
}
slot = slot->next;
}
del_check_timeout(ufr.subscriptions_check);
ufr.subscriptions_check = add_check_timeout(10);
}
return;
}
close(fr_session->fd);
fr_table[fr_session->fd] = NULL;
if (fr_session->instance_fd != -1) {
if (ufr.subscription_server && (fr_session->instance_failed || fr_session->status == FASTROUTER_STATUS_CONNECTING)) {
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
if (fr_session->un->len > 0) {
if (ufr.subscription_dict->count > 0) {
ufr.subscription_dict->count--;
}
if (ufr.subscription_dict->count == 0 && ufr.cheap && !ufr.i_am_cheap) {
if (ufr.subscriptions && (fr_session->instance_failed || fr_session->status == FASTROUTER_STATUS_CONNECTING)) {
if (fr_session->un && fr_session->un->len > 0) {
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
uwsgi_remove_subscribe_node(&ufr.subscriptions, fr_session->un);
if (ufr.subscriptions == NULL && ufr.cheap && !ufr.i_am_cheap) {
uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n");
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
while(ufr_sock) {
@@ -202,7 +227,6 @@ static void expire_timeouts(struct fastrouter_session **fr_table) {
if (urbt->key <= current) {
close_session(fr_table, (struct fastrouter_session *)urbt->data);
uwsgi_log("timeout !!!\n");
continue;
}
@@ -327,20 +351,22 @@ void fastrouter_loop() {
events = event_queue_alloc(ufr.nevents);
ufr.timeouts = uwsgi_init_rb_timer();
if (!ufr.socket_timeout) ufr.socket_timeout = 30;
if (ufr.subscription_server) {
ufr_subserver = bind_to_udp(ufr.subscription_server, 0, 0);
event_queue_add_fd_read(ufr.queue, ufr_subserver);
if (!ufr.subscription_slot) ufr.subscription_slot = 30;
ufr.subscription_dict = uwsgi_dict_create(ufr.subscription_slot, 0);
// check for node status every 10 seconds
//ufr.subscriptions_check = add_check_timeout(10);
}
if (ufr.pattern) {
init_magic_table(magic_table);
}
ufr.timeouts = uwsgi_init_rb_timer();
if (!ufr.socket_timeout) ufr.socket_timeout = 30;
for (;;) {
@@ -386,6 +412,8 @@ void fastrouter_loop() {
fr_table[new_connection]->un = NULL;
fr_table[new_connection]->instance_failed = 0;
fr_table[new_connection]->instance_address_len = 0;
fr_table[new_connection]->hostname_len = 0;
fr_table[new_connection]->hostname = NULL;
fr_table[new_connection]->timeout = add_timeout(fr_table[new_connection]);
@@ -409,8 +437,7 @@ void fastrouter_loop() {
if (len > 0) {
memset(&usr, 0, sizeof(struct uwsgi_subscribe_req));
uwsgi_hooked_parse(bbuf+4, len-4, fastrouter_manage_subscription, &usr);
uwsgi_add_subscriber(ufr.subscription_dict, &usr);
if (ufr.i_am_cheap) {
if (uwsgi_add_subscribe_node(&ufr.subscriptions, &usr, ufr.subscription_regexp) && ufr.i_am_cheap) {
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
while(ufr_sock) {
event_queue_add_fd_read(ufr.queue, ufr_sock->fd);
@@ -473,7 +500,7 @@ void fastrouter_loop() {
}
#ifdef UWSGI_DEBUG
uwsgi_log("requested domain %.*s\n", fr_session->hostname_len, fr_session->hostname);
//uwsgi_log("requested domain %.*s\n", fr_session->hostname_len, fr_session->hostname);
#endif
if (ufr.use_cache) {
fr_session->instance_address = uwsgi_cache_get(fr_session->hostname, fr_session->hostname_len, &fr_session->instance_address_len);
@@ -491,7 +518,7 @@ void fastrouter_loop() {
fr_session->instance_address = tmp_socket_name;
}
else if (ufr.subscription_server) {
fr_session->un = uwsgi_get_subscriber(ufr.subscription_dict, fr_session->hostname, fr_session->hostname_len);
fr_session->un = uwsgi_get_subscribe_node(&ufr.subscriptions, fr_session->hostname, fr_session->hostname_len, ufr.subscription_regexp);
if (fr_session->un && fr_session->un->len) {
fr_session->instance_address = fr_session->un->name;
fr_session->instance_address_len = fr_session->un->len;
@@ -531,14 +558,12 @@ void fastrouter_loop() {
if (tmp_socket_name) free(tmp_socket_name);
if (fr_session->instance_fd < 0) {
/*
if (ufr.subscription_server) {
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
if (fr_session->un->len > 0) {
fr_session->un->len = 0;
if (ufr.subscription_dict->count > 0) {
ufr.subscription_dict->count--;
}
if (ufr.subscription_dict->count == 0 && ufr.cheap && !ufr.i_am_cheap) {
if (fr_session->un && fr_session->un->len > 0) {
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
uwsgi_remove_subscribe_node(&ufr.subscriptions, fr_session->un);
if (ufr.subscriptions == NULL && ufr.cheap && !ufr.i_am_cheap) {
uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n");
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
while(ufr_sock) {
@@ -549,6 +574,8 @@ void fastrouter_loop() {
}
}
}
*/
fr_session->instance_failed = 1;
close_session(fr_table, fr_session);
break;
}
@@ -678,7 +705,7 @@ void fastrouter_loop() {
// fallback to destroy !!!
default:
uwsgi_log("default action\n");
uwsgi_log("unknown event: closing session\n");
close_session(fr_table, fr_session);
break;
@@ -701,13 +728,13 @@ int fastrouter_init() {
if (!ufr.nevents) ufr.nevents = 64;
if (ufr.code_string_code && ufr.code_string_function) {
if (register_fat_gateway("fastrouter", fastrouter_loop) == NULL) {
if (register_fat_gateway("uWSGI fastrouter", fastrouter_loop) == NULL) {
uwsgi_log("unable to register the fastrouter gateway\n");
exit(1);
}
}
else {
if (register_gateway("fastrouter", fastrouter_loop) == NULL) {
if (register_gateway("uWSGI fastrouter", fastrouter_loop) == NULL) {
uwsgi_log("unable to register the fastrouter gateway\n");
exit(1);
}
+20 -14
View File
@@ -39,6 +39,7 @@ struct uwsgi_http {
int server;
char *subscription_server;
int subscription_regexp;
char *pattern;
int pattern_len;
@@ -60,7 +61,7 @@ struct uwsgi_http {
int socket_timeout;
struct uwsgi_dict *subscription_dict;
struct uwsgi_subscribe_slot *subscriptions;
struct rb_root *timeouts;
} uhttp;
@@ -76,6 +77,7 @@ struct option http_options[] = {
{"http-use-cluster", no_argument, &uhttp.use_cluster, 1},
{"http-events", required_argument, 0, LONG_ARGS_HTTP_EVENTS},
{"http-subscription-server", required_argument, 0, LONG_ARGS_HTTP_SUBSCRIPTION_SERVER},
{"http-subscription-use-regexp", no_argument, &uhttp.subscription_regexp, 1},
{"http-timeout", required_argument, 0, LONG_ARGS_HTTP_TIMEOUT},
{0, 0, 0, 0},
};
@@ -136,8 +138,10 @@ struct http_session {
char uss[MAX_HTTP_VEC*2];
char buffer[UMAX16];
char path_info[UMAX16];
uint16_t path_info_len;
struct uwsgi_subscriber_name *un;
struct uwsgi_subscribe_node *un;
in_addr_t ip_addr;
char ip[INET_ADDRSTRLEN];
@@ -156,9 +160,9 @@ static void close_session(struct http_session **uhttp_table, struct http_session
close(uhttp_session->fd);
uhttp_table[uhttp_session->fd] = NULL;
if (uhttp_session->instance_fd != -1) {
if (uhttp.subscription_server && (uhttp_session->instance_failed || uhttp_session->status == HTTP_STATUS_CONNECTING)) {
if (uhttp.subscriptions && (uhttp_session->instance_failed || uhttp_session->status == HTTP_STATUS_CONNECTING)) {
uwsgi_log("marking %.*s as failed\n", (int) uhttp_session->instance_address_len,uhttp_session->instance_address);
uhttp_session->un->len = 0;
uwsgi_remove_subscribe_node(&uhttp.subscriptions, uhttp_session->un);
}
close(uhttp_session->instance_fd);
uhttp_table[uhttp_session->instance_fd] = NULL;
@@ -325,13 +329,19 @@ int http_parse(struct http_session *h_session) {
base = ptr;
while(ptr < watermark) {
if (*ptr == '?' && !query_string) {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, base, ptr-base, &c);
// PATH_INFO must be url-decoded !!!
h_session->path_info_len = ptr-base;
http_url_decode(base, &h_session->path_info_len, h_session->path_info);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, h_session->path_info, h_session->path_info_len, &c);
query_string = ptr+1;
}
else if (*ptr == ' ') {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "REQUEST_URI", 11, base, ptr-base, &c);
if (!query_string) {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, base, ptr-base, &c);
// PATH_INFO must be url-decoded !!!
h_session->path_info_len = ptr-base;
http_url_decode(base, &h_session->path_info_len, h_session->path_info);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, h_session->path_info, h_session->path_info_len, &c);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "QUERY_STRING", 12, "", 0, &c);
}
else {
@@ -474,7 +484,6 @@ void http_loop() {
if (uhttp.subscription_server) {
uhttp_subserver = bind_to_udp(uhttp.subscription_server, 0, 0);
event_queue_add_fd_read(uhttp_queue, uhttp_subserver);
uhttp.subscription_dict = uwsgi_dict_create(100, 0);
}
if (uhttp.pattern) {
@@ -550,7 +559,7 @@ void http_loop() {
if (len > 0) {
memset(&usr, 0, sizeof(struct uwsgi_subscribe_req));
uwsgi_hooked_parse(bbuf+4, len-4, http_manage_subscription, &usr);
uwsgi_add_subscriber(uhttp.subscription_dict, &usr);
uwsgi_add_subscribe_node(&uhttp.subscriptions, &usr, uhttp.subscription_regexp);
}
}
else {
@@ -630,7 +639,7 @@ void http_loop() {
uhttp_session->instance_address_len = uhttp.to_len;
}
else if (uhttp.subscription_server) {
uhttp_session->un = uwsgi_get_subscriber(uhttp.subscription_dict, uhttp_session->hostname, uhttp_session->hostname_len);
uhttp_session->un = uwsgi_get_subscribe_node(&uhttp.subscriptions, uhttp_session->hostname, uhttp_session->hostname_len, uhttp.subscription_regexp);
if (uhttp_session->un && uhttp_session->un->len) {
uhttp_session->instance_address = uhttp_session->un->name;
uhttp_session->instance_address_len = uhttp_session->un->len;
@@ -661,10 +670,7 @@ void http_loop() {
}
if (uhttp_session->instance_fd < 0) {
if (uhttp.subscription_server) {
uwsgi_log("marking %.*s as failed\n", (int) uhttp_session->instance_address_len,uhttp_session->instance_address);
uhttp_session->un->len = 0;
}
uhttp_session->instance_failed = 1;
close_session(uhttp_table, uhttp_session);
break;
}
@@ -883,7 +889,7 @@ int http_init() {
uhttp.server = bind_to_tcp(uhttp.socket_name, uwsgi.listen_queue, strchr(uhttp.socket_name,':'));
if (register_gateway("http", http_loop) == NULL) {
if (register_gateway("uWSGI http", http_loop) == NULL) {
uwsgi_log("unable to register the http gateway\n");
exit(1);
}
+1 -1
View File
@@ -34,7 +34,7 @@ struct uwsgi_perl {
void init_perl_embedded_module(void);
void uwsgi_psgi_app(void);
int psgi_response(struct wsgi_request *, PerlInterpreter *, AV*);
int psgi_response(struct wsgi_request *, AV*);
#define psgi_xs(func) newXS("uwsgi::" #func, XS_##func, "uwsgi")
#define psgi_check_args(x) if (items < x) Perl_croak(aTHX_ "Usage: uwsgi::%s takes %d arguments", __FUNCTION__ + 3, x)
+26 -14
View File
@@ -41,19 +41,11 @@ XS(XS_stream)
AV *response = (AV* ) SvREFCNT_inc(SvRV(ST(0))) ;
if (av_len(response) == 2) {
#ifdef my_perl
while (psgi_response(wsgi_req, my_perl, response) != UWSGI_OK);
#else
while (psgi_response(wsgi_req, uperl.main, response) != UWSGI_OK);
#endif
while (psgi_response(wsgi_req, response) != UWSGI_OK);
}
else if (av_len(response) == 1) {
#ifdef my_perl
while (psgi_response(wsgi_req, my_perl, response) != UWSGI_OK);
#else
while (psgi_response(wsgi_req, uperl.main, response) != UWSGI_OK);
#endif
while (psgi_response(wsgi_req, response) != UWSGI_OK);
SvREFCNT_dec(response);
ST(0) = sv_bless(newRV(sv_newmortal()), uperl.streaming_stash);
XSRETURN(1);
@@ -236,6 +228,7 @@ xs_init(pTHX)
void uwsgi_psgi_app() {
struct stat stat_psgi;
int id = uwsgi_apps_cnt;
if (uperl.psgi) {
@@ -291,7 +284,6 @@ void uwsgi_psgi_app() {
uperl.psgibuffer[stat_psgi.st_size] = 0;
if (uwsgi.threads < 2) {
uperl.psgi_main = perl_eval_pv(uwsgi_concat4("#line 1 ", uperl.psgi, "\n", uperl.psgibuffer), 0);
if (!uperl.psgi_main) {
uwsgi_log("unable to find PSGI function entry point.\n");
@@ -303,11 +295,31 @@ void uwsgi_psgi_app() {
exit(1);
}
if (uwsgi.threads < 2) {
free(uperl.psgibuffer);
close(uperl.fd);
}
}
struct uwsgi_app *wi = &uwsgi_apps[id];
memset(wi, 0, sizeof(struct uwsgi_app));
wi->modifier1 = 5;
wi->mountpoint = "";
wi->mountpoint_len = 0;
uwsgi_log("PSGI app %d (%s) loaded at %p\n", id, uperl.psgi, uperl.psgi_main);
uwsgi_apps_cnt++;
// check if we need to emulate fork() COW
int i;
if (uwsgi.mywid == 0) {
for(i=1;i<=uwsgi.numproc;i++) {
memcpy(&uwsgi.workers[i].apps[id], &uwsgi.workers[0].apps[id], sizeof(struct uwsgi_app));
uwsgi.workers[i].apps_cnt = uwsgi_apps_cnt;
}
}
uwsgi_log("PSGI app (%s) loaded at %p\n", uperl.psgi, uperl.psgi_main);
}
+41 -62
View File
@@ -23,7 +23,7 @@ SV *uwsgi_perl_obj_new(char *class, size_t class_len) {
SV *newobj;
// set current context ?
//dTHX;
dTHX;
dSP;
ENTER;
@@ -49,7 +49,7 @@ SV *uwsgi_perl_call_stream(SV *func) {
SV *ret = NULL;
// set current context ?
//dTHX;
dTHX;
dSP;
ENTER;
@@ -79,7 +79,7 @@ int uwsgi_perl_obj_can(SV *obj, char *method, size_t len) {
int ret;
// set current context ? needed for threading
//dTHX;
dTHX;
dSP;
ENTER;
@@ -107,6 +107,7 @@ SV *uwsgi_perl_obj_call(SV *obj, char *method) {
SV *ret = NULL;
dTHX;
dSP;
ENTER;
@@ -140,6 +141,7 @@ AV *psgi_call(struct wsgi_request *wsgi_req, SV *psgi_func, SV *env) {
AV *ret = NULL;
dTHX;
dSP;
ENTER;
@@ -149,6 +151,7 @@ AV *psgi_call(struct wsgi_request *wsgi_req, SV *psgi_func, SV *env) {
PUTBACK;
call_sv(psgi_func, G_SCALAR | G_EVAL);
SPAGAIN;
if(SvTRUE(ERRSV)) {
@@ -326,51 +329,19 @@ int uwsgi_perl_init(){
}
#ifdef my_perl
#ifdef USE_ITHREADS
void uwsgi_perl_enable_threads() {
int i;
if (pthread_key_create(&uperl.u_interpreter, NULL)) {
uwsgi_error("pthread_key_create()");
exit(1);
}
uperl.interp = malloc( sizeof(PerlInterpreter*) * uwsgi.threads );
if (!uperl.interp) {
uwsgi_error("malloc()");
exit(1);
}
uperl.interp = uwsgi_malloc( sizeof(PerlInterpreter*) * uwsgi.threads );
uperl.interp[0] = uperl.main;
for(i=1;i<uwsgi.threads;i++) {
uperl.interp[i] = perl_clone(uperl.main, CLONEf_KEEP_PTR_TABLE);
if (!uperl.interp[i]) {
uwsgi_log("unable to create new perl interpreter\n");
exit(1);
}
}
uperl.psgi_func = uwsgi_malloc( sizeof(SV*) * uwsgi.threads );
uperl.psgi_func = malloc( sizeof(SV*) * uwsgi.threads );
if (!uperl.psgi_func) {
uwsgi_error("malloc()");
exit(1);
}
dTHXa(uperl.main);
PERL_SET_CONTEXT(uperl.main);
uperl.psgi_main = perl_eval_pv(uperl.psgibuffer, 0);
if (!uperl.psgi_main) {
uwsgi_log("unable to find PSGI function entry point.\n");
exit(1);
}
if(SvTRUE(ERRSV)) {
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
exit(1);
}
}
#endif
@@ -381,12 +352,10 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
SV **harakiri;
SV *psgi_func = uperl.psgi_main;
// ugly hack
register PerlInterpreter *my_perl = uperl.main;
#ifdef UWSGI_ASYNC
if (wsgi_req->async_status == UWSGI_AGAIN) {
return psgi_response(wsgi_req, my_perl, wsgi_req->async_placeholder);
return psgi_response(wsgi_req, wsgi_req->async_placeholder);
}
#endif
@@ -401,19 +370,14 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
return -1;
}
#ifdef UWSGI_THREADING
if (uwsgi.threads > 1 && wsgi_req->async_id > 0) {
if (uwsgi.threads > 1) {
psgi_func = uperl.psgi_func[wsgi_req->async_id];
my_perl = pthread_getspecific(uperl.u_interpreter);
}
#endif
ENTER;
SAVETMPS;
wsgi_req->async_environ = build_psgi_env(wsgi_req);
if (!wsgi_req->async_environ) goto clear;
@@ -431,7 +395,7 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
goto clear2;
}
while (psgi_response(wsgi_req, my_perl, wsgi_req->async_result) != UWSGI_OK) {
while (psgi_response(wsgi_req, wsgi_req->async_result) != UWSGI_OK) {
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1) {
FREETMPS;
@@ -471,26 +435,41 @@ void uwsgi_perl_after_request(struct wsgi_request *wsgi_req) {
}
#ifdef USE_ITHREADS
void uwsgi_perl_init_thread(int core_id) {
pthread_setspecific(uperl.u_interpreter, uperl.interp[core_id]);
if (core_id > 0) {
uperl.interp[core_id] = perl_clone(uperl.main, CLONEf_KEEP_PTR_TABLE);
if (!uperl.interp[core_id]) {
uwsgi_log("unable to create new perl interpreter\n");
exit(1);
}
}
dTHXa(uperl.interp[core_id]);
PERL_SET_CONTEXT(uperl.interp[core_id]);
uperl.psgi_func[core_id] = perl_eval_pv(uperl.psgibuffer, 0);
if (!uperl.psgi_func[core_id]) {
uwsgi_log("unable to find PSGI function entry point.\n");
exit(1);
}
pthread_setspecific(uperl.u_interpreter, uperl.interp[core_id]);
if(SvTRUE(ERRSV)) {
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
exit(1);
}
uperl.psgi_func[0] = uperl.psgi_main;
if (core_id > 0) {
uperl.psgi_func[core_id] = perl_eval_pv(uwsgi_concat4("#line 1 ", uperl.psgi, "\n", uperl.psgibuffer), 0);
if (!uperl.psgi_func[core_id]) {
uwsgi_log("unable to find PSGI function entry point.\n");
exit(1);
}
if(SvTRUE(ERRSV)) {
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
exit(1);
}
}
}
#endif
int uwsgi_perl_manage_options(int i, char *optarg) {
@@ -531,11 +510,11 @@ struct uwsgi_plugin psgi_plugin = {
.init_apps = uwsgi_psgi_app,
//.magic = uwsgi_perl_magic,
//.help = uwsgi_perl_help,
#ifdef my_perl
#ifdef USE_ITHREADS
.enable_threads = uwsgi_perl_enable_threads,
.init_thread = uwsgi_perl_init_thread,
#endif
.manage_opt = uwsgi_perl_manage_options,
.init_thread = uwsgi_perl_init_thread,
.request = uwsgi_perl_request,
.after_request = uwsgi_perl_after_request,
+1 -1
View File
@@ -4,7 +4,7 @@ extern struct uwsgi_server uwsgi;
extern struct http_status_codes hsc[];
int psgi_response(struct wsgi_request *wsgi_req, PerlInterpreter *my_perl, AV *response) {
int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
SV **status_code, **hitem ;
AV *headers, *body =NULL;
+21 -8
View File
@@ -304,7 +304,7 @@ void pyerl_call_registered(void *func, ei_x_buff *x) {
PyTuple_SetItem(pyargs, 0, erl_to_py(x));
python_call((PyObject *) func, pyargs, 0);
python_call((PyObject *) func, pyargs, 0, NULL);
}
PyObject *pyerl_register_process(PyObject * self, PyObject * args) {
@@ -316,17 +316,30 @@ PyObject *pyerl_register_process(PyObject * self, PyObject * args) {
return NULL;
}
if (uerl.uep_cnt >= MAX_UWSGI_ERLANG_PROCESSES)
return PyErr_Format(PyExc_ValueError, "You can define max %d erlang registered processes", MAX_UWSGI_ERLANG_PROCESSES);
if (strlen(name) > 0xff-1)
return PyErr_Format(PyExc_ValueError, "Invalid erlang process name");
strcpy(uerl.uep[uerl.uep_cnt].name, name);
uerl.uep[uerl.uep_cnt].plugin = pyerl_call_registered;
uerl.uep[uerl.uep_cnt].func = callable;
struct uwsgi_erlang_process *uep = uerl.uep, *old_uep;
if (!uep) {
uerl.uep = uwsgi_malloc(sizeof(struct uwsgi_erlang_process));
uep = uerl.uep;
}
else {
while(uep) {
old_uep = uep;
uep = uep->next;
}
uep = uwsgi_malloc(sizeof(struct uwsgi_erlang_process));
old_uep->next = uep;
}
strcpy(uep->name, name);
uep->plugin = pyerl_call_registered;
uep->func = callable;
uep->next = NULL;
uerl.uep_cnt++;
Py_INCREF(Py_None);
return Py_None;
+38 -2
View File
@@ -915,9 +915,11 @@ void uwsgi_python_init_apps() {
#ifdef __linux__
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
#ifndef UWSGI_PYPY
#ifdef UWSGI_EMBEDDED
uwsgi_init_symbol_import();
#endif
#endif
#endif
if (up.test_module != NULL) {
@@ -1241,6 +1243,8 @@ clear:
uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, char *buffer) {
UWSGI_GET_GIL;
uint8_t i;
PyObject *pyargs = PyTuple_New(argc);
PyObject *ret;
@@ -1263,6 +1267,7 @@ uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, char *buffer) {
if (rl <= 0xffff) {
memcpy(buffer, rv, rl);
Py_DECREF(ret);
UWSGI_RELEASE_GIL;
return rl;
}
}
@@ -1271,6 +1276,7 @@ uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, char *buffer) {
if (PyErr_Occurred())
PyErr_Print();
UWSGI_RELEASE_GIL;
return 0;
@@ -1398,7 +1404,9 @@ int uwsgi_python_mule(char *opt) {
if (uwsgi_endswith(opt, ".py")) {
UWSGI_GET_GIL;
uwsgi_pyimport_by_filename("__main__", opt);
if (uwsgi_pyimport_by_filename("__main__", opt) == NULL) {
return 0;
}
UWSGI_RELEASE_GIL;
return 1;
}
@@ -1407,6 +1415,33 @@ int uwsgi_python_mule(char *opt) {
}
int uwsgi_python_mule_msg(char *message, size_t len) {
UWSGI_GET_GIL;
PyObject *mule_msg_hook = PyDict_GetItemString(up.embedded_dict, "mule_msg_hook");
if (!mule_msg_hook) {
// ignore
UWSGI_RELEASE_GIL;
return 0;
}
PyObject *pyargs = PyTuple_New(1);
PyTuple_SetItem(pyargs, 0, PyString_FromStringAndSize(message, len));
PyObject *ret = python_call(mule_msg_hook, pyargs, 0, NULL);
Py_DECREF(pyargs);
if (ret) {
Py_DECREF(ret);
}
if (PyErr_Occurred())
PyErr_Print();
UWSGI_RELEASE_GIL;
return 1;
}
struct uwsgi_plugin python_plugin = {
.name = "python",
@@ -1444,6 +1479,7 @@ struct uwsgi_plugin python_plugin = {
.rpc = uwsgi_python_rpc,
.mule = uwsgi_python_mule,
.mule_msg = uwsgi_python_mule_msg,
.spooler = uwsgi_python_spooler,
+43 -3
View File
@@ -1,6 +1,6 @@
#include "uwsgi_python.h"
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
#ifndef UWSGI_PYPY
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
@@ -201,9 +201,14 @@ static PyObject* symzipimporter_load_module(PyObject *self, PyObject *args) {
PyObject *source = PyObject_CallMethod(this->zip, "read", "(s)", filename);
free(filename);
PyObject *code = Py_CompileString(PyString_AsString(source), modname, Py_file_input);
if (!code) {
PyErr_Print();
goto shit;
}
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
shit:
Py_DECREF(source);
free(modname);
return mod;
@@ -231,9 +236,14 @@ static PyObject* symzipimporter_load_module(PyObject *self, PyObject *args) {
PyObject *source = PyObject_CallMethod(this->zip, "read", "(s)", filename);
free(filename);
PyObject *code = Py_CompileString(PyString_AsString(source), modname, Py_file_input);
if (!code) {
PyErr_Print();
goto shit2;
}
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
shit2:
Py_DECREF(source);
free(modname);
return mod;
@@ -306,9 +316,14 @@ static PyObject* symimporter_load_module(PyObject *self, PyObject *args) {
modname = uwsgi_concat3("sym://", fullname2, "_py");
code = Py_CompileString(source, modname, Py_file_input);
if (!code) {
PyErr_Print();
goto shit;
}
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
shit:
free(source);
free(modname);
free(fullname2);
@@ -334,9 +349,14 @@ static PyObject* symimporter_load_module(PyObject *self, PyObject *args) {
PyDict_SetItemString(dict, "__loader__", self);
code = Py_CompileString(source, modname, Py_file_input);
if (!code) {
PyErr_Print();
goto shit2;
}
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
shit2:
free(source);
free(modname);
free(fullname2);
@@ -450,7 +470,10 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
}
PyObject *stringio_dict = PyModule_GetDict(stringio);
#ifdef PYTHREE
PyObject *source_code = PyObject_CallMethodObjArgs(stringio, PyString_FromString("StringIO"), PyString_FromStringAndSize(body, len));
#else
PyObject *stringio_dict = PyModule_GetDict(stringio);
if (!stringio_dict) {
return -1;
}
@@ -466,7 +489,9 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
PyTuple_SetItem(stringio_args, 0, PyString_FromStringAndSize(body, len));
PyObject *source_code = PyInstance_New(stringio_stringio, stringio_args, NULL);
#endif
if (!source_code) {
return -1;
}
@@ -480,7 +505,10 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
}
PyObject *zipfile_dict = PyModule_GetDict(zipfile);
#ifdef PYTHREE
self->zip = PyObject_CallMethodObjArgs(zipfile, PyString_FromString("ZipFile"), source_code);
#else
PyObject *zipfile_dict = PyModule_GetDict(zipfile);
if (!zipfile_dict) {
return -1;
}
@@ -494,7 +522,9 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
PyObject *zipfile_args = PyTuple_New(1);
PyTuple_SetItem(zipfile_args, 0, source_code);
self->zip = PyInstance_New(zipfile_zipfile, zipfile_args, NULL);
#endif
if (!self->zip) {
return -1;
}
@@ -556,6 +586,9 @@ symzipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds
return -1;
}
#ifdef PYTHREE
PyObject *source_code = PyObject_CallMethodObjArgs(stringio, PyString_FromString("StringIO"), PyString_FromStringAndSize(code_start, code_end-code_start));
#else
PyObject *stringio_dict = PyModule_GetDict(stringio);
if (!stringio_dict) {
return -1;
@@ -569,7 +602,9 @@ symzipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds
PyObject *stringio_args = PyTuple_New(1);
PyTuple_SetItem(stringio_args, 0, PyString_FromStringAndSize(code_start, code_end-code_start));
PyObject *source_code = PyInstance_New(stringio_stringio, stringio_args, NULL);
#endif
if (!source_code) {
return -1;
}
@@ -579,6 +614,9 @@ symzipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds
return -1;
}
#ifdef PYTHREE
self->zip = PyObject_CallMethodObjArgs(zipfile, PyString_FromString("ZipFile"), source_code);
#else
PyObject *zipfile_dict = PyModule_GetDict(zipfile);
if (!zipfile_dict) {
return -1;
@@ -592,7 +630,9 @@ symzipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds
PyObject *zipfile_args = PyTuple_New(1);
PyTuple_SetItem(zipfile_args, 0, source_code);
self->zip = PyInstance_New(zipfile_zipfile, zipfile_args, NULL);
#endif
if (!self->zip) {
return -1;
}
+296 -22
View File
@@ -1037,7 +1037,7 @@ PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
}
uwsgi_unlock(uwsgi.user_lock);
uwsgi_unlock(uwsgi.user_lock[lock_num]);
Py_INCREF(Py_None);
return Py_None;
@@ -1072,52 +1072,319 @@ PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_setprocname(PyObject * self, PyObject * args) {
char *name = NULL;
if (!PyArg_ParseTuple(args, "s:setprocname", &name)) {
return NULL;
}
uwsgi_set_processname(name);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_in_farm(PyObject * self, PyObject * args) {
char *farm_name = NULL;
int i;
if (!PyArg_ParseTuple(args, "|s:in_farm", &farm_name)) {
return NULL;
}
if (uwsgi.muleid == 0) goto none;
for(i=0;i<uwsgi.farms_cnt;i++) {
if (!farm_name) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
Py_INCREF(Py_True);
return Py_True;
}
}
else {
if (!strcmp(farm_name, uwsgi.farms[i].name)) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
Py_INCREF(Py_True);
return Py_True;
}
}
}
}
none:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_farm_msg(PyObject * self, PyObject * args) {
char *message = NULL;
Py_ssize_t message_len = 0;
char *farm_name = NULL;
ssize_t len;
int i;
if (!PyArg_ParseTuple(args, "ss#:farm_msg", &farm_name, &message, &message_len)) {
return NULL;
}
for(i=0;i<uwsgi.farms_cnt;i++) {
if (!strcmp(farm_name, uwsgi.farms[i].name)) {
len = write(uwsgi.farms[i].queue_pipe[0], message, message_len);
if (len <= 0) {
uwsgi_error("write()");
}
break;
}
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_mule_msg(PyObject * self, PyObject * args) {
char *message = NULL;
Py_ssize_t message_len = 0;
int mule_id = 0;
PyObject *mule_obj = NULL;
ssize_t len;
int fd = -1;
int mule_id = -1;
if (!PyArg_ParseTuple(args, "s#|i:mule_msg", &message, &message_len, &mule_id)) {
if (!PyArg_ParseTuple(args, "s#|O:mule_msg", &message, &message_len, &mule_obj)) {
return NULL;
}
if (mule_id == 0) {
}
else if (mule_id > 0 && mule_id <= uwsgi.mules_cnt) {
len = write(uwsgi.mules[mule_id-1].queue_pipe[0], message, message_len);
if (uwsgi.mules_cnt < 1)
return PyErr_Format(PyExc_ValueError, "no mule configured");
if (mule_obj == NULL) {
len = write(uwsgi.shared->mule_queue_pipe[0], message, message_len);
if (len <= 0) {
uwsgi_error("write()");
}
}
else {
if (PyString_Check(mule_obj)) {
struct uwsgi_farm *uf = get_farm_by_name(PyString_AsString(mule_obj));
if (uf == NULL) {
return PyErr_Format(PyExc_ValueError, "unknown farm");
}
fd = uf->queue_pipe[0];
}
else if (PyInt_Check(mule_obj)) {
mule_id = PyInt_AsLong(mule_obj);
if (mule_id < 0 && mule_id > uwsgi.mules_cnt) {
return PyErr_Format(PyExc_ValueError, "invalid mule number");
}
if (mule_id == 0) {
fd = uwsgi.shared->mule_queue_pipe[0];
}
else {
fd = uwsgi.mules[mule_id-1].queue_pipe[0];
}
}
else {
return PyErr_Format(PyExc_ValueError, "invalid mule");
}
if (fd > -1) {
len = write(fd, message, message_len);
if (len < 0) {
uwsgi_error("write()");
}
}
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_mule_get_msg(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_mule_get_msg(PyObject * self, PyObject * args, PyObject *kwargs) {
ssize_t len;
ssize_t len = 0;
// this buffer will be configurable
char message[65536];
char *message;
struct pollfd *mulepoll;
int count = 4;
int farms_count = 0;
uint8_t uwsgi_signal;
PyObject *manage_signals = NULL;
PyObject *manage_farms = NULL;
int buffer_size = 65536;
int timeout = -1;
int i;
static char *kwlist[] = {"signals", "buffer_size", "timeout", "farms", NULL};
if (uwsgi.muleid == 0) {
return PyErr_Format(PyExc_ValueError, "you can receive mule messages only in a mule !!!");
}
UWSGI_RELEASE_GIL;
len = read(uwsgi.mules[uwsgi.muleid-1].queue_pipe[1], message, 65536);
UWSGI_GET_GIL;
if (len <= 0) {
uwsgi_error("read()");
Py_INCREF(Py_None);
return Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii:mule_get_msg", kwlist, &manage_signals, &manage_farms, &buffer_size, &timeout)) {
return NULL;
}
return PyString_FromStringAndSize(message, len);
if (manage_signals == Py_None || manage_signals == Py_False) {
count = 2;
}
if (manage_farms == Py_None || manage_farms == Py_False) {
goto next;
}
for(i=0;i<uwsgi.farms_cnt;i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) farms_count++;
}
next:
UWSGI_RELEASE_GIL;
if (timeout > -1) timeout = timeout*1000;
message = uwsgi_malloc(buffer_size);
mulepoll = uwsgi_malloc(sizeof(struct pollfd) * (count+farms_count));
mulepoll[0].fd = uwsgi.mules[uwsgi.muleid-1].queue_pipe[1];
mulepoll[0].events = POLLIN;
mulepoll[1].fd = uwsgi.shared->mule_queue_pipe[1];
mulepoll[1].events = POLLIN;
if (count > 2) {
mulepoll[2].fd = uwsgi.signal_socket;
mulepoll[2].events = POLLIN;
mulepoll[3].fd = uwsgi.my_signal_socket;
mulepoll[3].events = POLLIN;
}
for(i=0;i<farms_count;i++) {
mulepoll[count+i].fd = uwsgi.farms[i].queue_pipe[1];
mulepoll[count+i].events = POLLIN;
}
int ret = poll(mulepoll, count+farms_count, timeout);
if (ret <= 0) {
uwsgi_error("poll");
}
else {
if (mulepoll[0].revents & POLLIN) {
len = read(uwsgi.mules[uwsgi.muleid-1].queue_pipe[1], message, buffer_size);
}
else if (mulepoll[1].revents & POLLIN) {
len = read(uwsgi.shared->mule_queue_pipe[1], message, buffer_size);
}
else {
if (count > 2) {
int interesting_fd = -1;
if (mulepoll[2].revents & POLLIN) {
interesting_fd = mulepoll[2].fd;
}
else if (mulepoll[3].revents & POLLIN) {
interesting_fd = mulepoll[3].fd;
}
if (interesting_fd > -1) {
len = read(interesting_fd, &uwsgi_signal, 1);
if (len <= 0) {
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
end_me(0);
}
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.mywid);
}
goto clear;
}
}
for(i=0;i<farms_count;i++) {
if (mulepoll[count+i].revents & POLLIN) {
len = read(mulepoll[count+i].fd, message, buffer_size);
break;
}
}
}
}
UWSGI_GET_GIL;
if (len < 0) {
uwsgi_error("read()");
goto clear2;
}
PyObject *msg = PyString_FromStringAndSize(message, len);
free(message);
free(mulepoll);
return msg;
clear:
UWSGI_GET_GIL;
clear2:
free(message);
free(mulepoll);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_farm_get_msg(PyObject * self, PyObject * args) {
ssize_t len = 0;
// this buffer will be configurable
char message[65536];
int i, count = 0, pos = 0, ret;
struct pollfd *farmpoll;
if (uwsgi.muleid == 0) {
return PyErr_Format(PyExc_ValueError, "you can receive farm messages only in a mule !!!");
}
UWSGI_RELEASE_GIL;
for(i=0;i<uwsgi.farms_cnt;i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) count++;
}
farmpoll = uwsgi_malloc( sizeof(struct pollfd) * count);
for(i=0;i<uwsgi.farms_cnt;i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
farmpoll[pos].fd = uwsgi.farms[i].queue_pipe[1];
farmpoll[pos].events = POLLIN;
pos++;
}
}
ret = poll(farmpoll, count, -1);
if (ret <= 0) {
uwsgi_error("poll()");
free(farmpoll);
Py_INCREF(Py_None);
return Py_None;
}
for(i=0;i<count;i++) {
if (farmpoll[i].revents & POLLIN) {
len = read(farmpoll[i].fd, message, 65536);
break;
}
}
UWSGI_GET_GIL;
if (len <= 0) {
uwsgi_error("read()");
free(farmpoll);
Py_INCREF(Py_None);
return Py_None;
}
free(farmpoll);
return PyString_FromStringAndSize(message, len);
}
PyObject *py_uwsgi_extract(PyObject * self, PyObject * args) {
char *name;
@@ -2479,12 +2746,13 @@ PyObject *py_uwsgi_logsize(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_mem(PyObject * self, PyObject * args) {
uint64_t rss=0, vsz = 0;
PyObject *ml = PyTuple_New(2);
get_memusage();
get_memusage(&rss, &vsz);
PyTuple_SetItem(ml, 0, PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].rss_size));
PyTuple_SetItem(ml, 1, PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].vsz_size));
PyTuple_SetItem(ml, 0, PyLong_FromUnsignedLongLong(rss));
PyTuple_SetItem(ml, 1, PyLong_FromUnsignedLongLong(vsz));
return ml;
@@ -2636,6 +2904,7 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
goto clear;
}
// use a normal fork here
grunt_pid = fork();
if (grunt_pid < 0) {
uwsgi_error("fork()");
@@ -2809,6 +3078,8 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
{"cl", py_uwsgi_cl, METH_VARARGS, ""},
{"setprocname", py_uwsgi_setprocname, METH_VARARGS, ""},
{"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""},
{"attach_daemon", py_uwsgi_attach_daemon, METH_VARARGS, ""},
@@ -2868,7 +3139,10 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"extract", py_uwsgi_extract, METH_VARARGS, ""},
{"mule_msg", py_uwsgi_mule_msg, METH_VARARGS, ""},
{"mule_get_msg", py_uwsgi_mule_get_msg, METH_VARARGS, ""},
{"farm_msg", py_uwsgi_farm_msg, METH_VARARGS, ""},
{"mule_get_msg", (PyCFunction) py_uwsgi_mule_get_msg, METH_VARARGS|METH_KEYWORDS, ""},
{"farm_get_msg", py_uwsgi_farm_get_msg, METH_VARARGS, ""},
{"in_farm", py_uwsgi_in_farm, METH_VARARGS, ""},
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
{NULL, NULL},
-2
View File
@@ -275,7 +275,5 @@ char *uwsgi_pythonize(char *);
#define uwsgi_pyexit {PyErr_Print();exit(1);}
#ifdef __linux__
#ifndef PYTHREE
int uwsgi_init_symbol_import(void);
#endif
#endif
+188
View File
@@ -0,0 +1,188 @@
#include "../../uwsgi.h"
extern struct uwsgi_server uwsgi;
#define RRDTOOL_OPT_BASE 177000
#define RRDTOOL_OPT_RRDTOOL RRDTOOL_OPT_BASE+1
#define RRDTOOL_OPT_RRDTOOL_MAX_DS RRDTOOL_OPT_BASE+2
struct uwsgi_rrdtool {
void *lib;
int (*create)(int, char **);
int (*update)(int, char **);
struct uwsgi_string_list *rrd;
int max_ds;
char *update_area;
} u_rrd;
struct option rrdtool_options[] = {
{"rrdtool", required_argument, 0, RRDTOOL_OPT_RRDTOOL},
{"rrdtool-max-ds", required_argument, 0, RRDTOOL_OPT_RRDTOOL_MAX_DS},
{0, 0, 0, 0},
};
int rrdtool_init() {
u_rrd.lib = dlopen("librrd.so", RTLD_LAZY);
if (!u_rrd.lib) return -1;
u_rrd.create = dlsym(u_rrd.lib, "rrd_create");
if (!u_rrd.create) {
dlclose(u_rrd.lib);
return -1;
}
u_rrd.update = dlsym(u_rrd.lib, "rrd_update");
if (!u_rrd.update) {
dlclose(u_rrd.lib);
return -1;
}
if (!u_rrd.max_ds) u_rrd.max_ds = 30;
uwsgi_log("*** RRDtool library available at %p ***\n", u_rrd.lib);
return 0;
}
int rrdtool_opt(int i, char *optarg) {
switch(i) {
case RRDTOOL_OPT_RRDTOOL:
uwsgi.master_process = 1;
uwsgi_string_new_list(&u_rrd.rrd, optarg);
return 1;
case RRDTOOL_OPT_RRDTOOL_MAX_DS:
u_rrd.max_ds = atoi(optarg);
return 1;
}
return 0;
}
void rrdtool_post_init() {
struct uwsgi_string_list *usl = u_rrd.rrd;
char **argv;
int i;
if (!u_rrd.lib || !u_rrd.create) return;
// do not waste time if no --rrdtool option is defiend
if (!u_rrd.rrd) return;
if (uwsgi.numproc > u_rrd.max_ds) {
uwsgi_log("!!! NOT ENOUGH SLOTS IN RRDTOOL DS TO HOST WORKERS DATA (increase them with --rrdtool-max-ds) !!!\n");
dlclose(u_rrd.lib);
return;
}
// alloc space for DS_REQ + DS WORKER + RRA + create + filename
argv = uwsgi_malloc( sizeof(char *) * (1 + u_rrd.max_ds + 4 + 1 +1));
argv[0] = "create";
argv[2] = "DS:requests:DERIVE:600:0:U";
// create DS for workers
for(i=0;i<u_rrd.max_ds;i++) {
int max_size = sizeof("DS:worker65536:DERIVE:600:0:U")+1;
argv[3+i] = uwsgi_malloc( max_size );
if (snprintf(argv[3+i], max_size, "DS:worker%d:DERIVE:600:0:U", i+1) < 25) {
uwsgi_log("unable to create args for rrd_create()\n");
exit(1);
}
}
// create RRA
argv[3+u_rrd.max_ds] = "RRA:AVERAGE:0.5:1:288" ;
argv[3+u_rrd.max_ds+1] = "RRA:AVERAGE:0.5:12:168" ;
argv[3+u_rrd.max_ds+2] = "RRA:AVERAGE:0.5:288:31" ;
argv[3+u_rrd.max_ds+3] = "RRA:AVERAGE:0.5:2016:52";
while(usl) {
if (!uwsgi_file_exists(usl->value)) {
argv[1] = usl->value;
if (u_rrd.create((1 + u_rrd.max_ds + 4 + 1 +1), argv)) {
uwsgi_error("rrd_create()");
exit(1);
}
}
usl->value = realpath(usl->value, NULL);
if (!usl->value) {
uwsgi_error("realpath()");
exit(1);
}
usl = usl->next;
}
// free DS
for(i=0;i<u_rrd.max_ds;i++) {
free(argv[3+i]);
}
free(argv);
//now allocate memory for updates
u_rrd.update_area = uwsgi_malloc( 1+((1+sizeof(UMAX64_STR)) * (u_rrd.max_ds+1))+1 );
memset(u_rrd.update_area, 0, 1+((1+sizeof(UMAX64_STR)) * (u_rrd.max_ds+1))+1 );
u_rrd.update_area[0] = 'N';
}
void rrdtool_master_cycle() {
static time_t last_update = 0;
char *ptr;
int rlen, i;
char *argv[3];
struct uwsgi_string_list *usl = u_rrd.rrd;
if (!u_rrd.lib || !u_rrd.create || !u_rrd.rrd) return ;
if (last_update == 0) last_update = time(NULL);
// update every 5 minutes
if (uwsgi.current_time - last_update >= 300) {
ptr = u_rrd.update_area+1;
rlen = snprintf(ptr, 1+sizeof(UMAX64_STR), ":%llu", (unsigned long long )uwsgi.workers[0].requests);
if (rlen < 2) return;
ptr+=rlen;
for(i=0;i<u_rrd.max_ds;i++) {
if (i+1 <= uwsgi.numproc) {
rlen = snprintf(ptr, 1+sizeof(UMAX64_STR), ":%llu", (unsigned long long )uwsgi.workers[1+i].requests);
if (rlen < 2) return;
}
else {
memcpy(ptr, ":U", 2);
rlen = 2;
}
ptr+=rlen;
}
last_update = uwsgi.current_time;
argv[0] = "update";
argv[2] = u_rrd.update_area;
while(usl) {
argv[1] = usl->value;
if (u_rrd.update(3, argv)) {
uwsgi_log_verbose("ERROR: rrd_update(\"%s\", \"%s\")\n", argv[1], argv[2]);
}
usl = usl->next;
}
}
}
struct uwsgi_plugin rrdtool_plugin = {
.options = rrdtool_options,
.manage_opt = rrdtool_opt,
.master_cycle = rrdtool_master_cycle,
.post_init = rrdtool_post_init,
.init = rrdtool_init,
};
+7
View File
@@ -0,0 +1,7 @@
NAME='rrdtool'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['rrdtool']
+24 -6
View File
@@ -124,9 +124,18 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
base = ptr;
while (ptr < watermark) {
if (*ptr == '?' && !query_string) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) {
wsgi_req->path_info = watermark;
wsgi_req->path_info_len = ptr - base;
http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info);
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len);
}
else {
uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n");
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
}
wsgi_req->path_info_pos = 3;
query_string = ptr + 1;
}
@@ -136,9 +145,18 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
wsgi_req->uri_len = ptr - base;
if (!query_string) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) {
wsgi_req->path_info = watermark;
wsgi_req->path_info_len = ptr - base;
http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info);
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len);
}
else {
uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n");
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
}
wsgi_req->path_info_pos = 5;
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0);
}
+5 -31
View File
@@ -1,7 +1,7 @@
#ifdef UWSGI_PCRE
#include "uwsgi.h"
void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) {
int uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) {
const char *errstr;
int erroff;
@@ -9,15 +9,17 @@ void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) {
*pattern = pcre_compile( (const char *)re, 0, &errstr, &erroff, NULL);
if (!*pattern) {
uwsgi_log("pcre error: %s at offset %d\n", errstr, erroff);
exit(1);
return -1;
}
*pattern_extra = (pcre_extra *) pcre_study((const pcre*)*pattern, 0, &errstr);
if (!*pattern_extra) {
pcre_free(*pattern);
uwsgi_log("pcre (study) error: %s\n", errstr);
exit(1);
return -1;
}
return 0;
}
@@ -26,32 +28,4 @@ int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject,
return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, NULL, 0 );
}
/*
void uwsgi_regexp_match(regexp, what) {
int ret,i;
for(i=0;i<uwsgi->nroutes;i++) {
ret = pcre_exec(ur->pattern, ur->pattern_extra, wsgi_req->path_info, wsgi_req->path_info_len, 0, 0, wsgi_req->ovector, (ur->args+1)*3 );
if (ret >= 0) {
if (ur->action) {
ur->action(uwsgi, wsgi_req, ur);
}
else {
uwsgi_route_action_wsgi(uwsgi, wsgi_req, ur);
}
}
// TODO check for errors if < 0 && != NO_MATCH
}
return;
}
*/
#endif
+26 -10
View File
@@ -9,6 +9,12 @@ from setuptools.command.install import install
from setuptools.command.install_lib import install_lib
from setuptools.command.build_ext import build_ext
"""
This is a hack allowing you installing uWSGI and uwsgidecorators via pip and easy_install
"""
uwsgi_compiled = False
def get_profile():
profile = os.environ.get('UWSGI_PROFILE','buildconf/default.ini')
if not profile.endswith('.ini'):
@@ -35,26 +41,35 @@ def patch_bin_path(cmd, conf):
class uWSGIBuilder(build_ext):
def run(self):
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
global uwsgi_compiled
if not uwsgi_compiled:
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
uwsgi_compiled = True
class uWSGIInstall(install):
def run(self):
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
global uwsgi_compiled
if not uwsgi_compiled:
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
uwsgi_compiled = True
install.run(self)
class uWSGIInstallLib(install_lib):
def run(self):
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
global uwsgi_compiled
if not uwsgi_compiled:
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
uwsgi_compiled = True
install_lib.run(self)
class uWSGIDistribution(Distribution):
@@ -71,6 +86,7 @@ setup(name='uWSGI',
author_email='info@unbit.it',
url='http://projects.unbit.it/uwsgi/',
license='GPL2',
py_modules = ['uwsgidecorators'],
distclass = uWSGIDistribution,
)
+42 -1
View File
@@ -30,6 +30,13 @@ int uwsgi_signal_handler(uint8_t sig) {
set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]);
}
}
#ifdef UWSGI_SPOOLER
else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->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);
@@ -39,12 +46,19 @@ int uwsgi_signal_handler(uint8_t sig) {
set_harakiri(0);
}
}
if (uwsgi.muleid > 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);
}
}
#ifdef UWSGI_SPOOLER
else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) {
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(0);
}
}
#endif
return ret;
}
@@ -221,6 +235,7 @@ void uwsgi_route_signal(uint8_t sig) {
else if (!strcmp(use->receiver, "subscribed")) {
}
// route to spooler
#ifdef UWSGI_SPOOLER
else if (!strcmp(use->receiver, "spooler")) {
if (ushared->worker_signal_pipe[0] != -1) {
if (write(ushared->spooler_signal_pipe[0], &sig, 1) != 1) {
@@ -229,6 +244,7 @@ void uwsgi_route_signal(uint8_t sig) {
}
}
}
#endif
else if (!strcmp(use->receiver, "mules")) {
for(i=0;i<uwsgi.mules_cnt;i++) {
if (write(uwsgi.mules[i].signal_pipe[0], &sig, 1) != 1) {
@@ -255,6 +271,31 @@ void uwsgi_route_signal(uint8_t sig) {
}
}
}
else if (!strncmp(use->receiver, "farm_", 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 (write(uf->signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
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);
if (i > uwsgi.farms_cnt || i <= 0) {
uwsgi_log("invalid signal target: %s\n", use->receiver);
}
else {
if (write(uwsgi.farms[i-1].signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
uwsgi_log("could not deliver signal %d to farm %d (%s)\n", sig, i, uwsgi.farms[i-1].name);
}
}
}
else {
// unregistered signal, sending it to all the workers
uwsgi_log("^^^ UNSUPPORTED SIGNAL TARGET: %s ^^^\n", use->receiver);
+7 -1
View File
@@ -16,7 +16,7 @@ pid_t spooler_start() {
int i;
pid_t pid = fork();
pid_t pid = uwsgi_fork("uWSGI spooler");
if (pid < 0) {
uwsgi_error("fork()");
exit(1);
@@ -413,7 +413,13 @@ void spooler_manage_task(char *dir, char *task) {
for(i=0;i<0xff;i++) {
if (uwsgi.p[i]->spooler) {
time_t now = time(NULL);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
}
ret = uwsgi.p[i]->spooler(task, spool_buf, uh.pktsize, body, body_len);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(0);
}
if (body) {
free(body);
}
+274
View File
@@ -0,0 +1,274 @@
#include "uwsgi.h"
/*
subscription subsystem
each subscription slot is as an auto-optmizing linked list. Originally it was a uwsgi_dict (now removed from uWSGI) but this
would have not be able to support regexp as keys.
each slot has another circular linked list containing the nodes names
the structure and system is very similar to uwsgi_dyn_dict already used by the mime type parser
This system is not mean to run on shared memory. If you have multiple processes for the same app, you have to create
a new subscriptions slot list.
*/
struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen, int regexp) {
struct uwsgi_subscribe_slot *current_slot = *slot;
if (keylen > 0xff) return NULL;
while(current_slot) {
#ifdef UWSGI_PCRE
if (regexp) {
if (uwsgi_regexp_match(current_slot->pattern, current_slot->pattern_extra, key, keylen) >= 0) {
return current_slot;
}
}
else {
#endif
if (!uwsgi_strncmp(key, keylen, current_slot->key, current_slot->keylen)) {
// auto optimization
if (current_slot->prev) {
if (current_slot->hits > current_slot->prev->hits) {
struct uwsgi_subscribe_slot *slot_parent = current_slot->prev->prev, *slot_prev = current_slot->prev;
if (slot_parent) {
slot_parent->next = current_slot;
}
else {
*slot = current_slot;
}
slot_prev->prev = current_slot;
slot_prev->next = current_slot->next;
current_slot->next = slot_prev;
current_slot->prev = slot_parent;
}
}
return current_slot;
}
#ifdef UWSGI_PCRE
}
#endif
current_slot = current_slot->next;
}
return NULL;
}
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen, int regexp) {
if (keylen > 0xff) return NULL;
struct uwsgi_subscribe_slot *current_slot = uwsgi_get_subscribe_slot(slot, key, keylen, regexp);
uint64_t rr_pos = 0;
if (current_slot) {
// node found, move up in the list increasing hits
current_slot->hits++;
struct uwsgi_subscribe_node *node = current_slot->nodes;
while(node) {
if (rr_pos == current_slot->rr) {
current_slot->rr++;
return node;
}
node = node->next;
rr_pos++;
}
current_slot->rr = 0;
return current_slot->nodes;
}
return NULL;
}
void uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi_subscribe_node *node) {
struct uwsgi_subscribe_node *a_node;
struct uwsgi_subscribe_slot *node_slot = node->slot;
struct uwsgi_subscribe_slot *prev_slot = node_slot->prev;
struct uwsgi_subscribe_slot *next_slot = node_slot->next;
// over-engineering to avoid race conditions
node->len = 0;
if (node == node_slot->nodes) {
node_slot->nodes = node->next;
}
else {
a_node = node_slot->nodes;
while(a_node) {
if (a_node->next == node) {
a_node->next = node->next;
break;
}
a_node = a_node->next;
}
}
free(node);
// no more nodes, remove the slot too
if (node_slot->nodes == NULL) {
if (prev_slot) {
prev_slot->next = next_slot;
}
if (next_slot) {
next_slot->prev = prev_slot;
}
#ifdef UWSGI_PCRE
if (node_slot->pattern) {
pcre_free(node_slot->pattern);
}
if (node_slot->pattern_extra) {
pcre_free(node_slot->pattern_extra);
}
#endif
free(node_slot);
// am i the only slot ?
if (!prev_slot && !next_slot) {
*slot = NULL;
}
}
}
struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slot **slot, struct uwsgi_subscribe_req *usr, int regexp) {
struct uwsgi_subscribe_slot *current_slot = uwsgi_get_subscribe_slot(slot, usr->key, usr->keylen, 0), *old_slot = NULL, *a_slot;
struct uwsgi_subscribe_node *node, *old_node = NULL;
if (usr->address_len > 0xff) return NULL;
if (current_slot) {
node = current_slot->nodes;
while(node) {
if (!uwsgi_strncmp(node->name, node->len, usr->address, usr->address_len)) {
node->last_check = time(NULL);
return node;
}
old_node = node;
node = node->next;
}
node = uwsgi_malloc(sizeof(struct uwsgi_subscribe_node));
node->len = usr->address_len;
node->modifier1 = usr->modifier1;
node->modifier2 = usr->modifier2;
node->last_check = time(NULL);
node->slot = current_slot;
memcpy(node->name, usr->address, usr->address_len);
if (old_node) {
old_node->next = node;
}
node->next = NULL;
uwsgi_log("[uwsgi-subscription] %.*s => new node: %.*s\n", usr->keylen, usr->key, usr->address_len, usr->address);
return node;
}
else {
current_slot = uwsgi_malloc(sizeof(struct uwsgi_subscribe_slot));
current_slot->keylen = usr->keylen;
memcpy(current_slot->key, usr->key, usr->keylen);
current_slot->key[usr->keylen] = 0;
current_slot->hits = 0;
current_slot->rr = 0;
#ifdef UWSGI_PCRE
current_slot->pattern = NULL;
current_slot->pattern_extra = NULL;
if (regexp) {
if (uwsgi_regexp_build(current_slot->key, &current_slot->pattern, &current_slot->pattern_extra)) {
free(current_slot);
return NULL;
}
}
#endif
current_slot->nodes = uwsgi_malloc(sizeof(struct uwsgi_subscribe_node));
current_slot->nodes->slot = current_slot;
current_slot->nodes->len = usr->address_len;
current_slot->nodes->modifier1 = usr->modifier1;
current_slot->nodes->modifier2 = usr->modifier2;
memcpy(current_slot->nodes->name, usr->address, usr->address_len);
current_slot->nodes->last_check = time(NULL);
current_slot->nodes->next = NULL;
#ifdef UWSGI_PCRE
// if key is a regexp, order it by keylen
if (regexp) {
old_slot = NULL;
a_slot = *slot;
while(a_slot) {
if (a_slot->keylen > current_slot->keylen) {
old_slot = a_slot;
break;
}
a_slot = a_slot->next;
}
if (old_slot) {
current_slot->prev = old_slot->prev;
old_slot->prev = current_slot;
if (current_slot->prev) {
old_slot->prev->next = current_slot;
}
current_slot->next = old_slot;
}
else {
a_slot = *slot;
while(a_slot) {
old_slot = a_slot;
a_slot = a_slot->next;
}
if (old_slot) {
old_slot->next = current_slot;
}
current_slot->prev = old_slot;
current_slot->next = NULL;
}
}
else {
#endif
a_slot = *slot;
while(a_slot) {
old_slot = a_slot;
a_slot = a_slot->next;
}
if (old_slot) {
old_slot->next = current_slot;
}
current_slot->prev = old_slot;
current_slot->next = NULL;
#ifdef UWSGI_PCRE
}
#endif
if (!*slot || current_slot->prev == NULL) {
*slot = current_slot;
}
uwsgi_log("[uwsgi-subscription] new pool: %.*s\n", usr->keylen, usr->key);
uwsgi_log("[uwsgi-subscription] %.*s => new node: %.*s\n", usr->keylen, usr->key, usr->address_len, usr->address);
return current_slot->nodes;
}
}
+237 -139
View File
@@ -2,6 +2,7 @@
extern struct uwsgi_server uwsgi;
extern char **environ;
/* statistically ordered */
struct http_status_codes hsc[] = {
@@ -121,6 +122,20 @@ void set_mule_harakiri(int sec) {
}
}
#ifdef UWSGI_SPOOLER
void set_spooler_harakiri(int sec) {
if (sec == 0) {
uwsgi.shared->spooler_harakiri = 0;
}
else {
uwsgi.shared->spooler_harakiri = time(NULL) + sec;
}
if (!uwsgi.master_process) {
alarm(sec);
}
}
#endif
void daemonize(char *logfile) {
pid_t pid;
@@ -231,8 +246,8 @@ void logto(char *logfile) {
uwsgi_error_open(logfile);
exit(1);
}
#ifdef UWSGI_UDP
uwsgi.logfile = logfile;
#ifdef UWSGI_UDP
}
#endif
@@ -256,61 +271,6 @@ void logto(char *logfile) {
#ifdef UWSGI_ZEROMQ
void log_zeromq(char *node) {
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, uwsgi.shared->worker_log_pipe)) {
uwsgi_error("socketpair()\n");
exit(1);
}
uwsgi_socket_nb(uwsgi.shared->worker_log_pipe[0]);
uwsgi_socket_nb(uwsgi.shared->worker_log_pipe[1]);
#ifdef UWSGI_DEBUG
int so_bufsize;
socklen_t so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[0], SOL_SOCKET, SO_RCVBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("master logger SO_RCVBUF size: %d\n", so_bufsize);
}
so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[0], SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("master logger SO_SNDBUF size: %d\n", so_bufsize);
}
so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[1], SOL_SOCKET, SO_RCVBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("worker logger SO_RCVBUF size: %d\n", so_bufsize);
}
so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[1], SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("worker logger SO_SNDBUF size: %d\n", so_bufsize);
}
#endif
if (uwsgi.shared->worker_log_pipe[1] != 1) {
if (dup2(uwsgi.shared->worker_log_pipe[1], 1) < 0) {
uwsgi_error("dup2()");
exit(1);
}
}
if (dup2(1, 2) < 0) {
uwsgi_error("dup2()");
exit(1);
}
void *ctx = zmq_init(1);
if (ctx == NULL) {
uwsgi_error("zmq_init()");
@@ -350,10 +310,6 @@ void log_socket(char *socket_name) {
uwsgi_nuclear_blast();
}
// create log connection with the master
create_logpipe();
}
void create_logpipe(void) {
@@ -388,71 +344,12 @@ void log_syslog(char *syslog_opts) {
syslog_opts = "uwsgi";
}
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, uwsgi.shared->worker_log_pipe)) {
uwsgi_error("socketpair()\n");
exit(1);
}
uwsgi_socket_nb(uwsgi.shared->worker_log_pipe[0]);
uwsgi_socket_nb(uwsgi.shared->worker_log_pipe[1]);
#ifdef UWSGI_DEBUG
int so_bufsize;
uwsgi_log("log pipe %d %d\n", uwsgi.shared->worker_log_pipe[0], uwsgi.shared->worker_log_pipe[1]);
socklen_t so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[0], SOL_SOCKET, SO_RCVBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("master logger SO_RCVBUF size: %d\n", so_bufsize);
}
so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[0], SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("master logger SO_SNDBUF size: %d\n", so_bufsize);
}
so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[1], SOL_SOCKET, SO_RCVBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("worker logger SO_RCVBUF size: %d\n", so_bufsize);
}
so_bufsize_len = sizeof(int);
if (getsockopt(uwsgi.shared->worker_log_pipe[1], SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
else {
uwsgi_debug("worker logger SO_SNDBUF size: %d\n", so_bufsize);
}
#endif
if (uwsgi.shared->worker_log_pipe[1] != 1) {
if (dup2(uwsgi.shared->worker_log_pipe[1], 1) < 0) {
uwsgi_error("dup2()");
exit(1);
}
}
#ifdef UWSGI_DEBUG
uwsgi_log("opening syslog\n");
#endif
if (dup2(1, 2) < 0) {
uwsgi_error("dup2()");
exit(1);
}
openlog(syslog_opts, 0, LOG_DAEMON);
}
char *uwsgi_get_cwd() {
@@ -738,7 +635,7 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
int waitpid_status;
int tmp_id;
uint64_t tmp_rt;
uint64_t tmp_rt, rss = 0, vsz = 0;
gettimeofday(&wsgi_req->end_of_request, NULL);
@@ -748,8 +645,11 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
uwsgi.workers[uwsgi.mywid].avg_response_time = (uwsgi.workers[uwsgi.mywid].avg_response_time+tmp_rt)/2;
// get memory usage
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.force_get_memusage )
get_memusage();
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.force_get_memusage ) {
get_memusage(&rss, &vsz);
uwsgi.workers[uwsgi.mywid].vsz_size = vsz;
uwsgi.workers[uwsgi.mywid].rss_size = rss;
}
// close the connection with the webserver
@@ -798,11 +698,11 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
goodbye_cruel_world();
}
if (uwsgi.reload_on_as && (rlim_t) uwsgi.workers[uwsgi.mywid].vsz_size >= uwsgi.reload_on_as) {
if (uwsgi.reload_on_as && (rlim_t) vsz >= uwsgi.reload_on_as) {
goodbye_cruel_world();
}
if (uwsgi.reload_on_rss && (rlim_t) uwsgi.workers[uwsgi.mywid].rss_size >= uwsgi.reload_on_rss) {
if (uwsgi.reload_on_rss && (rlim_t) rss >= uwsgi.reload_on_rss) {
goodbye_cruel_world();
}
@@ -1697,24 +1597,45 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
return 0;
}
void add_exported_option(char *key, char *value, int configured) {
void _add_exported_option(char *key, char *value, int configured) {
if (!uwsgi.exported_opts) {
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt *));
}
else {
uwsgi.exported_opts = realloc(uwsgi.exported_opts, sizeof(struct uwsgi_opt *) * (uwsgi.exported_opts_cnt + 1));
if (!uwsgi.exported_opts) {
uwsgi_error("realloc()");
exit(1);
}
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt *));
}
else {
uwsgi.exported_opts = realloc(uwsgi.exported_opts, sizeof(struct uwsgi_opt *) * (uwsgi.exported_opts_cnt + 1));
if (!uwsgi.exported_opts) {
uwsgi_error("realloc()");
exit(1);
}
}
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
uwsgi.exported_opts_cnt++;
}
void add_exported_option(char *key, char *value, int configured) {
char *v = value;
if (value && strchr(value, ';')) {
v = uwsgi_str(value);
}
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
uwsgi.exported_opts_cnt++;
if (v == NULL) {
_add_exported_option(key, v, configured);
return;
}
char *p = strtok(v, ";");
while(p != NULL) {
_add_exported_option(key, p, configured);
p = strtok(NULL, ";");
}
}
@@ -2225,8 +2146,13 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
char *a;
int cnt = 1;
int devnull = -1;
int throttle = 0;
pid_t pid = fork();
if (uwsgi.current_time - ud->last_spawn <= 3) {
throttle = ud->respawns - (uwsgi.current_time-ud->last_spawn);
}
pid_t pid = uwsgi_fork("uWSGI external daemon");
if (pid < 0) {
uwsgi_error("fork()");
return;
@@ -2289,6 +2215,12 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
argv[cnt] = NULL;
if (throttle) {
uwsgi_log_verbose("throttling %s for %d seconds\n", argv[0], throttle);
sleep(throttle);
}
uwsgi_log_verbose("running %s\n", argv[0]);
if (execvp(argv[0], argv)) {
uwsgi_error("execvp()");
}
@@ -2417,6 +2349,37 @@ int uwsgi_list_has_str(char *list, char *str) {
return 0;
}
char hex2num(char *str) {
char val = 0;
val <<= 4;
if (str[0] >= '0' && str[0] <= '9') {
val += str[0] & 0x0F;
}
else if ( str[0] >= 'A' && str[0] <= 'F') {
val += (str[0] & 0x0F) + 9;
}
else {
return 0;
}
val <<= 4;
if (str[1] >= '0' && str[1] <= '9') {
val += str[1] & 0x0F;
}
else if ( str[1] >= 'A' && str[1] <= 'F') {
val += (str[1] & 0x0F) + 9;
}
else {
return 0;
}
return val;
}
int uwsgi_str2_num(char *str) {
int num = 0;
@@ -2603,6 +2566,22 @@ struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **dd, char *key,
return uwsgi_dd;
}
void uwsgi_dyn_dict_del(struct uwsgi_dyn_dict *item) {
struct uwsgi_dyn_dict *prev = item->prev;
struct uwsgi_dyn_dict *next = item->next;
if (prev) {
prev->next = next;
}
if (next) {
next->prev = prev;
}
free(item);
}
struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list, char *value) {
@@ -3187,3 +3166,122 @@ void uwsgi_apply_config_pass(char symbol, char*(*hook)(char *) ) {
}
}
void uwsgi_set_processname(char *name) {
#if defined(__linux__) || defined(__sun__)
size_t amount = 0;
// prepare for strncat
*uwsgi.orig_argv[0] = 0;
if (uwsgi.procname_prefix) {
amount += strlen(uwsgi.procname_prefix);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], uwsgi.procname_prefix, uwsgi.max_procname-(amount+1));
}
amount += strlen(name);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], name, (uwsgi.max_procname-amount+1));
if (uwsgi.procname_append) {
amount += strlen(uwsgi.procname_append);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], uwsgi.procname_append, uwsgi.max_procname-(amount+1));
}
memset(uwsgi.orig_argv[0]+amount+1, ' ', uwsgi.max_procname-(amount-1));
#elif defined(__FreeBSD__)
if (uwsgi.procname_prefix) {
if (!uwsgi.procname_append) {
setproctitle("-%s%s", uwsgi.procname_prefix, name);
}
else {
setproctitle("-%s%s%s", uwsgi.procname_prefix, name, uwsgi.procname_append);
}
}
else if (uwsgi.procname_append) {
if (!uwsgi.procname_prefix) {
setproctitle("-%s%s", name, uwsgi.procname_append);
}
else {
setproctitle("-%s%s%s", uwsgi.procname_prefix, name, uwsgi.procname_append);
}
}
else {
setproctitle("-%s", name);
}
#endif
}
// this is a wrapper for fork restoring original argv
pid_t uwsgi_fork(char *name) {
pid_t pid = fork();
if (pid == 0) {
#if defined(__linux__) || defined(__sun__)
int i;
for(i=0;i<uwsgi.argc;i++) {
strcpy(uwsgi.orig_argv[i],uwsgi.argv[i]);
}
#endif
if (uwsgi.auto_procname && name) {
if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else {
uwsgi_set_processname(name);
}
}
}
return pid;
}
void http_url_decode(char *buf, uint16_t *len, char *dst) {
uint16_t i;
int percent = 0;
char value[2];
size_t new_len = 0;
char *ptr = dst;
value[0] = '0';
value[1] = '0';
for(i=0;i<*len;i++) {
if (buf[i] == '%') {
if (percent == 0) {
percent = 1;
}
else {
*ptr++= '%';
new_len++;
percent = 0;
}
}
else {
if (percent == 1) {
value[0] = buf[i];
percent = 2;
}
else if (percent == 2) {
value[1] = buf[i];
*ptr++= hex2num(value);
percent = 0;
new_len++;
}
else {
*ptr++= buf[i];
new_len++;
}
}
}
*len = new_len;
}
+283 -58
View File
@@ -1,5 +1,5 @@
/*
_socket_nb(uwsgi.shared->worker_log_pipe[1]
*** uWSGI ***
Copyright (C) 2009-2011 Unbit S.a.s. <info@unbit.it>
@@ -70,6 +70,7 @@ static struct option long_base_options[] = {
{"abstract-socket", no_argument, 0, 'a'},
{"chmod-socket", optional_argument, 0, 'C'},
{"chown-socket", required_argument, 0, LONG_ARGS_CHOWN_SOCKET},
{"umask", required_argument, 0, LONG_ARGS_UMASK},
#ifdef __linux__
{"freebind", no_argument, &uwsgi.freebind, 1},
#endif
@@ -78,6 +79,12 @@ static struct option long_base_options[] = {
#ifdef UWSGI_THREADING
{"enable-threads", no_argument, 0, 'T'},
#endif
{"auto-procname", no_argument, &uwsgi.auto_procname, 1},
{"procname-prefix", required_argument, 0, LONG_ARGS_PROCNAME_PREFIX},
{"procname-prefix-spaced", required_argument, 0, LONG_ARGS_PROCNAME_PREFIX_SP},
{"procname-append", required_argument, 0, LONG_ARGS_PROCNAME_APPEND},
{"procname", required_argument, 0, LONG_ARGS_PROCNAME},
{"procname-master", required_argument, 0, LONG_ARGS_PROCNAME_MASTER},
{"single-interpreter", no_argument, 0, 'i'},
{"master", no_argument, 0, 'M'},
{"emperor", required_argument, 0, LONG_ARGS_EMPEROR},
@@ -121,6 +128,8 @@ static struct option long_base_options[] = {
{"spooler-chdir", required_argument, 0, LONG_ARGS_SPOOLER_CHDIR},
#endif
{"mule", optional_argument, 0, LONG_ARGS_MULE},
{"mules", required_argument, 0, LONG_ARGS_MULES},
{"farm", required_argument, 0, LONG_ARGS_FARM},
{"disable-logging", no_argument, 0, 'L'},
{"pidfile", required_argument, 0, LONG_ARGS_PIDFILE},
@@ -510,7 +519,7 @@ void kill_them_all(int signum) {
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi_log("killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
uwsgi_log("killing the spooler with pid %d\n", uwsgi.shared->spooler_pid);
}
#endif
@@ -518,7 +527,7 @@ void kill_them_all(int signum) {
if (uwsgi.emperor_pid >= 0) {
kill(uwsgi.emperor_pid, SIGKILL);
waitpid(uwsgi.emperor_pid, &i, 0);
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid);
}
@@ -560,14 +569,14 @@ void grace_them_all(int signum) {
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi_log("killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
uwsgi_log("killing the spooler with pid %d\n", uwsgi.shared->spooler_pid);
}
#endif
if (uwsgi.emperor_pid >= 0) {
kill(uwsgi.emperor_pid, SIGKILL);
waitpid(uwsgi.emperor_pid, &i, 0);
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid);
}
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
@@ -653,6 +662,7 @@ void reap_them_all(int signum) {
}
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (!uwsgi.mules) break;
if (uwsgi.mules[i].pid > 0)
kill(uwsgi.mules[i].pid, SIGKILL);
}
@@ -660,7 +670,7 @@ void reap_them_all(int signum) {
if (uwsgi.emperor_pid >= 0) {
kill(uwsgi.emperor_pid, SIGKILL);
waitpid(uwsgi.emperor_pid, &i, 0);
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid);
}
if (!uwsgi.workers)
@@ -847,6 +857,56 @@ void signal_pidfile(int sig, char *filename) {
}
}
void fixup_argv_and_environ(int argc, char **argv, char **environ) {
uwsgi.orig_argv = argv;
uwsgi.argv = argv;
uwsgi.argc = argc;
uwsgi.environ = environ;
#if defined(__linux__) || defined(__sun__)
int i;
int env_count = 0;
uwsgi.argv = uwsgi_malloc( sizeof(char *) * argc);
for(i=0;i<argc;i++) {
if (i==0 || argv[0] + uwsgi.max_procname + 1 == argv[i]) {
uwsgi.max_procname += strlen(argv[i]) + 1;
}
uwsgi.argv[i] = strdup(argv[i]);
}
uwsgi.max_procname++;
for (i = 0; environ[i] != NULL; i++) {
// useless
//if ((environ[0] + uwsgi.max_procname + 1) == environ[i]) {
uwsgi.max_procname += strlen(environ[i]) + 1;
//}
env_count++;
}
uwsgi.environ = uwsgi_malloc(sizeof(char *) * env_count);
for(i=0;i<env_count;i++) {
uwsgi.environ[i] = strdup(environ[i]);
#ifdef UWSGI_DEBUG
uwsgi_log("ENVIRON: %s\n", uwsgi.environ[i]);
#endif
environ[i] = uwsgi.environ[i];
}
#ifdef UWSGI_DEBUG
uwsgi_log("max space for custom process name = %d\n", uwsgi.max_procname);
#endif
//environ = uwsgi.environ;
#endif
}
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int argc, char *argv[], char *envp[]) {
@@ -886,6 +946,7 @@ int main(int argc, char *argv[], char *envp[]) {
signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
//initialize masterpid with a default value
masterpid = getpid();
@@ -934,6 +995,8 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.cache_server_fd = -1;
uwsgi.stats_fd = -1;
uwsgi.original_log_fd = -1;
uwsgi.emperor_fd_config = -1;
uwsgi.emperor_throttle = 1000;
uwsgi.emperor_pid = -1;
@@ -962,6 +1025,12 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.shared->mule_signal_pipe[0] = -1;
uwsgi.shared->mule_signal_pipe[1] = -1;
uwsgi.shared->mule_queue_pipe[0] = -1;
uwsgi.shared->mule_queue_pipe[1] = -1;
uwsgi.shared->worker_log_pipe[0] = -1;
uwsgi.shared->worker_log_pipe[1] = -1;
uwsgi.mime_file = "/etc/mime.types";
@@ -1024,6 +1093,9 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.page_size = getpagesize();
uwsgi.binary_path = uwsgi_get_binary_path(argv[0]);
// ok we can now safely play with argv and environ
fixup_argv_and_environ(argc, argv, environ);
//initialize embedded plugins
UWSGI_LOAD_EMBEDDED_PLUGINS
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
@@ -1067,7 +1139,7 @@ int main(int argc, char *argv[], char *envp[]) {
#endif
uwsgi.option_index = -1;
while ((i = getopt_long(argc, argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
if (uwsgi.option_index > -1) {
optname = (char *) uwsgi.long_options[uwsgi.option_index].name;
@@ -1077,7 +1149,7 @@ int main(int argc, char *argv[], char *envp[]) {
}
// is this a flagged option ?
if (i == 0) {
add_exported_option(optname, "1", 0);
add_exported_option(optname, strdup("1"), 0);
}
else {
add_exported_option(optname, optarg, 1);
@@ -1091,8 +1163,8 @@ int main(int argc, char *argv[], char *envp[]) {
#endif
if (optind < argc) {
for(i=optind;i<argc;i++) {
char *lazy = argv[i];
for(i=optind;i<uwsgi.argc;i++) {
char *lazy = uwsgi.argv[i];
if (lazy[0] != '[') {
if (0) {
}
@@ -1119,6 +1191,9 @@ int main(int argc, char *argv[], char *envp[]) {
else if (!strcmp(lazy + strlen(lazy) - 3, ".js")) {
uwsgi.json = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 5, ".json")) {
uwsgi.json = lazy;
}
#endif
#ifdef UWSGI_SQLITE3
else if (!strcmp(lazy + strlen(lazy) - 3, ".db")) {
@@ -1159,7 +1234,6 @@ int main(int argc, char *argv[], char *envp[]) {
}
}
struct uwsgi_string_list *config_file;
#ifdef UWSGI_XML
if (uwsgi.xml_config != NULL) {
@@ -1169,6 +1243,7 @@ int main(int argc, char *argv[], char *envp[]) {
}
#endif
#ifdef UWSGI_INI
struct uwsgi_string_list *config_file;
if (uwsgi.ini != NULL) {
config_file = uwsgi.ini;
while(config_file) {
@@ -1230,6 +1305,9 @@ int main(int argc, char *argv[], char *envp[]) {
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".js")) {
uwsgi_json_config(uct->filename, uwsgi.magic_table);
}
if (!strcmp(uct->filename + strlen(uct->filename) - 5, ".json")) {
uwsgi_json_config(uct->filename, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_SQLITE3
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".db")) {
@@ -1258,6 +1336,11 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_configure();
if (uwsgi.log_master) {
uwsgi.original_log_fd = dup(1);
create_logpipe();
}
/* uWSGI IS CONFIGURED !!! */
if (uwsgi.build_mime_dict) {
@@ -1337,8 +1420,8 @@ int main(int argc, char *argv[], char *envp[]) {
//call after_opt hooks
if (uwsgi.binary_path == argv[0]) {
uwsgi.binary_path = uwsgi_str(argv[0]);
if (uwsgi.binary_path == uwsgi.argv[0]) {
uwsgi.binary_path = uwsgi_str(uwsgi.argv[0]);
}
if (!uwsgi.no_initial_output) {
@@ -1433,7 +1516,7 @@ int main(int argc, char *argv[], char *envp[]) {
exit(1);
}
uwsgi.emperor_pid = fork();
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
if (uwsgi.emperor_pid < 0) {
uwsgi_error("pid()");
exit(1);
@@ -1454,7 +1537,7 @@ int main(int argc, char *argv[], char *envp[]) {
// call jail systems
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->jail) {
uwsgi.gp[i]->jail(uwsgi_start, argv);
uwsgi.gp[i]->jail(uwsgi_start, uwsgi.argv);
}
}
@@ -1462,12 +1545,12 @@ int main(int argc, char *argv[], char *envp[]) {
// TODO pluginize basic Linux namespace support
#ifdef __linux__
if (uwsgi.ns) {
linux_namespace_start((void *) argv);
linux_namespace_start((void *) uwsgi.argv);
// never here
}
else {
#endif
uwsgi_start((void *) argv);
uwsgi_start((void *) uwsgi.argv);
#ifdef __linux__
}
#endif
@@ -1479,8 +1562,6 @@ int main(int argc, char *argv[], char *envp[]) {
int uwsgi_start(void *v_argv) {
char **argv = v_argv;
#ifdef UWSGI_DEBUG
int so_bufsize;
socklen_t so_bufsize_len;
@@ -1590,7 +1671,7 @@ int uwsgi_start(void *v_argv) {
exit(1);
}
uwsgi.emperor_pid = fork();
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
if (uwsgi.emperor_pid < 0) {
uwsgi_error("pid()");
exit(1);
@@ -1705,7 +1786,7 @@ int uwsgi_start(void *v_argv) {
// application generic lock
uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks+1));
for(i=0;i<uwsgi.locks;i++) {
for(i=0;i<uwsgi.locks+1;i++) {
uwsgi.user_lock[i] = uwsgi_mmap_shared_lock();
uwsgi_lock_init(uwsgi.user_lock[i]);
}
@@ -1861,6 +1942,21 @@ int uwsgi_start(void *v_argv) {
continue;
}
if (uwsgi.shared->worker_log_pipe[0] > -1) {
if (j == uwsgi.shared->worker_log_pipe[0])
continue;
}
if (uwsgi.shared->worker_log_pipe[1] > -1) {
if (j == uwsgi.shared->worker_log_pipe[1])
continue;
}
if (uwsgi.original_log_fd > -1) {
if (j == uwsgi.original_log_fd)
continue;
}
if (uwsgi.cache_server && uwsgi.cache_server_fd != -1) {
if (j == uwsgi.cache_server_fd)
continue;
@@ -2154,6 +2250,7 @@ skipzero:
for(i=1;i<=uwsgi.numproc;i++) {
uwsgi.workers[i].signal_pipe[0] = - 1;
uwsgi.workers[i].signal_pipe[1] = - 1;
snprintf(uwsgi.workers[i].name, 0xff, "uWSGI worker %d", i);
}
if (uwsgi.master_process) {
@@ -2183,6 +2280,11 @@ skipzero:
exit(1);
}
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, uwsgi.shared->mule_queue_pipe)) {
uwsgi_error("socketpair()");
exit(1);
}
for(i=0;i<uwsgi.mules_cnt;i++) {
// create the socket pipe
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.mules[i].signal_pipe)) {
@@ -2193,9 +2295,68 @@ skipzero:
uwsgi_error("socketpair()");
exit(1);
}
uwsgi.mules[i].id = i+1;
snprintf(uwsgi.mules[i].name, 0xff, "uWSGI mule %d", i+1);
}
}
if (uwsgi.farms_cnt > 0) {
uwsgi.farms = (struct uwsgi_farm *) mmap(NULL, sizeof(struct uwsgi_farm) * uwsgi.farms_cnt, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.farms) {
uwsgi_error("mmap()");
exit(1);
}
memset(uwsgi.farms, 0, sizeof(struct uwsgi_farm) * uwsgi.farms_cnt);
struct uwsgi_string_list *farm_name = uwsgi.farms_list;
for(i=0;i<uwsgi.farms_cnt;i++) {
char *farm_value = uwsgi_str(farm_name->value);
char *mules_list = strchr(farm_value, ':');
if (!mules_list) {
uwsgi_log("invalid farm value (%s) must be in the form name:mule[,muleN].\n", farm_value);
exit(1);
}
mules_list[0] = 0;
mules_list++;
strncpy(uwsgi.farms[i].name, farm_value, 0xff);
// create the socket pipe
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.farms[i].signal_pipe)) {
uwsgi_error("socketpair()\n");
}
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, uwsgi.farms[i].queue_pipe)) {
uwsgi_error("socketpair()");
exit(1);
}
char *p = strtok(mules_list, ",");
while(p != NULL) {
struct uwsgi_mule *um = get_mule_by_id( atoi( p ) );
if (!um) {
uwsgi_log("invalid mule id: %s\n", p);
exit(1);
}
uwsgi_mule_farm_new(&uwsgi.farms[i].mules, um);
p = strtok(NULL, ",");
}
uwsgi_log("created farm %d name: %s mules:%s\n", i+1, uwsgi.farms[i].name, strchr(farm_name->value, ':')+1);
farm_name = farm_name->next;
}
}
/*
uwsgi.shared->hooks[0] = uwsgi_request_wsgi;
@@ -2370,15 +2531,14 @@ skipzero:
}
}
if (getpid() == masterpid && uwsgi.master_process == 1) {
#ifdef UWSGI_AS_SHARED_LIBRARY
int ml_ret = master_loop(argv, environ);
int ml_ret = master_loop(uwsgi.argv, uwsgi.environ);
if (ml_ret == -1) {
return 0;
}
#else
(void) master_loop(argv, environ);
(void) master_loop(uwsgi.argv, uwsgi.environ);
#endif
//from now on the process is a real worker
}
@@ -2794,11 +2954,32 @@ static int manage_base_opt(int i, char *optarg) {
struct uwsgi_cron *uc, *old_uc;
struct uwsgi_socket *uwsgi_sock = NULL;
int zerg_fd;
mode_t umask_mode;
switch (i) {
case 0:
return 1;
case LONG_ARGS_PROCNAME_PREFIX:
uwsgi.auto_procname = 1;
uwsgi.procname_prefix = optarg;
return 1;
case LONG_ARGS_PROCNAME_PREFIX_SP:
uwsgi.auto_procname = 1;
uwsgi.procname_prefix = uwsgi_concat2(optarg, " ");
return 1;
case LONG_ARGS_PROCNAME_APPEND:
uwsgi.auto_procname = 1;
uwsgi.procname_append = optarg;
return 1;
case LONG_ARGS_PROCNAME:
uwsgi.auto_procname = 1;
uwsgi.procname = optarg;
return 1;
case LONG_ARGS_PROCNAME_MASTER:
uwsgi.auto_procname = 1;
uwsgi.procname_master = optarg;
return 1;
#ifdef UWSGI_UDP
case LONG_ARGS_CLUSTER_RELOAD:
send_udp_message(98, optarg, "", 0);
@@ -2930,10 +3111,6 @@ static int manage_base_opt(int i, char *optarg) {
uwsgi.lazy = 1;
return 1;
case LONG_ARGS_LOG_MAXSIZE:
if (!uwsgi.log_master) {
uwsgi.original_log_fd = dup(1);
create_logpipe();
}
uwsgi.log_master = 1;
uwsgi.log_maxsize = atoi(optarg);
return 1;
@@ -2941,10 +3118,6 @@ static int manage_base_opt(int i, char *optarg) {
uwsgi.log_backupname = optarg;
return 1;
case LONG_ARGS_LOG_MASTER:
if (!uwsgi.log_master) {
uwsgi.original_log_fd = dup(1);
create_logpipe();
}
uwsgi.log_master = 1;
return 1;
case LONG_ARGS_LOG_SOCKET:
@@ -3212,13 +3385,8 @@ static int manage_base_opt(int i, char *optarg) {
}
return 1;
case LONG_ARGS_SUBSCRIBE_TO:
if (uwsgi.subscriptions_cnt < MAX_SUBSCRIPTIONS) {
uwsgi.subscriptions[uwsgi.subscriptions_cnt] = optarg;
uwsgi.subscriptions_cnt++;
}
else {
uwsgi_log("you can specify at most %d --attach-daemons options\n", MAX_SUBSCRIPTIONS);
}
uwsgi.master_process = 1;
uwsgi_string_new_list(&uwsgi.subscriptions, optarg);
return 1;
#ifdef __linux__
case LONG_ARGS_CGROUP:
@@ -3301,6 +3469,18 @@ static int manage_base_opt(int i, char *optarg) {
uwsgi.mules_cnt++;
uwsgi_string_new_list(&uwsgi.mules_patches, optarg);
return 1;
case LONG_ARGS_MULES:
uwsgi.master_process = 1;
for(i=0;i<atoi(optarg);i++) {
uwsgi.mules_cnt++;
uwsgi_string_new_list(&uwsgi.mules_patches, optarg);
}
return 1;
case LONG_ARGS_FARM:
uwsgi.master_process = 1;
uwsgi.farms_cnt++;
uwsgi_string_new_list(&uwsgi.farms_list, optarg);
return 1;
case LONG_ARGS_SOCKET_PROTOCOL:
// TODO map each socket to a specific protocol
return 1;
@@ -3521,12 +3701,14 @@ static int manage_base_opt(int i, char *optarg) {
case 't':
uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] = atoi(optarg);
return 1;
#ifdef UWSGI_SPOOLER
case LONG_ARGS_SPOOLER_HARAKIRI:
uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] = atoi(optarg);
return 1;
case LONG_ARGS_SPOOLER_CHDIR:
uwsgi.spooler_chdir = optarg;
return 1;
#endif
case LONG_ARGS_MULE_HARAKIRI:
uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI] = atoi(optarg);
return 1;
@@ -3549,6 +3731,23 @@ static int manage_base_opt(int i, char *optarg) {
case LONG_ARGS_CHOWN_SOCKET:
uwsgi.chown_socket = optarg;
return 1;
case LONG_ARGS_UMASK:
if (strlen(optarg) < 3) {
uwsgi_log("invalid umask: %s\n", optarg);
}
umask_mode = 0;
if (strlen(optarg) == 3) {
umask_mode = (umask_mode << 3) + (optarg[0] - '0');
umask_mode = (umask_mode << 3) + (optarg[1] - '0');
umask_mode = (umask_mode << 3) + (optarg[2] - '0');
}
else {
umask_mode = (umask_mode << 3) + (optarg[1] - '0');
umask_mode = (umask_mode << 3) + (optarg[2] - '0');
umask_mode = (umask_mode << 3) + (optarg[3] - '0');
}
umask(umask_mode);
return 1;
case 'C':
uwsgi.chmod_socket = 1;
if (optarg) {
@@ -3601,32 +3800,58 @@ static int manage_base_opt(int i, char *optarg) {
return 0;
}
void manage_opt(int i, char *optarg) {
int _manage_opt(int i, char *p) {
int j;
if (manage_base_opt(i, optarg)) {
if (manage_base_opt(i, p)) {
return 1;
}
for (j = 0; j < 0xFF; j++) {
if (uwsgi.p[j]->manage_opt) {
if (uwsgi.p[j]->manage_opt(i, p)) {
return 1;
}
}
}
for (j = 0; j < uwsgi.gp_cnt; j++) {
if (uwsgi.gp[j]->manage_opt) {
if (uwsgi.gp[j]->manage_opt(i, p)) {
return 1;
}
}
}
return 0;
}
void manage_opt(int i, char *optarg) {
char *value = optarg;
if (value && strchr(optarg, ';')) {
value = uwsgi_str(optarg);
}
if (!value) {
if (!_manage_opt(i, NULL)) {
exit(1);
}
return;
}
for (j = 0; j < 0xFF; j++) {
if (uwsgi.p[j]->manage_opt) {
if (uwsgi.p[j]->manage_opt(i, optarg)) {
return;
}
}
char *p = strtok(value, ";");
while(p != NULL) {
if (_manage_opt(i, p)) goto next;
exit(1);
next:
p = strtok(NULL, ";");
}
for (j = 0; j < uwsgi.gp_cnt; j++) {
if (uwsgi.gp[j]->manage_opt) {
if (uwsgi.gp[j]->manage_opt(i, optarg)) {
return;
}
}
}
//never here
exit(1);
return;
}
+110 -36
View File
@@ -8,6 +8,8 @@ extern "C" {
#define UMAX16 65536
#define UMAX64_STR "18446744073709551616"
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#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__);
@@ -37,7 +39,6 @@ extern "C" {
#define MAX_RPC 64
#define MAX_GATEWAYS 64
#define MAX_DAEMONS 8
#define MAX_SUBSCRIPTIONS 8
#define MAX_CRONS 64
#ifndef UWSGI_LOAD_EMBEDDED_PLUGINS
@@ -528,6 +529,14 @@ struct uwsgi_opt {
#define LONG_ARGS_EMPEROR_STATS 17150
#define LONG_ARGS_SPOOLER_CHDIR 17151
#define LONG_ARGS_LOCKS 17152
#define LONG_ARGS_PROCNAME_PREFIX 17153
#define LONG_ARGS_PROCNAME_APPEND 17154
#define LONG_ARGS_PROCNAME 17155
#define LONG_ARGS_PROCNAME_MASTER 17156
#define LONG_ARGS_FARM 17157
#define LONG_ARGS_MULES 17158
#define LONG_ARGS_PROCNAME_PREFIX_SP 17159
#define LONG_ARGS_UMASK 17160
#define UWSGI_OK 0
@@ -651,6 +660,7 @@ struct uwsgi_plugin {
void (*init_apps) (void);
void (*fixup) (void);
void (*master_fixup) (int);
void (*master_cycle) (void);
int (*mount_app) (char *, char *, int);
int (*manage_udp) (char *, int, char *, int);
int (*manage_xml) (char *, char *);
@@ -674,13 +684,14 @@ struct uwsgi_plugin {
void (*jail) (int (*)(void *), char **);
int (*mule)(char *);
int (*mule_msg)(char *, size_t);
struct uwsgi_help_item *help;
};
#ifdef UWSGI_PCRE
#include <pcre.h>
void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra);
int uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra);
int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length);
#endif
@@ -966,6 +977,17 @@ struct uwsgi_server {
char hostname[256];
int hostname_len;
char **orig_argv;
char **argv;
int argc;
int max_procname;
int auto_procname;
char **environ;
char *procname_prefix;
char *procname_append;
char *procname_master;
char *procname;
// quiet startup
int no_initial_output;
@@ -1279,12 +1301,15 @@ struct uwsgi_server {
/* the list of mules */
struct uwsgi_string_list *mules_patches;
struct uwsgi_mule *mules;
struct uwsgi_string_list *farms_list;
struct uwsgi_farm *farms;
pid_t mypid;
int mywid;
int muleid;
int mules_cnt;
int farms_cnt;
rlim_t max_fd;
@@ -1494,8 +1519,7 @@ struct uwsgi_server {
int startup_daemons_cnt;
// subscription client
char *subscriptions[MAX_SUBSCRIPTIONS];
int subscriptions_cnt;
struct uwsgi_string_list *subscriptions;
};
@@ -1594,6 +1618,7 @@ struct uwsgi_shared {
#ifdef UWSGI_SPOOLER
pid_t spooler_pid;
int spooler_frequency;
time_t spooler_harakiri;
#endif
#ifdef UWSGI_SNMP
@@ -1616,6 +1641,7 @@ struct uwsgi_shared {
int spooler_signal_pipe[2];
#endif
int mule_signal_pipe[2];
int mule_queue_pipe[2];
struct uwsgi_signal_entry signal_table[256];
@@ -1712,8 +1738,10 @@ struct uwsgi_worker {
uint64_t avg_response_time;
char name[0xff];
};
struct uwsgi_mule {
int id;
pid_t pid;
@@ -1736,6 +1764,23 @@ struct uwsgi_mule {
char name[0xff];
};
struct uwsgi_mule_farm {
struct uwsgi_mule *mule;
struct uwsgi_mule_farm *next;
};
struct uwsgi_farm {
int id;
char name[0xff];
int signal_pipe[2];
int queue_pipe[2];
struct uwsgi_mule_farm *mules;
};
char *uwsgi_get_cwd(void);
@@ -1763,7 +1808,7 @@ void daemonize(char *);
void logto(char *);
void log_request(struct wsgi_request *);
void get_memusage(void);
void get_memusage(uint64_t *, uint64_t *);
void harakiri(void);
void stats(int);
@@ -1787,6 +1832,7 @@ pid_t spooler_start(void);
void set_harakiri(int);
void set_mule_harakiri(int);
void set_spooler_harakiri(int);
void inc_harakiri(int);
#ifdef __BIG_ENDIAN__
@@ -2113,30 +2159,6 @@ struct uwsgi_dict {
struct uwsgi_dict_item *items;
};
#define SUBSCRIBER_PAGESIZE 4096
#define SUBSCRIBER_NODES (SUBSCRIBER_PAGESIZE/128)-4
struct uwsgi_subscriber_name {
uint16_t len;
char name[128];
uint8_t modifier1;
uint8_t modifier2;
// total requests managed by this node
uint64_t requests;
// bytes transferred by this node
uint64_t transferred;
};
struct uwsgi_subscriber {
uint64_t nodes;
uint64_t current;
// support upto md5
char auth[32];
struct uwsgi_subscriber_name names[SUBSCRIBER_NODES];
};
struct uwsgi_subscribe_req {
char *key;
@@ -2152,13 +2174,6 @@ struct uwsgi_subscribe_req {
uint8_t modifier2;
};
struct uwsgi_dict *uwsgi_dict_create(uint64_t, uint64_t);
void uwsgi_add_subscriber(struct uwsgi_dict *, struct uwsgi_subscribe_req *);
char *uwsgi_dict_get(struct uwsgi_dict *, char *, uint16_t, uint64_t *);
int uwsgi_dict_set(struct uwsgi_dict *, char *, uint16_t, char *, uint64_t);
struct uwsgi_subscriber_name *uwsgi_get_subscriber(struct uwsgi_dict *, char *, uint16_t);
#ifndef _NO_UWSGI_RB
#include "lib/rbtree.h"
@@ -2360,6 +2375,7 @@ int uwsgi_simple_parse_vars(struct wsgi_request *, char *, char *);
void uwsgi_build_mime_dict(char *);
struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **, char *, int, char *, int);
void uwsgi_dyn_dict_del(struct uwsgi_dyn_dict *);
void uwsgi_send_stats(int);
@@ -2371,6 +2387,64 @@ char *uwsgi_string_get_list(struct uwsgi_string_list **, int, size_t *);
void uwsgi_fixup_fds(int, int);
void uwsgi_set_processname(char *);
void http_url_decode(char *, uint16_t *, char *);
pid_t uwsgi_fork(char *);
struct uwsgi_mule *get_mule_by_id(int);
struct uwsgi_mule_farm *uwsgi_mule_farm_new(struct uwsgi_mule_farm **, struct uwsgi_mule *);
int uwsgi_farm_has_mule(struct uwsgi_farm *, int);
struct uwsgi_farm *get_farm_by_name(char *);
struct uwsgi_subscribe_slot;
struct uwsgi_subscribe_node {
char name[0xff];
uint16_t len;
uint8_t modifier1;
uint8_t modifier2;
time_t last_check;
uint64_t requests;
uint64_t transferred;
struct uwsgi_subscribe_slot *slot;
struct uwsgi_subscribe_node *next;
};
struct uwsgi_subscribe_slot {
char key[0xff];
uint16_t keylen;
#ifdef UWSGI_PCRE
pcre *pattern;
pcre_extra *pattern_extra;
#endif
uint64_t hits;
// used for round robin
uint64_t rr;
struct uwsgi_subscribe_node *nodes;
struct uwsgi_subscribe_slot *prev;
struct uwsgi_subscribe_slot *next;
};
struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **, char *, uint16_t, int);
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **, char *, uint16_t, int);
void uwsgi_remove_subscribe_node(struct uwsgi_subscribe_slot **, struct uwsgi_subscribe_node *);
struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slot **, struct uwsgi_subscribe_req *, int);
#ifdef UWSGI_CAP
void uwsgi_build_cap(char *);
#endif
+1 -1
View File
@@ -231,7 +231,7 @@ class uConf(object):
ulp.close()
self.config.read(filename)
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify', 'mule',
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify', 'mule', 'subscription',
'plugins', 'lock', 'cache', 'queue', 'event', 'signal', 'rpc', 'gateway', 'loop', 'lib/rbtree', 'lib/amqp', 'rb_timers', 'uwsgi']
# add protocols
self.gcc_list.append('proto/base')
+118
View File
@@ -1,6 +1,12 @@
import uwsgi
from threading import Thread
try:
import cPickle as pickle
except:
import pickle
if uwsgi.masterpid() == 0:
raise Exception("you have to enable the uWSGI master process to use this module")
@@ -8,6 +14,7 @@ if uwsgi.opt.get('lazy'):
raise Exception("uWSGI lazy mode is not supported by this module")
spooler_functions = {}
mule_functions = {}
postfork_chain = []
def get_free_signal():
@@ -75,6 +82,46 @@ class spoolraw(spool):
return uwsgi.spool(arguments)
class mulefunc(object):
def __init__(self, f):
if callable(f):
self.fname = f.__name__
self.mule = 0
mule_functions[f.__name__] = f
else:
self.mule = f
self.fname = None
def real_call(self, *args, **kwargs):
uwsgi.mule_msg(pickle.dumps(
{
'service': 'uwsgi_mulefunc',
'func':self.fname,
'args': args,
'kwargs': kwargs
}
), self.mule)
def __call__(self, *args, **kwargs):
if not self.fname:
self.fname = args[0].__name__
mule_functions[self.fname] = args[0]
return self.real_call
return self.real_call(*args, **kwargs)
def mule_msg_dispatcher(message):
msg = pickle.loads(message)
if msg['service'] == 'uwsgi_mulefunc':
return mule_functions[msg['func']](*msg['args'],**msg['kwargs'])
uwsgi.mule_msg_hook = mule_msg_dispatcher
class rpc(object):
def __init__(self, name):
@@ -84,6 +131,68 @@ class rpc(object):
uwsgi.register_rpc(self.name, f)
return f
class farm_loop(object):
def __init__(self, f, farm):
self.f = f
self.farm = farm
def __call__(self):
if uwsgi.mule_id() == 0:
return
if not uwsgi.in_farm(self.farm):
return
while True:
message = uwsgi.farm_get_msg()
if message:
self.f(message)
class farm(object):
def __init__(self, name=None, **kwargs):
self.name = name
def __call__(self, f):
postfork_chain.append(farm_loop(f, self.name))
class mule_loop(object):
def __init__(self, f, num):
self.f = f
self.num = num
def __call__(self):
if uwsgi.mule_id() == self.num:
self.f()
class mule(object):
def __init__(self, num):
self.num = num
def __call__(self, f):
postfork_chain.append(mule_loop(f, self.num))
class mulemsg_loop(object):
def __init__(self, f, num):
self.f = f
self.num = num
def __call__(self):
if uwsgi.mule_id() == self.num:
print " i am the mule"
while True:
message = uwsgi.mule_get_msg()
if message:
self.f(message)
class mulemsg(object):
def __init__(self, num):
self.num = num
def __call__(self, f):
postfork_chain.append(mulemsg_loop(f, self.num))
class signal(object):
def __init__(self, num, **kwargs):
@@ -148,6 +257,15 @@ class filemon(object):
uwsgi.add_file_monitor(self.num, self.fsobj)
return f
class erlang(object):
def __init__(self, name):
self.name = name
def __call__(self, f):
uwsgi.erlang_register_process(self.name, f)
return f
class lock(object):
def __init__(self, f):
self.f = f
+20 -7
View File
@@ -2,11 +2,12 @@ import uwsgi
import os
import gc
import sys
from uwsgidecorators import *
gc.set_debug(gc.DEBUG_SAVEALL)
print os.environ
print sys.modules
print sys.argv
print(os.environ)
print(sys.modules)
print(sys.argv)
try:
if sys.argv[1] == 'debug':
@@ -42,13 +43,25 @@ routes['/logo'] = serve_logo
routes['/config'] = serve_config
routes['/options'] = serve_options
@postfork
def setprocname():
if uwsgi.worker_id() > 0:
uwsgi.setprocname("i am the worker %d" % uwsgi.worker_id())
def application(env, start_response):
uwsgi.mule_msg(env['REQUEST_URI'], 1)
try:
uwsgi.mule_msg(env['REQUEST_URI'], 1)
except:
pass
req = uwsgi.workers()[uwsgi.worker_id()-1]['requests']
uwsgi.setprocname("worker %d managed %d requests" % (uwsgi.worker_id(), req))
gc.collect(2)
if DEBUG:
print env['wsgi.input'].fileno()
print(env['wsgi.input'].fileno())
if routes.has_key(env['PATH_INFO']):
return routes[env['PATH_INFO']](env, start_response)
@@ -56,12 +69,12 @@ def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
if DEBUG:
print env['wsgi.input'].fileno()
print(env['wsgi.input'].fileno())
gc.collect(2)
if DEBUG:
print len(gc.get_objects())
print(len(gc.get_objects()))
workers = ''
for w in uwsgi.workers():
+1 -1
View File
@@ -129,7 +129,7 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, int app_tag
add_exported_option((char *) node->name, (char *) node->children->content, 0);
}
else {
add_exported_option((char *) node->name, "1", 0);
add_exported_option((char *) node->name, strdup("1"), 0);
}
}
}