mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53913357e0 | ||
|
|
098416f444 | ||
|
|
c98cb09c7c | ||
|
|
bb1ef28d69 | ||
|
|
1d5b05265d | ||
|
|
d9fef3c30e | ||
|
|
e5dfb9efc3 | ||
|
|
02bab15e86 | ||
|
|
6f4ddead09 | ||
|
|
b361248ff6 | ||
|
|
e9c42ceaa5 | ||
|
|
5d7029744a | ||
|
|
1084a3afa8 | ||
|
|
ed254bffee | ||
|
|
733784d7dd | ||
|
|
cb5b26bcb4 | ||
|
|
0065152bb1 | ||
|
|
03266203fd | ||
|
|
4a5f68f9d8 | ||
|
|
83e31a1c27 | ||
|
|
0efed5ef9c | ||
|
|
cdfef1281d | ||
|
|
e00907e142 | ||
|
|
6dcbcf39e3 | ||
|
|
044579a8e0 | ||
|
|
d2b52b4663 | ||
|
|
7f75b2c02c | ||
|
|
24a3f671e5 | ||
|
|
875100e3c8 | ||
|
|
34bc7c0cfd | ||
|
|
b39a10ff7c | ||
|
|
02331904de | ||
|
|
d1a4ae694e | ||
|
|
7a5ffc1124 | ||
|
|
19c5bfb42c | ||
|
|
893bf3686b | ||
|
|
e54fa9bcd4 | ||
|
|
c1eb5ab0fe | ||
|
|
461914dde4 | ||
|
|
85662578e4 | ||
|
|
a59c0ae795 | ||
|
|
3a860155ee | ||
|
|
27553c2967 | ||
|
|
9a8ac9af3c | ||
|
|
2f5daffe99 | ||
|
|
75cd31dce4 | ||
|
|
f7150d1b41 | ||
|
|
d6a6b65338 | ||
|
|
979f6027b4 | ||
|
|
7dc059c75b | ||
|
|
b639b5974f | ||
|
|
0de08c553c | ||
|
|
80788ac695 | ||
|
|
1494c621c1 | ||
|
|
605e5b5173 | ||
|
|
4cf2213051 | ||
|
|
3aa36668e5 | ||
|
|
1c0b5b42e9 | ||
|
|
702dc44fad | ||
|
|
2cae07aa52 | ||
|
|
b5616ff25c | ||
|
|
b7b7521975 | ||
|
|
dce3263ee3 | ||
|
|
9796e05ca1 | ||
|
|
5cc0d459ec | ||
|
|
531a850a71 | ||
|
|
4c36280287 | ||
|
|
70be8eb55e | ||
|
|
f8b757b21e | ||
|
|
3a63d352bb | ||
|
|
60467705c5 | ||
|
|
eada0c09e0 | ||
|
|
8e851aa6a1 | ||
|
|
eaf7bb967d | ||
|
|
7be45c77b1 | ||
|
|
5e2b460dc8 | ||
|
|
16143e698f | ||
|
|
4259946e3b | ||
|
|
0a750d76ee | ||
|
|
e4a9f5f0dd | ||
|
|
d5b7698f89 | ||
|
|
a481e8508e | ||
|
|
a53b57497b | ||
|
|
d871357b2d | ||
|
|
2d57db55f4 | ||
|
|
bae45ce03a | ||
|
|
44cc4336f1 | ||
|
|
44f6e214fd | ||
|
|
3e46f81d2b | ||
|
|
e4532b9a50 | ||
|
|
2694be562c | ||
|
|
fadb9edd7f | ||
|
|
d85e0790de | ||
|
|
bc46c4d704 | ||
|
|
a73a010188 | ||
|
|
4e8c8ef317 | ||
|
|
e402e7805d | ||
|
|
302b8f026b | ||
|
|
630054b72a | ||
|
|
a05f459b2b | ||
|
|
207979580a | ||
|
|
f69526f8bf | ||
|
|
e249d567a1 | ||
|
|
a23ba653da | ||
|
|
0644d53572 | ||
|
|
f58f51294d | ||
|
|
86194eb93e | ||
|
|
0a89f375e6 | ||
|
|
6282178b3c | ||
|
|
8e14d68022 | ||
|
|
e86bd0c070 | ||
|
|
bf991f8892 | ||
|
|
b341678d20 | ||
|
|
5f59365d88 | ||
|
|
5130a7bb33 | ||
|
|
cc84a596d6 | ||
|
|
e67bed431a | ||
|
|
72613a9f48 | ||
|
|
c048ea0615 | ||
|
|
957ca1b7ed | ||
|
|
d80a6df039 | ||
|
|
94f9bd9d91 | ||
|
|
b480efe672 | ||
|
|
4fc306d979 | ||
|
|
56abccbdeb | ||
|
|
f218af0735 | ||
|
|
9b69c62780 | ||
|
|
eb5d67e07f | ||
|
|
e7391987b1 | ||
|
|
02cbe15575 | ||
|
|
a5a657f0d4 | ||
|
|
67567c86e0 | ||
|
|
445d02da45 | ||
|
|
4a05df41ce | ||
|
|
5c0c2f6b45 | ||
|
|
0ab55fef46 | ||
|
|
dd344bfe38 | ||
|
|
e92a889bcc | ||
|
|
419d656a83 | ||
|
|
3c3d58bfe9 | ||
|
|
1989099cc5 | ||
|
|
1446e3f0a9 | ||
|
|
00fc31289d | ||
|
|
2c463ad6af | ||
|
|
e641ae05c4 | ||
|
|
a13e0075ee | ||
|
|
e617a7b88e | ||
|
|
cbdeb4caad | ||
|
|
59314d692f | ||
|
|
3dfa56b279 | ||
|
|
920d5d7416 | ||
|
|
dcb654d7fb | ||
|
|
a563da1223 | ||
|
|
1e26cda615 | ||
|
|
97133b27ce | ||
|
|
b428bd3b87 | ||
|
|
05136e74b4 | ||
|
|
9f28a8bdf1 | ||
|
|
d9361f1fee | ||
|
|
835230b1a4 | ||
|
|
f88f51c553 | ||
|
|
1996305eb1 | ||
|
|
c7ad50e950 | ||
|
|
0ec0c29d67 | ||
|
|
75af117e8a | ||
|
|
2b04cefe4e | ||
|
|
0e41c4111a | ||
|
|
5f5d382c64 | ||
|
|
3e867fe401 | ||
|
|
153142b8b0 | ||
|
|
5562c0c047 | ||
|
|
f4a1f800ba | ||
|
|
bdbc5e5605 | ||
|
|
4104f825ff | ||
|
|
efa01ea404 | ||
|
|
982559ae66 | ||
|
|
60002e8de8 |
@@ -30,3 +30,8 @@ fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
|
||||
f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
|
||||
6945ee03c7ea95eb19217ef1e1fb17d9ae26adbc 0.9.9-beta1
|
||||
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
|
||||
|
||||
@@ -12,3 +12,5 @@ Marco Beri, Link I.T. S.p.a.
|
||||
Leonid Borisenko
|
||||
Cal Leeming, Simplicity Media Ltd
|
||||
Luigi Scarso
|
||||
Corey Farwell
|
||||
Charles Duffy
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
*** august 2011 ***
|
||||
|
||||
* 0.9.9 [20110829]
|
||||
|
||||
- various spooler improvements
|
||||
- upload progress optimizations and fixes
|
||||
- new emperor mode: Tyrant
|
||||
- allows multiple --ini options
|
||||
- better binary path detection
|
||||
- gevent loop engine support
|
||||
- resolve domain names in socket logging
|
||||
- snmp fixes and reintroduction of the snmp-api
|
||||
- fixed grunt mode
|
||||
- you can specify build profile via env var UWSGI_PROFILE
|
||||
- reintroduction of string-based multiapp
|
||||
- new option --emperor-throttle
|
||||
- improved queue and sharedarea subsystems
|
||||
- uWSGI can now be built as a shared library
|
||||
- new api attribute: uwsgi.magic_table
|
||||
- improved apache2 module
|
||||
- new option --pyshell
|
||||
- allow threads in gateways
|
||||
- fastrouter improvements
|
||||
- the application list is now shared and exported to the api
|
||||
- allows setting the thread stack size
|
||||
- UWSGI_APPID for better multiapp hosting
|
||||
- better reloading in lazy mode
|
||||
- native pump support
|
||||
- various rack fixes
|
||||
- support for attaching binary data in the executable
|
||||
- new option --set
|
||||
- extreme-optimized http protocol parser
|
||||
- WSGI handler optimizations
|
||||
|
||||
*** july 2011 ***
|
||||
|
||||
* 0.9.8.3 [20110723]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import uwsgi
|
||||
|
||||
print uwsgi.extract("data://0")
|
||||
@@ -0,0 +1,5 @@
|
||||
[uwsgi]
|
||||
inherit = default
|
||||
bin_name = pyuwsgi.so
|
||||
embedded_plugins = pyuwsgi,python,ping,cache,nagios,rpc,ugreen
|
||||
as_shared_library = true
|
||||
@@ -138,7 +138,7 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *
|
||||
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;
|
||||
@@ -164,6 +164,8 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *
|
||||
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;
|
||||
}
|
||||
@@ -171,9 +173,13 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *
|
||||
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++;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -512,7 +518,7 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
|
||||
uci->prev = last_index;
|
||||
}
|
||||
}
|
||||
else if (flags && UWSGI_CACHE_FLAG_UPDATE) {
|
||||
else if (flags & UWSGI_CACHE_FLAG_UPDATE) {
|
||||
uci = &uwsgi.cache_items[index] ;
|
||||
if (expires) {
|
||||
expires += time(NULL);
|
||||
|
||||
@@ -12,4 +12,6 @@ env LOGTO=/tmp/uwsgi.log
|
||||
env BINPATH=/home/foo/uwsgi/uwsgi
|
||||
|
||||
# --no-orphans avoid workers without master
|
||||
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -m simple_app --logto $LOGTO -M -p 4
|
||||
# --die-on-term could be a good idea
|
||||
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -w simple_app --logto $LOGTO -M -p 4
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
require 'rubygems'
|
||||
require 'socket'
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError
|
||||
end
|
||||
require 'rack'
|
||||
require 'rack/content_length'
|
||||
require 'rack/rewindable_input'
|
||||
|
||||
+21
-10
@@ -10,8 +10,8 @@ import time
|
||||
|
||||
# register rpc function helloworld
|
||||
@rpc("helloworld")
|
||||
def hello_world():
|
||||
return "Hello World"
|
||||
def hello2():
|
||||
return "[RPC] Hello World"
|
||||
|
||||
# register signal 1
|
||||
@signal(1)
|
||||
@@ -45,6 +45,7 @@ def tmpmodified(num):
|
||||
def a_long_task(args):
|
||||
for i in xrange(1,10):
|
||||
print("%s = %d" % ( str(args), i))
|
||||
print(uwsgi.call('helloworld'))
|
||||
time.sleep(1)
|
||||
|
||||
# continuosly spool a long running task
|
||||
@@ -52,10 +53,12 @@ def a_long_task(args):
|
||||
def an_infinite_task(args):
|
||||
for i in xrange(1,4):
|
||||
print("infinite: %d %s" % (i, str(args)))
|
||||
print(uwsgi.call('helloworld'))
|
||||
uwsgi.signal(100)
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
# spool a task after 60 seconds
|
||||
# spool a task after 5 seconds
|
||||
@spool
|
||||
def delayed_task(args):
|
||||
print("*** I am a delayed spool job. It is %s [%s]***" % (time.asctime(), str(args)))
|
||||
@@ -89,7 +92,10 @@ def a_running_thread_with_args(who):
|
||||
def a_post_fork_thread():
|
||||
while True:
|
||||
time.sleep(3)
|
||||
print("Hello from a thread in worker %d" % uwsgi.worker_id())
|
||||
if uwsgi.i_am_the_spooler():
|
||||
print("Hello from a thread in the spooler")
|
||||
else:
|
||||
print("Hello from a thread in worker %d" % uwsgi.worker_id())
|
||||
|
||||
@postfork
|
||||
def fork_happened():
|
||||
@@ -97,24 +103,29 @@ def fork_happened():
|
||||
|
||||
@postfork
|
||||
def fork_happened2():
|
||||
print("waiting for a signal...")
|
||||
uwsgi.signal_wait()
|
||||
print("signal received: %d" % uwsgi.signal_received())
|
||||
if uwsgi.i_am_the_spooler():
|
||||
return
|
||||
print("worker %d is waiting for signal 100..." % uwsgi.worker_id())
|
||||
uwsgi.signal_wait(100)
|
||||
print("worker %d received signal %d" % (uwsgi.worker_id(), uwsgi.signal_received()))
|
||||
print("fork() has been called [2] wid: %d" % uwsgi.worker_id())
|
||||
|
||||
@postfork
|
||||
@lock
|
||||
def locked_func():
|
||||
print("starting locked function on worker %d" % uwsgi.worker_id())
|
||||
for i in xrange(1, 100):
|
||||
time.sleep(0.2)
|
||||
for i in xrange(1, 5):
|
||||
time.sleep(1)
|
||||
print("[locked %d] waiting..." % uwsgi.worker_id())
|
||||
print("done with locked function on worker %d" % uwsgi.worker_id())
|
||||
|
||||
print(uwsgi.call('helloworld'))
|
||||
spool_filename = a_long_task.spool({'foo':'bar'}, hello='world')
|
||||
print("spool filename = %s" % spool_filename)
|
||||
an_infinite_task.spool(foo='bar', priority=3)
|
||||
delayed_task.spool(foo2='bar2', at=time.time()+60)
|
||||
when = int(time.time())+5
|
||||
print("scheduling a delayed task at %d" % when)
|
||||
delayed_task.spool(foo2='bar2', at=when)
|
||||
a_running_thread()
|
||||
a_running_thread_with_args("uWSGI")
|
||||
uwsgi_source_file = open('uwsgi.c','r')
|
||||
|
||||
@@ -14,10 +14,11 @@ def index(request):
|
||||
w['load'] = (100 * (w['running_time']/1000))/total_load
|
||||
w['last_spawn_str'] = time.ctime(w['last_spawn'])
|
||||
|
||||
spooler_jobs = uwsgi.spooler_jobs()
|
||||
jobs = []
|
||||
for j in spooler_jobs:
|
||||
jobs.append({'file': j, 'env': uwsgi.parsefile(j)})
|
||||
if 'spooler' in uwsgi.opt:
|
||||
spooler_jobs = uwsgi.spooler_jobs()
|
||||
for j in spooler_jobs:
|
||||
jobs.append({'file': j, 'env': uwsgi.parsefile(j)})
|
||||
|
||||
return render_to_response('uwsgi.html', {'masterpid': uwsgi.masterpid(),
|
||||
'started_on': time.ctime(uwsgi.started_on),
|
||||
|
||||
@@ -8,6 +8,8 @@ extern char **environ;
|
||||
int emperor_queue;
|
||||
char *emperor_absolute_dir;
|
||||
|
||||
void emperor_send_stats(int);
|
||||
|
||||
struct uwsgi_instance {
|
||||
struct uwsgi_instance *ui_prev;
|
||||
struct uwsgi_instance *ui_next;
|
||||
@@ -32,6 +34,9 @@ struct uwsgi_instance {
|
||||
int loyal;
|
||||
|
||||
int zerg;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
|
||||
@@ -169,12 +174,12 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
|
||||
uwsgi_log("reload the uwsgi instance %s\n", c_ui->name);
|
||||
}
|
||||
|
||||
void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
void emperor_add(char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid) {
|
||||
|
||||
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;
|
||||
@@ -183,6 +188,13 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
|
||||
usleep(uwsgi.emperor_throttle*1000);
|
||||
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (uid == 0 || gid == 0) {
|
||||
uwsgi_log("[emperor-tyrant] invalid permissions for file %s\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (c_ui->ui_next) {
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
@@ -209,6 +221,8 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
|
||||
memcpy(n_ui->name, name, strlen(name));
|
||||
n_ui->born = born;
|
||||
n_ui->uid = uid;
|
||||
n_ui->gid = gid;
|
||||
n_ui->last_mod = born;
|
||||
// start without loyalty
|
||||
n_ui->last_loyal = born;
|
||||
@@ -253,6 +267,24 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
}
|
||||
else {
|
||||
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) uid, (int) gid, name);
|
||||
if (setgid(gid)) {
|
||||
uwsgi_error("setgid()");
|
||||
exit(1);
|
||||
}
|
||||
if (setgroups(0, NULL)) {
|
||||
uwsgi_error("setgroups()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setuid(uid)) {
|
||||
uwsgi_error("setuid()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsetenv("UWSGI_RELOADS");
|
||||
unsetenv("NOTIFY_SOCKET");
|
||||
|
||||
@@ -308,9 +340,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
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, ':');
|
||||
@@ -319,29 +351,29 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
}
|
||||
}
|
||||
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 (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++) {
|
||||
@@ -360,7 +392,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
}
|
||||
|
||||
// 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");
|
||||
@@ -400,6 +432,8 @@ void emperor_loop() {
|
||||
int interesting_fd;
|
||||
char notification_message[64];
|
||||
|
||||
uwsgi.emperor_stats_fd = -1;
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
uwsgi_unix_signal(SIGINT, royal_death);
|
||||
uwsgi_unix_signal(SIGTERM, royal_death);
|
||||
@@ -420,6 +454,23 @@ void emperor_loop() {
|
||||
uwsgi_log("*** starting uWSGI Emperor ***\n");
|
||||
}
|
||||
|
||||
if (uwsgi.emperor_stats) {
|
||||
char *tcp_port = strchr(uwsgi.emperor_stats, ':');
|
||||
if (tcp_port) {
|
||||
// disable deferred accept for this socket
|
||||
int current_defer_accept = uwsgi.no_defer_accept;
|
||||
uwsgi.no_defer_accept = 1;
|
||||
uwsgi.emperor_stats_fd = bind_to_tcp(uwsgi.emperor_stats, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi.no_defer_accept = current_defer_accept;
|
||||
}
|
||||
else {
|
||||
uwsgi.emperor_stats_fd = bind_to_unix(uwsgi.emperor_stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
|
||||
event_queue_add_fd_read(emperor_queue, uwsgi.emperor_stats_fd);
|
||||
uwsgi_log("*** Emperor stats server enabled on %s fd: %d ***\n", uwsgi.emperor_stats, uwsgi.emperor_stats_fd);
|
||||
}
|
||||
|
||||
amqp_port = strchr(uwsgi.emperor_dir, ':');
|
||||
|
||||
if (amqp_port) {
|
||||
@@ -517,7 +568,7 @@ reconnect:
|
||||
}
|
||||
else {
|
||||
if (msgsize > 0) {
|
||||
emperor_add(config_file, time(NULL), config, msgsize);
|
||||
emperor_add(config_file, time(NULL), config, msgsize, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,13 +605,18 @@ reconnect:
|
||||
emperor_respawn(ui_current, time(NULL));
|
||||
}
|
||||
else {
|
||||
emperor_add(config_file, time(NULL), NULL, 0);
|
||||
emperor_add(config_file, time(NULL), NULL, 0, 0, 0);
|
||||
}
|
||||
|
||||
free(config_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uwsgi.emperor_stats && uwsgi.emperor_stats_fd > -1) {
|
||||
if (interesting_fd == uwsgi.emperor_stats_fd) {
|
||||
emperor_send_stats(uwsgi.emperor_stats_fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui_current = emperor_get_by_fd(interesting_fd);
|
||||
if (ui_current) {
|
||||
@@ -583,7 +639,7 @@ reconnect:
|
||||
else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
|
||||
uwsgi_log("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
|
||||
char *zerg_name = uwsgi_concat3(ui_current->name,":","zerg");
|
||||
emperor_add(zerg_name, time(NULL), NULL, 0);
|
||||
emperor_add(zerg_name, time(NULL), NULL, 0, ui_current->uid, ui_current->gid);
|
||||
free(zerg_name);
|
||||
}
|
||||
}
|
||||
@@ -620,13 +676,21 @@ reconnect:
|
||||
ui_current = emperor_get(de->d_name);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, sotp the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n");
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(de->d_name, st.st_mtime, NULL, 0);
|
||||
emperor_add(de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -659,13 +723,21 @@ reconnect:
|
||||
ui_current = emperor_get(g.gl_pathv[i]);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, sotp the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n");
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(g.gl_pathv[i], st.st_mtime, NULL, 0);
|
||||
emperor_add(g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,7 +801,7 @@ reconnect:
|
||||
}
|
||||
else {
|
||||
// UNSAFE
|
||||
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len);
|
||||
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid);
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
break;
|
||||
@@ -748,3 +820,72 @@ reconnect:
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define stats_send_llu(x, y) fprintf(output, x, (long long unsigned int) y)
|
||||
#define stats_send(x, y) fprintf(output, x, y)
|
||||
|
||||
void emperor_send_stats(int fd) {
|
||||
|
||||
struct sockaddr_un client_src;
|
||||
socklen_t client_src_len = 0;
|
||||
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("accept()");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *output = fdopen(client_fd, "w");
|
||||
if (!output) {
|
||||
uwsgi_error("fdopen()");
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
|
||||
|
||||
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
|
||||
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
|
||||
|
||||
char *cwd = uwsgi_get_cwd();
|
||||
stats_send("\"cwd\": \"%s\",\n", cwd);
|
||||
free(cwd);
|
||||
|
||||
stats_send("\"emperor\": \"%s\",\n", uwsgi.emperor_dir);
|
||||
|
||||
fprintf(output,"\"emperor_tyrant\": %d,\n", uwsgi.emperor_tyrant);
|
||||
|
||||
|
||||
fprintf(output, "\"vassals\": [\n");
|
||||
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
|
||||
while (c_ui) {
|
||||
fprintf(output,"\t{");
|
||||
stats_send("\"id\": \"%s\", ", c_ui->name);
|
||||
fprintf(output,"\"pid\": %d, ", (int) c_ui->pid);
|
||||
|
||||
stats_send_llu( "\"born\": %llu, ", c_ui->born);
|
||||
stats_send_llu( "\"last_mod\": %llu, ", c_ui->last_mod);
|
||||
|
||||
fprintf(output,"\"loyal\": %d, ", c_ui->loyal);
|
||||
fprintf(output,"\"zerg\": %d, ", c_ui->zerg);
|
||||
|
||||
fprintf(output,"\"uid\": %d, ", (int)c_ui->uid);
|
||||
fprintf(output,"\"gid\": %d, ", (int)c_ui->gid);
|
||||
|
||||
stats_send_llu( "\"respawns\": %llu ", c_ui->respawns);
|
||||
c_ui = c_ui->ui_next;
|
||||
|
||||
if (c_ui) {
|
||||
fprintf(output,"},\n");
|
||||
}
|
||||
else {
|
||||
fprintf(output,"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fprintf(output,"]}\n");
|
||||
fclose(output);
|
||||
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ void *event_queue_alloc(int nevents) {
|
||||
int event_queue_interesting_fd(void *events, int id) {
|
||||
port_event_t *pe = (port_event_t *) events;
|
||||
if (pe[id].portev_source == PORT_SOURCE_FILE || pe[id].portev_source == PORT_SOURCE_TIMER) {
|
||||
return (int) pe[id].portev_user;
|
||||
return (long) pe[id].portev_user;
|
||||
}
|
||||
|
||||
return (int) pe[id].portev_object;
|
||||
@@ -149,7 +149,7 @@ int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
||||
|
||||
|
||||
if (pe.portev_source == PORT_SOURCE_FILE || pe.portev_source == PORT_SOURCE_TIMER) {
|
||||
*interesting_fd = (int) pe.portev_user;
|
||||
*interesting_fd = (long) pe.portev_user;
|
||||
}
|
||||
else {
|
||||
*interesting_fd = (int) pe.portev_object;
|
||||
@@ -327,11 +327,13 @@ int event_queue_fd_write_to_read(int eq, int fd) {
|
||||
|
||||
struct kevent kev;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
EV_SET(&kev, fd, EVFILT_WRITE, EV_DISABLE, 0, 0, 0);
|
||||
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
||||
uwsgi_error("kevent()");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
||||
@@ -476,7 +478,7 @@ int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
||||
fo.fo_ctime = st.st_ctim;
|
||||
|
||||
fmon_id++;
|
||||
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *) fmon_id)) {
|
||||
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *) (long) fmon_id)) {
|
||||
uwsgi_error("port_associate()");
|
||||
return -1;
|
||||
}
|
||||
@@ -506,7 +508,7 @@ struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
||||
fo.fo_atime = st.st_atim;
|
||||
fo.fo_mtime = st.st_mtim;
|
||||
fo.fo_ctime = st.st_ctim;
|
||||
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *)id)) {
|
||||
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *)(long)id)) {
|
||||
uwsgi_error("port_associate()");
|
||||
return NULL;
|
||||
}
|
||||
@@ -687,13 +689,21 @@ enum
|
||||
|
||||
|
||||
static int timerfd_create (clockid_t __clock_id, int __flags) {
|
||||
#ifdef __amd64__
|
||||
return syscall(283, __clock_id, __flags);
|
||||
#elif defined(__i386__)
|
||||
return syscall(322, __clock_id, __flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int timerfd_settime (int __ufd, int __flags,
|
||||
__const struct itimerspec *__utmr,
|
||||
struct itimerspec *__otmr) {
|
||||
#ifdef __amd64__
|
||||
return syscall(286, __ufd, __flags, __utmr, __otmr);
|
||||
#elif defined(__i386__)
|
||||
return syscall(325, __ufd, __flags, __utmr, __otmr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -765,7 +775,7 @@ int event_queue_add_timer(int eq, int *id, int sec) {
|
||||
timer_id++;
|
||||
|
||||
pnotif.portnfy_port = eq;
|
||||
pnotif.portnfy_user = (void *) timer_id;
|
||||
pnotif.portnfy_user = (void *) (long) timer_id;
|
||||
|
||||
sigev.sigev_notify = SIGEV_PORT;
|
||||
sigev.sigev_value.sival_ptr = &pnotif;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
use POSIX;
|
||||
|
||||
open CONFIG,'welcome.ini';
|
||||
|
||||
dup2(fileno(CONFIG), 17);
|
||||
|
||||
exec './uwsgi','--ini','fd://17';
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
if (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) ) {
|
||||
if (uwsgi_check_scheme(file)) {
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
|
||||
char *colon;
|
||||
int i;
|
||||
|
||||
if (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6)) {
|
||||
if (uwsgi_check_scheme(file)) {
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ void uwsgi_lock(void *lock) {
|
||||
void uwsgi_unlock(void *lock) {
|
||||
|
||||
pthread_mutex_unlock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_rwlock_init(void *lock) {
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t val
|
||||
}
|
||||
}
|
||||
|
||||
void master_loop(char **argv, char **environ) {
|
||||
int master_loop(char **argv, char **environ) {
|
||||
|
||||
uint64_t tmp_counter;
|
||||
|
||||
@@ -284,15 +284,28 @@ void master_loop(char **argv, char **environ) {
|
||||
#ifdef UWSGI_SNMP
|
||||
int snmp_fd = -1;
|
||||
#endif
|
||||
|
||||
int i=0;
|
||||
int rlen;
|
||||
|
||||
int check_interval = 1;
|
||||
uint64_t overload_count = 0;
|
||||
uint64_t idle_count = 0;
|
||||
|
||||
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);
|
||||
@@ -318,6 +331,15 @@ void master_loop(char **argv, char **environ) {
|
||||
#endif
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]);
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding %d to signal poll (spooler)\n", uwsgi.shared->spooler_signal_pipe[0]);
|
||||
#endif
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.log_master) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]);
|
||||
@@ -337,6 +359,23 @@ void master_loop(char **argv, char **environ) {
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.zerg_server_fd);
|
||||
uwsgi_log("*** Zerg server enabled on %s ***\n", uwsgi.zerg_server);
|
||||
}
|
||||
|
||||
if (uwsgi.stats) {
|
||||
char *tcp_port = strchr(uwsgi.stats, ':');
|
||||
if (tcp_port) {
|
||||
// disable deferred accept for this socket
|
||||
int current_defer_accept = uwsgi.no_defer_accept;
|
||||
uwsgi.no_defer_accept = 1;
|
||||
uwsgi.stats_fd = bind_to_tcp(uwsgi.stats, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi.no_defer_accept = current_defer_accept;
|
||||
}
|
||||
else {
|
||||
uwsgi.stats_fd = bind_to_unix(uwsgi.stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.stats_fd);
|
||||
uwsgi_log("*** Stats server enabled on %s fd: %d ***\n", uwsgi.stats, uwsgi.stats_fd);
|
||||
}
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket) {
|
||||
udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
|
||||
@@ -351,6 +390,9 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
if (uwsgi.cheap) {
|
||||
uwsgi_add_sockets_to_queue(uwsgi.master_queue);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
uwsgi.workers[i].cheaped = 1;
|
||||
}
|
||||
uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
|
||||
}
|
||||
|
||||
@@ -450,10 +492,12 @@ void master_loop(char **argv, char **environ) {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
// spawn mules
|
||||
for(i=0;i<uwsgi.mules_cnt;i++) {
|
||||
size_t mule_patch_size = 0;
|
||||
uwsgi.mules[i].patch = uwsgi_string_get_list(&uwsgi.mules_patches, i, &mule_patch_size);
|
||||
uwsgi_mule(i+1);
|
||||
}
|
||||
|
||||
// spawn fat gateways
|
||||
for(i=0;i<uwsgi.gateways_cnt;i++) {
|
||||
@@ -481,16 +525,18 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.touch_reload) {
|
||||
struct uwsgi_string_list *touch_reload = uwsgi.touch_reload;
|
||||
while(touch_reload) {
|
||||
struct stat tr_st;
|
||||
if (stat(uwsgi.touch_reload, &tr_st)) {
|
||||
uwsgi_error("stat()");
|
||||
uwsgi_log("unable to stat() %s, touch-reload will be disabled\n", uwsgi.touch_reload);
|
||||
uwsgi.touch_reload = NULL;
|
||||
if (stat(touch_reload->value, &tr_st)) {
|
||||
uwsgi_log("unable to stat() %s, reload will be triggered as soon as the file is created\n", touch_reload->value);
|
||||
touch_reload->custom = 0;
|
||||
}
|
||||
else {
|
||||
uwsgi.last_touch_reload_mtime = tr_st.st_mtime;
|
||||
touch_reload->custom = (uint64_t) tr_st.st_mtime;
|
||||
}
|
||||
touch_reload = touch_reload->next;
|
||||
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@@ -504,6 +550,7 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi.lazy_respawned = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.master_mercy) {
|
||||
if (uwsgi.master_mercy < time(NULL)) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
@@ -519,7 +566,7 @@ void master_loop(char **argv, char **environ) {
|
||||
else if (uwsgi.to_heaven) { ready_to_reload++;}
|
||||
else if (uwsgi.to_outworld) {
|
||||
uwsgi.lazy_respawned++;
|
||||
if (uwsgi_respawn_worker(i)) return;
|
||||
if (uwsgi_respawn_worker(i)) return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -532,7 +579,7 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
if (uwsgi.respawn_workers) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi_respawn_worker(i)) return;
|
||||
if (uwsgi_respawn_worker(i)) return 0;
|
||||
}
|
||||
|
||||
uwsgi.respawn_workers = 0;
|
||||
@@ -560,9 +607,74 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi.restore_snapshot = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// cheaper management
|
||||
if (uwsgi.cheaper) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
if (uwsgi.workers[i].busy == 0) {
|
||||
if (overload_count > 0) overload_count--;
|
||||
goto healthy;
|
||||
}
|
||||
}
|
||||
}
|
||||
overload_count++;
|
||||
idle_count = 0;
|
||||
}
|
||||
|
||||
healthy:
|
||||
if (uwsgi.cheaper) {
|
||||
if (overload_count > 3) {
|
||||
// activate the first available worker
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].cheaped == 1 && uwsgi.workers[i].pid == 0) {
|
||||
if (uwsgi_respawn_worker(i)) return 0;
|
||||
overload_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (overload_count == 0) {
|
||||
// how many active workers ?
|
||||
idle_count++;
|
||||
int active_workers = 0;
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
active_workers++;
|
||||
}
|
||||
}
|
||||
|
||||
// find the oldest worker and cheap it
|
||||
if (active_workers > uwsgi.cheaper_count+1 || (idle_count > 60 && active_workers > uwsgi.cheaper_count)) {
|
||||
time_t oldest_worker_spawn = INT_MAX;
|
||||
int oldest_worker = 0;
|
||||
idle_count = 0;
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
|
||||
if (uwsgi.workers[i].last_spawn < oldest_worker_spawn) {
|
||||
oldest_worker_spawn = uwsgi.workers[i].last_spawn;
|
||||
oldest_worker = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldest_worker > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("worker %d should die...\n", oldest_worker);
|
||||
#endif
|
||||
uwsgi.workers[oldest_worker].cheaped = 1;
|
||||
uwsgi.workers[oldest_worker].manage_next_request = 0;
|
||||
// wakeup task in case of wait
|
||||
(void) kill(uwsgi.workers[oldest_worker].pid, SIGWINCH);
|
||||
overload_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -570,8 +682,8 @@ void master_loop(char **argv, char **environ) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -616,6 +728,9 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
return -1;
|
||||
#else
|
||||
uwsgi_log( "running %s\n", uwsgi.binary_path);
|
||||
argv[0] = uwsgi.binary_path;
|
||||
//strcpy (argv[0], uwsgi.binary_path);
|
||||
@@ -623,6 +738,7 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("execvp()");
|
||||
// never here
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!uwsgi.cheap) {
|
||||
@@ -643,6 +759,16 @@ void master_loop(char **argv, char **environ) {
|
||||
else {
|
||||
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
|
||||
if (diedpid == -1) {
|
||||
if (errno == ECHILD && uwsgi.cheaper) {
|
||||
if (uwsgi.to_heaven) {
|
||||
ready_to_reload = uwsgi.numproc;
|
||||
continue;
|
||||
}
|
||||
else if (uwsgi.to_hell) {
|
||||
ready_to_die = uwsgi.numproc;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uwsgi_error("waitpid()");
|
||||
/* here is better to reload all the uWSGI stack */
|
||||
uwsgi_log( "something horrible happened...\n");
|
||||
@@ -760,6 +886,12 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.stats && uwsgi.stats_fd > -1) {
|
||||
if (interesting_fd == uwsgi.stats_fd) {
|
||||
uwsgi_send_stats(uwsgi.stats_fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.zerg_server) {
|
||||
if (interesting_fd == uwsgi.zerg_server_fd) {
|
||||
struct sockaddr_un zsun;
|
||||
@@ -846,7 +978,7 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi.cheap = 0;
|
||||
uwsgi_del_sockets_from_queue(uwsgi.master_queue);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi_respawn_worker(i)) return;
|
||||
if (uwsgi_respawn_worker(i)) return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1016,23 +1148,75 @@ void master_loop(char **argv, char **environ) {
|
||||
//uwsgi.workers[i].pipe[0] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
// check for spooler signal
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) {
|
||||
rlen = read(interesting_fd, &uwsgi_signal, 1);
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("received uwsgi signal %d from the spooler\n", uwsgi_signal);
|
||||
#endif
|
||||
uwsgi_route_signal(uwsgi_signal);
|
||||
}
|
||||
else {
|
||||
uwsgi_log_verbose("lost connection with the spooler\n");
|
||||
close(interesting_fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
uwsgi.current_time = time(NULL);
|
||||
// checking logsize
|
||||
if (uwsgi.logfile) {
|
||||
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
|
||||
/*
|
||||
if (uwsgi.shared->logsize > 8192) {
|
||||
//uwsgi_log("logsize: %d\n", uwsgi.shared->logsize);
|
||||
char *new_logfile = uwsgi_malloc(strlen(uwsgi.logfile) + 14 + 1);
|
||||
memset(new_logfile, 0, strlen(uwsgi.logfile) + 14 + 1);
|
||||
if (!rename(uwsgi.logfile, new_logfile)) {
|
||||
// close 2, reopen logfile dup'it and gracefully reload workers;
|
||||
if (uwsgi.log_master) {
|
||||
uwsgi.shared->logsize = lseek(uwsgi.original_log_fd, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
|
||||
}
|
||||
if (uwsgi.log_maxsize > 0 && uwsgi.shared->logsize > uwsgi.log_maxsize) {
|
||||
char *rot_name = uwsgi.log_backupname;
|
||||
int need_free = 0;
|
||||
if (rot_name == NULL) {
|
||||
char *ts_str = uwsgi_num2str((int)time(NULL));
|
||||
rot_name = uwsgi_concat3(uwsgi.logfile, ".", ts_str);
|
||||
free(ts_str);
|
||||
need_free = 1;
|
||||
}
|
||||
free(new_logfile);
|
||||
char message[1024];
|
||||
int ret = snprintf(message, 1024, "[%d] logsize: %llu, triggering rotation to %s...\n", (int) time(NULL), (unsigned long long) uwsgi.shared->logsize, rot_name);
|
||||
if (ret > 0) {
|
||||
rlen = write(uwsgi.original_log_fd, message, ret);
|
||||
|
||||
}
|
||||
if (rename(uwsgi.logfile, rot_name) == 0) {
|
||||
// close 2, reopen logfile dup'it and gracefully reload workers;
|
||||
int fd = open(uwsgi.logfile, O_RDWR | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open(uwsgi.logfile);
|
||||
grace_them_all(0);
|
||||
}
|
||||
if (dup2(fd, uwsgi.original_log_fd) < 0) {
|
||||
uwsgi_error("dup2()");
|
||||
grace_them_all(0);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
uwsgi_error("unable to rotate log: rename()");
|
||||
}
|
||||
if (need_free)
|
||||
free(rot_name);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -1164,10 +1348,43 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi.workers[i].harakiri = 0;
|
||||
}
|
||||
}
|
||||
// then for evil memory checkers
|
||||
if (uwsgi.evil_reload_on_as) {
|
||||
if ((rlim_t) uwsgi.workers[i].vsz_size >= uwsgi.evil_reload_on_as) {
|
||||
uwsgi_log("*** EVIL RELOAD ON WORKER %d ADDRESS SPACE: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].vsz_size, uwsgi.workers[i].pid );
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
uwsgi.workers[i].vsz_size = 0;
|
||||
}
|
||||
}
|
||||
if (uwsgi.evil_reload_on_rss) {
|
||||
if ((rlim_t) uwsgi.workers[i].rss_size >= uwsgi.evil_reload_on_rss) {
|
||||
uwsgi_log("*** EVIL RELOAD ON WORKER %d RSS: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].rss_size, uwsgi.workers[i].pid );
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
uwsgi.workers[i].rss_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// need to find a better way
|
||||
//uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time;
|
||||
}
|
||||
for (i = 0; i < uwsgi.mules_cnt; i++) {
|
||||
if (uwsgi.mules[i].harakiri > 0) {
|
||||
if (uwsgi.mules[i].harakiri < (time_t) uwsgi.current_time) {
|
||||
uwsgi_log("*** HARAKIRI ON MULE %d HANDLING SIGNAL %d (pid: %d) ***\n", i+1, uwsgi.mules[i].signum, uwsgi.mules[i].pid );
|
||||
kill(uwsgi.mules[i].pid, SIGKILL);
|
||||
uwsgi.mules[i].harakiri = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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
|
||||
@@ -1200,19 +1417,20 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
|
||||
// check touch_reload
|
||||
if (uwsgi.touch_reload && !uwsgi.to_heaven && !uwsgi.to_hell) {
|
||||
struct uwsgi_string_list *touch_reload = uwsgi.touch_reload;
|
||||
while (touch_reload && !uwsgi.to_heaven && !uwsgi.to_hell) {
|
||||
struct stat tr_st;
|
||||
if (stat(uwsgi.touch_reload, &tr_st)) {
|
||||
uwsgi_error("stat()");
|
||||
uwsgi_log("unable to stat() %s, touch-reload will be disabled\n", uwsgi.touch_reload);
|
||||
uwsgi.touch_reload = NULL;
|
||||
if (stat(touch_reload->value, &tr_st)) {
|
||||
touch_reload->custom = 0;
|
||||
}
|
||||
else {
|
||||
if (tr_st.st_mtime > uwsgi.last_touch_reload_mtime) {
|
||||
uwsgi_log("*** %s has been touched... grace them all !!! ***\n", uwsgi.touch_reload);
|
||||
if ((uint64_t)tr_st.st_mtime > touch_reload->custom) {
|
||||
uwsgi_log("*** %s has been touched... grace them all !!! ***\n", touch_reload->value);
|
||||
grace_them_all(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
touch_reload = touch_reload->next;
|
||||
}
|
||||
|
||||
|
||||
@@ -1230,12 +1448,27 @@ void master_loop(char **argv, char **environ) {
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
if (diedpid == uwsgi.shared->spooler_pid) {
|
||||
uwsgi_log( "OOOPS the spooler is no more...trying respawn...\n");
|
||||
uwsgi.spooler_respawned++;
|
||||
uwsgi.shared->spooler_pid = spooler_start();
|
||||
//event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pid_found = 0;
|
||||
for(i=0;i<uwsgi.mules_cnt;i++) {
|
||||
if (uwsgi.mules[i].pid == diedpid) {
|
||||
uwsgi_log("OOOPS mule %d crippled...trying respawn...\n", i+1);
|
||||
uwsgi_mule(i+1);
|
||||
pid_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pid_found) continue;
|
||||
|
||||
|
||||
/* reload the gateways */
|
||||
// TODO reload_gateway(diedpid);
|
||||
pid_found = 0;
|
||||
@@ -1276,6 +1509,37 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
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));
|
||||
}
|
||||
@@ -1285,10 +1549,12 @@ void master_loop(char **argv, char **environ) {
|
||||
else if (WIFSTOPPED(waitpid_status)) {
|
||||
uwsgi_log("subprocess %d stopped\n", (int) diedpid);
|
||||
}
|
||||
next:
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
if (uwsgi.to_heaven) {
|
||||
ready_to_reload++;
|
||||
uwsgi.workers[uwsgi.mywid].pid = 0;
|
||||
@@ -1315,6 +1581,12 @@ void master_loop(char **argv, char **environ) {
|
||||
if (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
uwsgi_log( "DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int)diedpid);
|
||||
}
|
||||
|
||||
if (uwsgi.workers[uwsgi.mywid].cheaped == 1) {
|
||||
uwsgi.workers[uwsgi.mywid].pid = 0;
|
||||
uwsgi_log("uWSGI worker %d cheaped.\n", uwsgi.mywid);
|
||||
continue;
|
||||
}
|
||||
gettimeofday(&last_respawn, NULL);
|
||||
if (last_respawn.tv_sec == uwsgi.respawn_delta) {
|
||||
last_respawn_rate++;
|
||||
@@ -1338,7 +1610,7 @@ void master_loop(char **argv, char **environ) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
if (uwsgi_respawn_worker(uwsgi.mywid)) return;
|
||||
if (uwsgi_respawn_worker(uwsgi.mywid)) return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+184
-37
@@ -2,6 +2,8 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void worker_wakeup() {}
|
||||
|
||||
void master_check_cluster_nodes() {
|
||||
|
||||
int i;
|
||||
@@ -31,24 +33,67 @@ void master_check_cluster_nodes() {
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_fixup_fds(int wid, int muleid) {
|
||||
|
||||
int i;
|
||||
|
||||
// close the cache server
|
||||
if (uwsgi.cache_server_fd != -1) {
|
||||
close(uwsgi.cache_server_fd);
|
||||
}
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
// fix the communication pipe
|
||||
close(uwsgi.shared->worker_signal_pipe[0]);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].signal_pipe[0] != -1) close(uwsgi.workers[i].signal_pipe[0]);
|
||||
if (i != wid) {
|
||||
if (uwsgi.workers[i].signal_pipe[1] != -1) close(uwsgi.workers[i].signal_pipe[1]);
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.shared->spooler_pid != getpid()) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
|
||||
if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
|
||||
}
|
||||
#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]);
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.mules_cnt;i++) {
|
||||
if (uwsgi.mules[i].signal_pipe[0] != -1) close(uwsgi.mules[i].signal_pipe[0]);
|
||||
if (muleid != i+1) {
|
||||
if (uwsgi.mules[i].signal_pipe[1] != -1) close(uwsgi.mules[i].signal_pipe[1]);
|
||||
if (uwsgi.mules[i].queue_pipe[1] != -1) close(uwsgi.mules[i].queue_pipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_respawn_worker(int wid) {
|
||||
|
||||
int respawns = uwsgi.workers[wid].respawn_count;
|
||||
int i;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
if (uwsgi.signal_pipe[wid][0] != -1) close(uwsgi.signal_pipe[wid][0]);
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.signal_pipe[wid])) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pid_t pid = fork();
|
||||
pid_t pid = uwsgi_fork(uwsgi.workers[wid].name);
|
||||
|
||||
if (pid == 0) {
|
||||
signal(SIGWINCH, worker_wakeup);
|
||||
uwsgi.mywid = wid;
|
||||
uwsgi.mypid = getpid();
|
||||
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
|
||||
@@ -59,43 +104,33 @@ int uwsgi_respawn_worker(int wid) {
|
||||
uwsgi.workers[uwsgi.mywid].respawn_count++;
|
||||
uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
|
||||
uwsgi.workers[uwsgi.mywid].cheaped = 0;
|
||||
uwsgi.workers[uwsgi.mywid].busy = 0;
|
||||
uwsgi.workers[uwsgi.mywid].sig = 0;
|
||||
|
||||
// close the cache server
|
||||
if (uwsgi.cache_server_fd != -1) {
|
||||
close(uwsgi.cache_server_fd);
|
||||
}
|
||||
// reset the apps count with a copy from the master
|
||||
uwsgi.workers[uwsgi.mywid].apps_cnt = uwsgi.workers[0].apps_cnt;
|
||||
|
||||
uwsgi_fixup_fds(wid, 0);
|
||||
|
||||
uwsgi.my_signal_socket = uwsgi.workers[wid].signal_pipe[1];
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
// fix the communication pipe
|
||||
close(uwsgi.shared->worker_signal_pipe[0]);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.signal_pipe[i][0] != -1) {
|
||||
close(uwsgi.signal_pipe[i][0]);
|
||||
}
|
||||
}
|
||||
uwsgi.my_signal_socket = uwsgi.signal_pipe[wid][1];
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
|
||||
}
|
||||
#endif
|
||||
if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (pid < 1) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.signal_pipe[wid][1]);
|
||||
}
|
||||
if (respawns > 0) {
|
||||
uwsgi_log("Respawned uWSGI worker %d (new pid: %d)\n", wid, (int) pid);
|
||||
}
|
||||
@@ -257,3 +292,115 @@ void uwsgi_manage_command_cron(time_t now) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
#define stats_send_llu(x, y) fprintf(output, x, (long long unsigned int) y)
|
||||
#define stats_send(x, y) fprintf(output, x, y)
|
||||
|
||||
void uwsgi_send_stats(int fd) {
|
||||
|
||||
int i,j;
|
||||
struct sockaddr_un client_src;
|
||||
struct uwsgi_app *ua;
|
||||
socklen_t client_src_len = 0;
|
||||
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("accept()");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *output = fdopen(client_fd, "w");
|
||||
if (!output) {
|
||||
uwsgi_error("fdopen()");
|
||||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
|
||||
|
||||
#ifdef __linux__
|
||||
stats_send_llu("\"listen_queue\": %llu,\n", uwsgi.shared->ti.tcpi_unacked);
|
||||
#endif
|
||||
|
||||
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
|
||||
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
|
||||
|
||||
char *cwd = uwsgi_get_cwd();
|
||||
stats_send("\"cwd\": \"%s\",\n", cwd);
|
||||
free(cwd);
|
||||
|
||||
fprintf(output, "\"workers\": [\n");
|
||||
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
fprintf(output,"\t{");
|
||||
|
||||
fprintf(output,"\"id\": %d, ", uwsgi.workers[i+1].id);
|
||||
fprintf(output,"\"pid\": %d, ", (int) uwsgi.workers[i+1].pid);
|
||||
stats_send_llu("\"requests\": %llu, ", uwsgi.workers[i+1].requests);
|
||||
stats_send_llu("\"exceptions\": %llu, ", uwsgi.workers[i+1].exceptions);
|
||||
stats_send_llu("\"signals\": %llu, ", uwsgi.workers[i+1].signals);
|
||||
|
||||
if (uwsgi.workers[i + 1].cheaped) {
|
||||
fprintf(output,"\"status\": \"cheap\", ");
|
||||
}
|
||||
else {
|
||||
if (uwsgi.workers[i + 1].sig) {
|
||||
fprintf(output,"\"status\": \"sig%d\", ", uwsgi.workers[i + 1].signum);
|
||||
}
|
||||
else if (uwsgi.workers[i + 1].busy) {
|
||||
fprintf(output,"\"status\": \"busy\", ");
|
||||
}
|
||||
else {
|
||||
fprintf(output,"\"status\": \"idle\", ");
|
||||
}
|
||||
}
|
||||
|
||||
stats_send_llu("\"rss\": %llu, ", uwsgi.workers[i+1].rss_size);
|
||||
stats_send_llu("\"vsz\": %llu, ", uwsgi.workers[i+1].vsz_size);
|
||||
|
||||
stats_send_llu("\"running_time\": %llu, ", uwsgi.workers[i+1].running_time);
|
||||
stats_send_llu("\"last_spawn\": %llu, ", uwsgi.workers[i+1].last_spawn);
|
||||
stats_send_llu("\"respawn_count\": %llu, ", uwsgi.workers[i+1].respawn_count);
|
||||
stats_send_llu("\"tx\": %llu, ", uwsgi.workers[i+1].tx);
|
||||
stats_send_llu("\"avg_rt\": %llu, ", uwsgi.workers[i+1].avg_response_time);
|
||||
|
||||
fprintf(output,"\"apps\": [\n");
|
||||
|
||||
for(j=0;j<uwsgi.workers[i+1].apps_cnt;j++) {
|
||||
ua = &uwsgi.workers[i+1].apps[j];
|
||||
fprintf(output,"\t\t{ ");
|
||||
|
||||
fprintf(output, "\"id\": %d, ", j);
|
||||
fprintf(output, "\"modifier1\": %d, ", ua->modifier1);
|
||||
fprintf(output, "\"mountpoint\": \"%.*s\", ", ua->mountpoint_len, ua->mountpoint);
|
||||
|
||||
stats_send_llu( "\"requests\": %llu, ", ua->requests);
|
||||
stats_send_llu( "\"exceptions\": %llu, ", ua->exceptions);
|
||||
|
||||
if (ua->chdir) {
|
||||
fprintf(output, "\"chdir\": \"%s\", ", ua->chdir);
|
||||
}
|
||||
else {
|
||||
fprintf(output, "\"chdir\": \"\" ");
|
||||
}
|
||||
|
||||
if (j == uwsgi.workers[i+1].apps_cnt-1) {
|
||||
fprintf(output,"}\n");
|
||||
}
|
||||
else {
|
||||
fprintf(output,"},\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output,"\t\t]");
|
||||
|
||||
if (i == uwsgi.numproc-1) {
|
||||
fprintf(output,"}\n");
|
||||
}
|
||||
else {
|
||||
fprintf(output,"},\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output,"]}\n");
|
||||
fclose(output);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
|
||||
uWSGI mules are very simple workers only managing signals or running custom code in background.
|
||||
|
||||
By default they born in signal-only mode, but if you patch them (passing the script/code to run) they will became fully customized daemons.
|
||||
|
||||
*/
|
||||
|
||||
#include "uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void uwsgi_mule_handler(void);
|
||||
|
||||
void uwsgi_mule(int id) {
|
||||
|
||||
int i;
|
||||
|
||||
pid_t pid = uwsgi_fork(uwsgi.mules[id-1].name);
|
||||
if (pid == 0) {
|
||||
uwsgi.muleid = id;
|
||||
// avoid race conditions
|
||||
uwsgi.mules[id-1].id = id;
|
||||
uwsgi.mules[id-1].pid = getpid();
|
||||
|
||||
uwsgi_fixup_fds(0, id);
|
||||
|
||||
uwsgi.my_signal_socket = uwsgi.mules[id-1].signal_pipe[1];
|
||||
uwsgi.signal_socket = uwsgi.shared->mule_signal_pipe[1];
|
||||
|
||||
uwsgi_close_all_sockets();
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->post_fork) {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (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) {
|
||||
uwsgi_log("loaded mule patch %s\n", uwsgi.mules[id-1].patch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_mule_handler();
|
||||
}
|
||||
else if (pid > 0) {
|
||||
uwsgi.mules[id-1].id = id;
|
||||
uwsgi.mules[id-1].pid = pid;
|
||||
uwsgi_log("spawned uWSGI mule %d (pid: %d)\n", id, (int) pid);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
uint8_t uwsgi_signal;
|
||||
int rlen;
|
||||
int interesting_fd;
|
||||
|
||||
// this must be configurable
|
||||
char message[65536];
|
||||
|
||||
int mule_queue = event_queue_init();
|
||||
|
||||
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]);
|
||||
|
||||
uwsgi_mule_add_farm_to_queue(mule_queue);
|
||||
|
||||
for(;;) {
|
||||
rlen = event_queue_wait(mule_queue, -1, &interesting_fd);
|
||||
if (rlen <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket || farm_has_signaled(interesting_fd)) {
|
||||
len = read(interesting_fd, &uwsgi_signal, 1);
|
||||
if (len <= 0) {
|
||||
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
|
||||
end_me(0);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
}
|
||||
else if (interesting_fd == uwsgi.mules[uwsgi.muleid-1].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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ struct uwsgi_fastrouter {
|
||||
int use_cache;
|
||||
int nevents;
|
||||
|
||||
int queue;
|
||||
|
||||
int subscription_slot;
|
||||
|
||||
char *pattern;
|
||||
@@ -61,6 +63,9 @@ struct uwsgi_fastrouter {
|
||||
char *code_string_function;
|
||||
|
||||
struct rb_root *timeouts;
|
||||
|
||||
int cheap;
|
||||
int i_am_cheap;
|
||||
} ufr;
|
||||
|
||||
|
||||
@@ -97,6 +102,7 @@ struct option fastrouter_options[] = {
|
||||
{"fastrouter-use-base", required_argument, 0, LONG_ARGS_FASTROUTER_USE_BASE},
|
||||
{"fastrouter-use-code-string", required_argument, 0, LONG_ARGS_FASTROUTER_USE_CODE_STRING},
|
||||
{"fastrouter-events", required_argument, 0, LONG_ARGS_FASTROUTER_EVENTS},
|
||||
{"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-timeout", required_argument, 0, LONG_ARGS_FASTROUTER_TIMEOUT},
|
||||
@@ -156,8 +162,22 @@ static void close_session(struct fastrouter_session **fr_table, struct fastroute
|
||||
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("marking %.*s as failed\n", (int) fr_session->instance_address_len,fr_session->instance_address);
|
||||
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);
|
||||
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) {
|
||||
uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n");
|
||||
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
|
||||
while(ufr_sock) {
|
||||
event_queue_del_fd(ufr.queue, ufr_sock->fd, event_queue_read());
|
||||
ufr_sock = ufr_sock->next;
|
||||
}
|
||||
ufr.i_am_cheap = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
close(fr_session->instance_fd);
|
||||
fr_table[fr_session->instance_fd] = NULL;
|
||||
@@ -222,7 +242,6 @@ struct fastrouter_session *alloc_fr_session() {
|
||||
|
||||
void fastrouter_loop() {
|
||||
|
||||
int fr_queue;
|
||||
int nevents;
|
||||
int interesting_fd;
|
||||
int new_connection;
|
||||
@@ -269,7 +288,7 @@ void fastrouter_loop() {
|
||||
fr_table[i] = NULL;
|
||||
}
|
||||
|
||||
fr_queue = event_queue_init();
|
||||
ufr.queue = event_queue_init();
|
||||
|
||||
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
|
||||
|
||||
@@ -295,7 +314,13 @@ void fastrouter_loop() {
|
||||
|
||||
uwsgi_log("uwsgi fastrouter/proxy bound on %s\n", ufr_sock->name);
|
||||
|
||||
event_queue_add_fd_read(fr_queue, ufr_sock->fd);
|
||||
if (!ufr.cheap) {
|
||||
event_queue_add_fd_read(ufr.queue, ufr_sock->fd);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("[uwsgi-fastrouter] cheap mode requested. Waiting for subscriptions...\n");
|
||||
ufr.i_am_cheap = 1;
|
||||
}
|
||||
ufr_sock = ufr_sock->next;
|
||||
}
|
||||
|
||||
@@ -305,7 +330,7 @@ void fastrouter_loop() {
|
||||
|
||||
if (ufr.subscription_server) {
|
||||
ufr_subserver = bind_to_udp(ufr.subscription_server, 0, 0);
|
||||
event_queue_add_fd_read(fr_queue, ufr_subserver);
|
||||
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);
|
||||
}
|
||||
@@ -331,7 +356,7 @@ void fastrouter_loop() {
|
||||
}
|
||||
}
|
||||
|
||||
nevents = event_queue_wait_multi(fr_queue, delta, events, ufr.nevents);
|
||||
nevents = event_queue_wait_multi(ufr.queue, delta, events, ufr.nevents);
|
||||
|
||||
if (nevents == 0) {
|
||||
expire_timeouts(fr_table);
|
||||
@@ -364,7 +389,7 @@ void fastrouter_loop() {
|
||||
|
||||
fr_table[new_connection]->timeout = add_timeout(fr_table[new_connection]);
|
||||
|
||||
event_queue_add_fd_read(fr_queue, new_connection);
|
||||
event_queue_add_fd_read(ufr.queue, new_connection);
|
||||
taken = 1;
|
||||
break;
|
||||
}
|
||||
@@ -379,12 +404,21 @@ void fastrouter_loop() {
|
||||
if (interesting_fd == ufr_subserver) {
|
||||
len = recv(ufr_subserver, bbuf, 4096, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(fr_queue, ufr_subserver);
|
||||
event_queue_add_fd_read(ufr.queue, ufr_subserver);
|
||||
#endif
|
||||
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) {
|
||||
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
|
||||
while(ufr_sock) {
|
||||
event_queue_add_fd_read(ufr.queue, ufr_sock->fd);
|
||||
ufr_sock = ufr_sock->next;
|
||||
}
|
||||
ufr.i_am_cheap = 0;
|
||||
uwsgi_log("[uwsgi-fastrouter] leaving cheap mode...\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -498,8 +532,22 @@ void fastrouter_loop() {
|
||||
|
||||
if (fr_session->instance_fd < 0) {
|
||||
if (ufr.subscription_server) {
|
||||
uwsgi_log("marking %.*s as failed\n", (int) fr_session->instance_address_len,fr_session->instance_address);
|
||||
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);
|
||||
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) {
|
||||
uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n");
|
||||
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
|
||||
while(ufr_sock) {
|
||||
event_queue_del_fd(ufr.queue, ufr_sock->fd, event_queue_read());
|
||||
ufr_sock = ufr_sock->next;
|
||||
}
|
||||
ufr.i_am_cheap = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
close_session(fr_table, fr_session);
|
||||
break;
|
||||
@@ -508,7 +556,7 @@ void fastrouter_loop() {
|
||||
|
||||
fr_session->status = FASTROUTER_STATUS_CONNECTING;
|
||||
fr_table[fr_session->instance_fd] = fr_session;
|
||||
event_queue_add_fd_write(fr_queue, fr_session->instance_fd);
|
||||
event_queue_add_fd_write(ufr.queue, fr_session->instance_fd);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -574,7 +622,7 @@ void fastrouter_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
event_queue_fd_write_to_read(fr_queue, fr_session->instance_fd);
|
||||
event_queue_fd_write_to_read(ufr.queue, fr_session->instance_fd);
|
||||
fr_session->status = FASTROUTER_STATUS_RESPONSE;
|
||||
}
|
||||
|
||||
@@ -653,13 +701,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);
|
||||
}
|
||||
|
||||
+189
-73
@@ -10,34 +10,82 @@ struct option gevent_options[] = {
|
||||
#define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, ugevent.greenlet_switch_args, 0, NULL); Py_DECREF(gswitch)
|
||||
#define GET_CURRENT_GREENLET python_call(ugevent.get_current, ugevent.get_current_args, 0, NULL)
|
||||
#define free_req_queue uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req
|
||||
#define stop_the_watchers ret = PyObject_CallMethod(timer, "stop", NULL);\
|
||||
if (ret) Py_DECREF(ret);\
|
||||
ret = PyObject_CallMethod(watcher, "stop", NULL);\
|
||||
if (ret) Py_DECREF(ret);
|
||||
|
||||
struct uwsgi_gevent {
|
||||
PyObject *greenlet_switch;
|
||||
PyObject *greenlet_switch_args;
|
||||
PyObject *get_current;
|
||||
PyObject *get_current_args;
|
||||
PyObject *hub;
|
||||
PyObject *hub_loop;
|
||||
PyObject *spawn;
|
||||
PyObject *greenlet_args;
|
||||
PyObject *signal_args;
|
||||
} ugevent;
|
||||
|
||||
|
||||
PyObject* gevent_wait_io_and_switch(int fd, PyObject *greenlet_switch) {
|
||||
PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", fd, 1);
|
||||
if (!watcher) {
|
||||
PyErr_Print();
|
||||
return NULL;
|
||||
uint8_t uwsgi_signal;
|
||||
int signal_socket;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:uwsgi_gevent_signal_handler", &signal_socket)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (read(signal_socket, &uwsgi_signal, 1) <= 0) {
|
||||
if (uwsgi.no_orphans) {
|
||||
uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid);
|
||||
end_me(0);
|
||||
}
|
||||
// close the socket to end the mess...from now on the worker is alone (no master)
|
||||
else close(signal_socket);
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *ret = PyObject_CallMethod(watcher, "start", "O", greenlet_switch);
|
||||
Py_DECREF(ret);
|
||||
|
||||
return watcher;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_gevent_callback(PyObject * self, PyObject * args) {
|
||||
PyObject *py_uwsgi_gevent_signal(PyObject * self, PyObject * args) {
|
||||
|
||||
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.signal_socket));
|
||||
|
||||
// spawn the signal_handler greenlet
|
||||
PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
|
||||
Py_DECREF(new_gl);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
// yes copy&paste no-DRY for me :P
|
||||
PyObject *py_uwsgi_gevent_my_signal(PyObject * self, PyObject * args) {
|
||||
|
||||
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.my_signal_socket));
|
||||
|
||||
// spawn the signal_handler greenlet
|
||||
PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
|
||||
Py_DECREF(new_gl);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {
|
||||
|
||||
|
||||
struct wsgi_request *wsgi_req = find_first_available_wsgi_req();
|
||||
@@ -48,21 +96,30 @@ PyObject *py_uwsgi_gevent_callback(PyObject * self, PyObject * args) {
|
||||
}
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
// fill wsgi_request structure
|
||||
wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets );
|
||||
|
||||
// mark core as used
|
||||
uwsgi.core[wsgi_req->async_id]->in_request = 1;
|
||||
|
||||
gettimeofday(&wsgi_req->start_of_request, NULL);
|
||||
|
||||
// enter harakiri mode
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
|
||||
}
|
||||
|
||||
// accept the connection
|
||||
if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) {
|
||||
uwsgi_close_request(wsgi_req);
|
||||
free_req_queue;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
|
||||
// hack to easily pass wsgi_req pointer to the greenlet
|
||||
PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req));
|
||||
|
||||
// spawn the request greenlet
|
||||
PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL);
|
||||
Py_DECREF(new_gl);
|
||||
|
||||
@@ -71,8 +128,27 @@ clear:
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
|
||||
PyObject *uwsgi_gevent_wait(PyObject *watcher, PyObject *timer, PyObject *current) {
|
||||
|
||||
PyObject *ret;
|
||||
|
||||
// start the io watcher
|
||||
ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher);
|
||||
if (!ret) return NULL;
|
||||
Py_DECREF(ret);
|
||||
|
||||
// start the timeout handler
|
||||
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
|
||||
if (!ret) return NULL;
|
||||
Py_DECREF(ret);
|
||||
|
||||
// pass control to the hub
|
||||
return PyObject_CallMethod(ugevent.hub, "switch", NULL);
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *ret;
|
||||
PyObject *py_wsgi_req = PyTuple_GetItem(args, 0);
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req);
|
||||
int status ;
|
||||
@@ -80,24 +156,47 @@ PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
|
||||
PyObject *current_greenlet = GET_CURRENT_GREENLET;
|
||||
PyObject *greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch");
|
||||
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
// create a watcher for request socket
|
||||
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1);
|
||||
if (!watcher) goto clear1;
|
||||
|
||||
// a timer to implement timeoit (thanks Denis)
|
||||
PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (!timer) goto clear0;
|
||||
|
||||
for(;;) {
|
||||
// wait for data in the socket
|
||||
PyObject *ret = uwsgi_gevent_wait(watcher, timer, greenlet_switch);
|
||||
if (!ret) goto clear_and_stop;
|
||||
|
||||
// do not forget to overwrite this pointer each time !!!
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
PyObject *watcher = gevent_wait_io_and_switch(wsgi_req->poll.fd, greenlet_switch);
|
||||
if (!watcher) {
|
||||
goto clear;
|
||||
}
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
status = wsgi_req->socket->proto(wsgi_req);
|
||||
PyObject *ret = PyObject_CallMethod(watcher, "stop", NULL);
|
||||
|
||||
// we can safely decref here as watcher and timer has got a +1 for start() method
|
||||
Py_DECREF(ret);
|
||||
Py_DECREF(watcher);
|
||||
if (status < 0) {
|
||||
goto clear;
|
||||
if (ret == timer) {
|
||||
uwsgi_log( "timeout. skip request.\n");
|
||||
goto clear_and_stop;
|
||||
}
|
||||
else if (status == 0) {
|
||||
break;
|
||||
else if (ret == watcher) {
|
||||
|
||||
status = wsgi_req->socket->proto(wsgi_req);
|
||||
if (status < 0) {
|
||||
goto clear_and_stop;
|
||||
}
|
||||
else if (status == 0) {
|
||||
stop_the_watchers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
uwsgi_log("unrecognized gevent event !!!\n");
|
||||
goto clear_and_stop;
|
||||
}
|
||||
|
||||
stop_the_watchers;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
@@ -106,10 +205,21 @@ PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
|
||||
if (wsgi_req->async_status <= UWSGI_OK) {
|
||||
goto clear;
|
||||
}
|
||||
// switch after each yield
|
||||
GEVENT_SWITCH;
|
||||
}
|
||||
|
||||
goto clear;
|
||||
|
||||
clear_and_stop:
|
||||
|
||||
stop_the_watchers;
|
||||
|
||||
clear:
|
||||
Py_DECREF(timer);
|
||||
clear0:
|
||||
Py_DECREF(watcher);
|
||||
clear1:
|
||||
Py_DECREF(greenlet_switch);
|
||||
Py_DECREF(current_greenlet);
|
||||
uwsgi_close_request(wsgi_req);
|
||||
@@ -124,8 +234,11 @@ clear:
|
||||
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_gevent_callback_method[] = { {"uwsgi_gevent_callback", py_uwsgi_gevent_callback, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_greenlet_method[] = { {"uwsgi_gevent_greenlet", py_uwsgi_gevent_greenlet, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_main_def[] = { {"uwsgi_gevent_main", py_uwsgi_gevent_main, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_request_def[] = { {"uwsgi_gevent_request", py_uwsgi_gevent_request, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_signal_def[] = { {"uwsgi_gevent_signal", py_uwsgi_gevent_signal, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_my_signal_def[] = { {"uwsgi_gevent_my_signal", py_uwsgi_gevent_my_signal, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_signal_handler_def[] = { {"uwsgi_gevent_signal_handler", py_uwsgi_gevent_signal_handler, METH_VARARGS, ""} };
|
||||
|
||||
|
||||
void gevent_loop() {
|
||||
@@ -139,16 +252,10 @@ void gevent_loop() {
|
||||
|
||||
|
||||
PyObject *gevent_dict = get_uwsgi_pydict("gevent");
|
||||
if (!gevent_dict) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!gevent_dict) uwsgi_pyexit;
|
||||
|
||||
PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
|
||||
if (!gevent_version) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!gevent_version) uwsgi_pyexit;
|
||||
|
||||
if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) {
|
||||
uwsgi_log("uWSGI requires at least gevent 1.x version\n");
|
||||
@@ -156,16 +263,10 @@ void gevent_loop() {
|
||||
}
|
||||
|
||||
ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
|
||||
if (!ugevent.spawn) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!ugevent.spawn) uwsgi_pyexit;
|
||||
|
||||
ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
|
||||
if (!ugevent.greenlet_switch) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!ugevent.greenlet_switch) uwsgi_pyexit;
|
||||
|
||||
ugevent.greenlet_switch_args = PyTuple_New(0);
|
||||
Py_INCREF(ugevent.greenlet_switch_args);
|
||||
@@ -173,52 +274,67 @@ void gevent_loop() {
|
||||
|
||||
PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");
|
||||
|
||||
PyObject *gevent_hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
|
||||
if (!gevent_hub) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
|
||||
if (!ugevent.hub) uwsgi_pyexit;
|
||||
|
||||
ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent");
|
||||
if (!ugevent.get_current) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!ugevent.get_current) uwsgi_pyexit;
|
||||
|
||||
ugevent.get_current_args = PyTuple_New(0);
|
||||
Py_INCREF(ugevent.get_current_args);
|
||||
|
||||
|
||||
ugevent.hub_loop = PyObject_GetAttrString(gevent_hub, "loop");
|
||||
if (!ugevent.hub_loop) {
|
||||
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop");
|
||||
if (!ugevent.hub_loop) uwsgi_pyexit;
|
||||
|
||||
// this is the watcher for server socket
|
||||
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1);
|
||||
if (!watcher) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!watcher) uwsgi_pyexit;
|
||||
|
||||
// main greenlet waiting for connection
|
||||
PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
|
||||
Py_INCREF(uwsgi_gevent_main);
|
||||
|
||||
PyObject *uwsgi_gevent_callback = PyCFunction_New(uwsgi_gevent_callback_method, NULL);
|
||||
Py_INCREF(uwsgi_gevent_callback);
|
||||
|
||||
PyObject *uwsgi_gevent_greenlet = PyCFunction_New(uwsgi_gevent_greenlet_method, NULL);
|
||||
Py_INCREF(uwsgi_gevent_greenlet);
|
||||
// greenlet to run at each request
|
||||
PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL);
|
||||
Py_INCREF(uwsgi_request_greenlet);
|
||||
|
||||
// pre-fill the greenlet args
|
||||
ugevent.greenlet_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_gevent_greenlet);
|
||||
PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet);
|
||||
|
||||
if (uwsgi.signal_socket > -1) {
|
||||
// and these are the watcher for signal sockets
|
||||
|
||||
PyObject *signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1);
|
||||
if (!signal_watcher) uwsgi_pyexit;
|
||||
|
||||
PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_callback);
|
||||
PyObject *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
|
||||
if (!my_signal_watcher) uwsgi_pyexit;
|
||||
|
||||
if (PyObject_CallMethod(gevent_hub, "switch", NULL)) {
|
||||
PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL);
|
||||
Py_INCREF(uwsgi_greenlet_signal);
|
||||
|
||||
PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL);
|
||||
Py_INCREF(uwsgi_greenlet_my_signal);
|
||||
|
||||
PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL);
|
||||
Py_INCREF(uwsgi_greenlet_signal_handler);
|
||||
|
||||
ugevent.signal_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler);
|
||||
|
||||
// start the two signal watchers
|
||||
if (!PyObject_CallMethod(signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit;
|
||||
if (!PyObject_CallMethod(my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit;
|
||||
|
||||
}
|
||||
|
||||
// start the main greenlet
|
||||
PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_main);
|
||||
|
||||
if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("the gevent Hub is no more :(\n");
|
||||
|
||||
+12
-3
@@ -136,6 +136,8 @@ 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;
|
||||
|
||||
@@ -325,13 +327,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 {
|
||||
@@ -647,6 +655,7 @@ void http_loop() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
uhttp_session->pass_fd = is_unix(uhttp_session->instance_address, uhttp_session->instance_address_len);
|
||||
|
||||
uhttp_session->instance_fd = uwsgi_connectn(uhttp_session->instance_address, uhttp_session->instance_address_len, 0, 1);
|
||||
@@ -882,7 +891,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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+45
-63
@@ -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)) {
|
||||
@@ -280,7 +283,7 @@ int uwsgi_perl_init(){
|
||||
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
int argc = 3;
|
||||
int argc;
|
||||
uperl.embedding[0] = "";
|
||||
uperl.embedding[1] = "-e";
|
||||
uperl.embedding[2] = "0";
|
||||
@@ -298,6 +301,9 @@ int uwsgi_perl_init(){
|
||||
#else
|
||||
uwsgi_log("initializing Perl environment\n");
|
||||
#endif
|
||||
|
||||
argc = 3;
|
||||
|
||||
PERL_SYS_INIT3(&argc, (char ***) &uperl.embedding, &environ);
|
||||
uperl.main = perl_alloc();
|
||||
if (!uperl.main) {
|
||||
@@ -323,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
|
||||
@@ -378,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
|
||||
|
||||
@@ -398,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;
|
||||
|
||||
@@ -428,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;
|
||||
@@ -468,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) {
|
||||
|
||||
@@ -528,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,
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import os,sys
|
||||
|
||||
NAME='psgi'
|
||||
CFLAGS = [os.popen('perl -MExtUtils::Embed -e ccopts').read().rstrip()]
|
||||
LDFLAGS = [os.popen('perl -MExtUtils::Embed -e ldopts').read().rstrip()]
|
||||
CFLAGS = os.popen('perl -MExtUtils::Embed -e ccopts').read().rstrip().split()
|
||||
LDFLAGS = os.popen('perl -MExtUtils::Embed -e ldopts').read().rstrip().split()
|
||||
LIBS = []
|
||||
GCC_LIST = ['uwsgi_plmodule', 'psgi_loader', 'psgi_response', 'psgi_plugin']
|
||||
|
||||
for item in LDFLAGS:
|
||||
if item.endswith('DynaLoader.a'):
|
||||
GCC_LIST.append(item)
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
#ifdef UWSGI_PYPY
|
||||
void gil_real_get() {}
|
||||
void gil_real_release() {}
|
||||
#else
|
||||
|
||||
void gil_real_get() {
|
||||
//uwsgi_log("LOCK %d\n", uwsgi.mywid);
|
||||
#ifndef PYTHREE
|
||||
@@ -26,5 +31,7 @@ void gil_real_release() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void gil_fake_get() {}
|
||||
void gil_fake_release() {}
|
||||
|
||||
@@ -15,6 +15,7 @@ int PyFrame_GetLineNumber(PyFrameObject *frame) {
|
||||
|
||||
int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) {
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
switch(what) {
|
||||
case PyTrace_CALL:
|
||||
uwsgi_log("[uWSGI Python profiler] CALL: %s (line %d) -> %s %d args, stacksize %d\n",
|
||||
@@ -29,6 +30,7 @@ int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, Py
|
||||
PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,11 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->headers_size += wsize;
|
||||
|
||||
PyObject *hhkey, *hhvalue;
|
||||
#ifdef UWSGI_PYTHON_OLD
|
||||
int hhpos = 0;
|
||||
#else
|
||||
Py_ssize_t hhpos = 0;
|
||||
#endif
|
||||
while (PyDict_Next(headers, &hhpos, &hhkey, &hhvalue)) {
|
||||
if (!PyString_Check(hhkey)) continue;
|
||||
|
||||
|
||||
@@ -22,6 +22,57 @@ PyMethodDef uwsgi_eventfd_read_method[] = { {"uwsgi_eventfd_read", py_eventfd_re
|
||||
PyMethodDef uwsgi_eventfd_write_method[] = { {"uwsgi_eventfd_write", py_eventfd_write, METH_VARARGS, ""}};
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
|
||||
void set_dyn_pyhome(char *home, uint16_t pyhome_len) {
|
||||
|
||||
|
||||
char venv_version[15];
|
||||
PyObject *site_module;
|
||||
|
||||
PyObject *pysys_dict = get_uwsgi_pydict("sys");
|
||||
|
||||
PyObject *pypath = pypath = PyDict_GetItemString(pysys_dict, "path");
|
||||
if (!pypath) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// simulate a pythonhome directive
|
||||
if (uwsgi.wsgi_req->pyhome_len > 0) {
|
||||
|
||||
PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->pyhome, uwsgi.wsgi_req->pyhome_len);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("setting dynamic virtualenv to %.*s\n", uwsgi.wsgi_req->pyhome_len, uwsgi.wsgi_req->pyhome);
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString(pysys_dict, "prefix", venv_path);
|
||||
PyDict_SetItemString(pysys_dict, "exec_prefix", venv_path);
|
||||
|
||||
venv_version[14] = 0;
|
||||
if (snprintf(venv_version, 15, "/lib/python%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check here
|
||||
PyString_Concat(&venv_path, PyString_FromString(venv_version));
|
||||
|
||||
if (PyList_Insert(pypath, 0, venv_path)) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
site_module = PyImport_ImportModule("site");
|
||||
if (site_module) {
|
||||
PyImport_ReloadModule(site_module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter, int app_type) {
|
||||
|
||||
PyObject *app_list = NULL, *applications = NULL;
|
||||
@@ -94,7 +145,9 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s = %s\n", PyString_AsString(k), PyString_AsString(env_value));
|
||||
#endif
|
||||
|
||||
if (PyObject_SetItem(py_environ, k, env_value)) {
|
||||
PyErr_Print();
|
||||
@@ -109,7 +162,9 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
if (interpreter == NULL && id) {
|
||||
|
||||
wi->interpreter = Py_NewInterpreter();
|
||||
if (!wi->interpreter) {
|
||||
uwsgi_log( "unable to initialize the new python interpreter\n");
|
||||
@@ -132,6 +187,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
wi->interpreter = up.main_thread;
|
||||
}
|
||||
|
||||
if (wsgi_req->pyhome_len) {
|
||||
set_dyn_pyhome(wsgi_req->pyhome, wsgi_req->pyhome_len);
|
||||
}
|
||||
#else
|
||||
wi->interpreter = up.main_thread;
|
||||
#endif
|
||||
|
||||
if (wsgi_req->touch_reload_len) {
|
||||
struct stat trst;
|
||||
char *touch_reload = uwsgi_strncopy(wsgi_req->touch_reload, wsgi_req->touch_reload_len);
|
||||
@@ -144,7 +206,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
wi->callable = up.loaders[loader](arg1);
|
||||
|
||||
if (!wi->callable) {
|
||||
uwsgi_log("unable to load app mountpoint=%s\n", mountpoint);
|
||||
uwsgi_log("unable to load app %d (mountpoint='%s') (callable not found or import error)\n", id, mountpoint);
|
||||
goto doh;
|
||||
}
|
||||
|
||||
@@ -309,13 +371,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
}
|
||||
|
||||
if (app_type == PYTHON_APP_TYPE_WSGI) {
|
||||
uwsgi_log( "WSGI application %d (mountpoint=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
uwsgi_log( "WSGI application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_WEB3) {
|
||||
uwsgi_log( "Web3 application %d (mountpoint=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
uwsgi_log( "Web3 application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
else if (app_type == PYTHON_APP_TYPE_PUMP) {
|
||||
uwsgi_log( "Pump application %d (mountpoint=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
uwsgi_log( "Pump application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
|
||||
}
|
||||
|
||||
if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
|
||||
@@ -366,6 +428,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
doh:
|
||||
free(mountpoint);
|
||||
PyErr_Print();
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
if (interpreter == NULL && id) {
|
||||
Py_EndInterpreter(wi->interpreter);
|
||||
if (uwsgi.threads > 1) {
|
||||
@@ -375,6 +438,7 @@ doh:
|
||||
PyThreadState_Swap(up.main_thread);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -419,7 +483,9 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
|
||||
|
||||
PyObject *tmp_callable;
|
||||
PyObject *applications;
|
||||
#ifndef UWSGI_PYPY
|
||||
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
|
||||
#endif
|
||||
|
||||
char *module = (char *) arg1;
|
||||
|
||||
@@ -442,8 +508,10 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
applications = PyDict_GetItemString(uwsgi_dict, "applications");
|
||||
if (applications && PyDict_Check(applications)) return applications;
|
||||
#endif
|
||||
|
||||
|
||||
applications = PyDict_GetItemString(wsgi_dict, "applications");
|
||||
@@ -614,6 +682,8 @@ PyObject *uwsgi_paste_loader(void *arg1) {
|
||||
|
||||
PyObject *uwsgi_eval_loader(void *arg1) {
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
|
||||
char *code = (char *) arg1;
|
||||
|
||||
PyObject *wsgi_eval_module, *wsgi_eval_callable = NULL;
|
||||
@@ -669,6 +739,9 @@ PyObject *uwsgi_eval_loader(void *arg1) {
|
||||
}
|
||||
|
||||
return wsgi_eval_callable;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
+109
-58
@@ -16,7 +16,7 @@ struct option uwsgi_python_options[] = {
|
||||
{"module", required_argument, 0, 'w'},
|
||||
{"wsgi", required_argument, 0, 'w'},
|
||||
{"callable", required_argument, 0, LONG_ARGS_CALLABLE},
|
||||
{"test", required_argument, 0, 'j'},
|
||||
{"test", required_argument, 0, 'J'},
|
||||
{"home", required_argument, 0, 'H'},
|
||||
{"virtualenv", required_argument, 0, 'H'},
|
||||
{"venv", required_argument, 0, 'H'},
|
||||
@@ -47,8 +47,12 @@ struct option uwsgi_python_options[] = {
|
||||
{"ignore-script-name", no_argument, &up.ignore_script_name, 1},
|
||||
{"pep3333-input", no_argument, &up.pep3333_input, 1},
|
||||
{"reload-os-env", no_argument, &up.reload_os_env, 1},
|
||||
#ifndef UWSGI_PYPY
|
||||
{"no-site", no_argument, &Py_NoSiteFlag, 1},
|
||||
#endif
|
||||
{"pyshell", no_argument, 0, LONG_ARGS_PYSHELL},
|
||||
{"python", required_argument, 0, LONG_ARGS_PYTHON_RUN},
|
||||
{"py", required_argument, 0, LONG_ARGS_PYTHON_RUN},
|
||||
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
@@ -71,6 +75,7 @@ struct uwsgi_help_item uwsgi_python_help[] = {
|
||||
{"file <file>", "use python file instead of python module for configuration"},
|
||||
{"eval <code>", "evaluate code for app configuration"},
|
||||
{"ini-paste <inifile>", "path of ini config file that contains paste configuration"},
|
||||
{"pyshell", "run a python interactive shell in the uwsgi environment (steals a worker)"},
|
||||
|
||||
|
||||
{ 0, 0},
|
||||
@@ -99,9 +104,14 @@ PyMethodDef uwsgi_write_method[] = { {"uwsgi_write", py_uwsgi_write, METH_VARARG
|
||||
|
||||
int uwsgi_python_init() {
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
char *pyversion = strchr(Py_GetVersion(), '\n');
|
||||
uwsgi_log("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1);
|
||||
#else
|
||||
uwsgi_log("PyPy version: %s\n", PYPY_VERSION);
|
||||
#endif
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
if (up.home != NULL) {
|
||||
#ifdef PYTHREE
|
||||
wchar_t *wpyhome;
|
||||
@@ -130,9 +140,12 @@ int uwsgi_python_init() {
|
||||
#endif
|
||||
|
||||
|
||||
Py_OptimizeFlag = up.optimize;
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
Py_OptimizeFlag = up.optimize;
|
||||
|
||||
#endif
|
||||
|
||||
up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL);
|
||||
up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL);
|
||||
@@ -155,6 +168,7 @@ int uwsgi_python_init() {
|
||||
|
||||
void uwsgi_python_reset_random_seed() {
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
PyObject *random_module, *random_dict, *random_seed;
|
||||
|
||||
// reinitialize the random seed (thanks Jonas Borgström)
|
||||
@@ -174,6 +188,7 @@ void uwsgi_python_reset_random_seed() {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void uwsgi_python_post_fork() {
|
||||
@@ -188,6 +203,7 @@ void uwsgi_python_post_fork() {
|
||||
|
||||
uwsgi_python_reset_random_seed();
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
// call the post_fork_hook
|
||||
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
|
||||
@@ -199,6 +215,7 @@ void uwsgi_python_post_fork() {
|
||||
}
|
||||
PyErr_Clear();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UWSGI_RELEASE_GIL
|
||||
|
||||
@@ -206,6 +223,7 @@ UWSGI_RELEASE_GIL
|
||||
|
||||
PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
FILE *pyfile;
|
||||
struct _node *py_file_node = NULL;
|
||||
PyObject *py_compiled_node, *py_file_module;
|
||||
@@ -214,7 +232,7 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
char *real_filename = filename;
|
||||
|
||||
|
||||
if (strncmp(filename, "http://", 7) && strncmp(filename, "sym://", 6) && strncmp(filename, "data://", 7)) {
|
||||
if (!uwsgi_check_scheme(filename)) {
|
||||
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
@@ -291,10 +309,12 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
}
|
||||
|
||||
return py_file_module;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void init_uwsgi_vars() {
|
||||
|
||||
int i;
|
||||
@@ -303,11 +323,6 @@ void init_uwsgi_vars() {
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
PyObject *tmp_module;
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
char venv_version[15];
|
||||
PyObject *site_module;
|
||||
#endif
|
||||
|
||||
/* add cwd to pythonpath */
|
||||
pysys = PyImport_ImportModule("sys");
|
||||
if (!pysys) {
|
||||
@@ -330,39 +345,6 @@ void init_uwsgi_vars() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
// simulate a pythonhome directive
|
||||
if (uwsgi.wsgi_req->pyhome_len > 0) {
|
||||
|
||||
PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->pyhome, uwsgi.wsgi_req->pyhome_len);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("setting dynamic virtualenv to %.*s\n", uwsgi.wsgi_req->pyhome_len, uwsgi.wsgi_req->pyhome);
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString(pysys_dict, "prefix", venv_path);
|
||||
PyDict_SetItemString(pysys_dict, "exec_prefix", venv_path);
|
||||
|
||||
venv_version[14] = 0;
|
||||
if (snprintf(venv_version, 15, "/lib/python%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check here
|
||||
PyString_Concat(&venv_path, PyString_FromString(venv_version));
|
||||
|
||||
if (PyList_Insert(pypath, 0, venv_path)) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
site_module = PyImport_ImportModule("site");
|
||||
if (site_module) {
|
||||
PyImport_ReloadModule(site_module);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PyList_Insert(pypath, 0, UWSGI_PYFROMSTRING(".")) != 0) {
|
||||
PyErr_Print();
|
||||
}
|
||||
@@ -548,7 +530,12 @@ void init_uwsgi_embedded_module() {
|
||||
if (PyDict_Contains(py_opt_dict, PyString_FromString(uwsgi.exported_opts[i]->key))) {
|
||||
PyObject *py_opt_item = PyDict_GetItemString(py_opt_dict, uwsgi.exported_opts[i]->key);
|
||||
if (PyList_Check(py_opt_item)) {
|
||||
PyList_Append(py_opt_item, PyString_FromString(uwsgi.exported_opts[i]->value));
|
||||
if (uwsgi.exported_opts[i]->value == NULL) {
|
||||
PyList_Append(py_opt_item, Py_True);
|
||||
}
|
||||
else {
|
||||
PyList_Append(py_opt_item, PyString_FromString(uwsgi.exported_opts[i]->value));
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyObject *py_opt_list = PyList_New(0);
|
||||
@@ -681,9 +668,11 @@ void init_uwsgi_embedded_module() {
|
||||
init_uwsgi_module_queue(new_uwsgi_module);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp) {
|
||||
init_uwsgi_module_snmp(new_uwsgi_module);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (up.extension) {
|
||||
up.extension();
|
||||
@@ -750,7 +739,6 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
case LONG_ARGS_PYSHELL:
|
||||
uwsgi.honour_stdin = 1;
|
||||
up.pyshell = 1;
|
||||
uwsgi.to_hell = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_PYIMPORT:
|
||||
uwsgi_string_new_list(&up.import_list, optarg);
|
||||
@@ -774,7 +762,7 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
case LONG_ARGS_PYARGV:
|
||||
up.argv = optarg;
|
||||
return 1;
|
||||
case 'j':
|
||||
case 'J':
|
||||
up.test_module = optarg;
|
||||
return 1;
|
||||
case 'H':
|
||||
@@ -790,12 +778,12 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
|
||||
#ifdef UWSGI_INI
|
||||
case LONG_ARGS_INI_PASTE:
|
||||
uwsgi.ini = optarg;
|
||||
if (uwsgi.ini[0] != '/') {
|
||||
up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", uwsgi.ini);
|
||||
uwsgi_string_new_list(&uwsgi.ini,optarg);
|
||||
if (optarg[0] != '/') {
|
||||
up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", optarg);
|
||||
}
|
||||
else {
|
||||
up.paste = uwsgi_concat2("config:", uwsgi.ini);
|
||||
up.paste = uwsgi_concat2("config:", optarg);
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
@@ -819,14 +807,31 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_python_mount_app(char *mountpoint, char *app) {
|
||||
int uwsgi_python_mount_app(char *mountpoint, char *app, int regexp) {
|
||||
|
||||
int id;
|
||||
uwsgi.wsgi_req->appid = mountpoint;
|
||||
uwsgi.wsgi_req->appid_len = strlen(mountpoint);
|
||||
if (uwsgi.single_interpreter) {
|
||||
return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
id = init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
|
||||
}
|
||||
return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI);
|
||||
id = init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI);
|
||||
|
||||
#ifdef UWSGI_PCRE
|
||||
int i;
|
||||
if (regexp && id != -1) {
|
||||
struct uwsgi_app *ua = &uwsgi_apps[id];
|
||||
uwsgi_regexp_build(mountpoint, &ua->pattern, &ua->pattern_extra);
|
||||
if (uwsgi.mywid == 0) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
uwsgi.workers[i].apps[id].pattern = ua->pattern;
|
||||
uwsgi.workers[i].apps[id].pattern_extra = ua->pattern_extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return id;
|
||||
|
||||
}
|
||||
|
||||
@@ -852,7 +857,7 @@ char *uwsgi_pythonize(char *orig) {
|
||||
name[i] = '_';
|
||||
}
|
||||
else if (name[i] == '/') {
|
||||
name[i] = '.';
|
||||
name[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,7 +874,6 @@ void uwsgi_python_spooler_init(void) {
|
||||
|
||||
struct uwsgi_string_list *upli = up.spooler_import_list;
|
||||
|
||||
|
||||
UWSGI_GET_GIL
|
||||
|
||||
while(upli) {
|
||||
@@ -896,17 +900,22 @@ void uwsgi_python_init_apps() {
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
|
||||
#ifndef UWSGI_PYPY
|
||||
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
|
||||
#endif
|
||||
}
|
||||
|
||||
init_pyargv();
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
#ifndef UWSGI_PYPY
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
init_uwsgi_embedded_module();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef PYTHREE
|
||||
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
|
||||
uwsgi_init_symbol_import();
|
||||
#endif
|
||||
#endif
|
||||
@@ -1011,9 +1020,11 @@ void uwsgi_python_init_apps() {
|
||||
}
|
||||
|
||||
if (uwsgi.profiler) {
|
||||
#ifndef UWSGI_PYPY
|
||||
if (!strcmp(uwsgi.profiler, "pycall")) {
|
||||
PyEval_SetProfile(uwsgi_python_profiler_call, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1064,7 +1075,9 @@ void uwsgi_python_enable_threads() {
|
||||
up.swap_ts = threaded_swap_ts;
|
||||
up.reset_ts = threaded_reset_ts;
|
||||
}
|
||||
|
||||
uwsgi_log("threads support enabled\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1075,6 +1088,9 @@ void uwsgi_python_init_thread(int core_id) {
|
||||
pts = PyThreadState_New(up.main_thread->interp);
|
||||
pthread_setspecific(up.upt_save_key, (void *) pts);
|
||||
pthread_setspecific(up.upt_gil_key, (void *) pts);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("pts %d = %p\n", core_id, pts);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -1128,6 +1144,7 @@ int uwsgi_python_xml(char *node, char *content) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
@@ -1142,6 +1159,7 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
char *uwsgi_python_code_string(char *id, char *code, char *function, char *key, uint16_t keylen) {
|
||||
|
||||
@@ -1211,6 +1229,7 @@ int uwsgi_python_signal_handler(uint8_t sig, void *handler) {
|
||||
ret = python_call(handler, args, 0, NULL);
|
||||
Py_DECREF(args);
|
||||
if (ret) {
|
||||
Py_DECREF(ret);
|
||||
UWSGI_RELEASE_GIL;
|
||||
return 0;
|
||||
}
|
||||
@@ -1329,6 +1348,7 @@ int uwsgi_python_spooler(char *filename, char *buf, uint16_t len, char *body, si
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
@@ -1343,21 +1363,48 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void uwsgi_python_fixup() {
|
||||
// set hacky modifier 30
|
||||
uwsgi.p[30] = uwsgi.p[0];
|
||||
uwsgi.p[30] = uwsgi_malloc( sizeof(struct uwsgi_plugin) );
|
||||
memcpy(uwsgi.p[30], uwsgi.p[0], sizeof(struct uwsgi_plugin) );
|
||||
uwsgi.p[30]->init_thread = NULL;
|
||||
}
|
||||
|
||||
void uwsgi_python_hijack(void) {
|
||||
// the pyshell will be execute only in the first worker
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
if (up.pyshell && uwsgi.mywid == 1) {
|
||||
// re-map stdin to stdout and stderr if we are logging to a file
|
||||
if (uwsgi.logfile) {
|
||||
if (dup2(0, 1) < 0) {
|
||||
uwsgi_error("dup2()");
|
||||
}
|
||||
if (dup2(0, 2) < 0) {
|
||||
uwsgi_error("dup2()");
|
||||
}
|
||||
}
|
||||
UWSGI_GET_GIL;
|
||||
PyImport_ImportModule("readline");
|
||||
PyRun_InteractiveLoop(stdin, "uwsgi");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int uwsgi_python_mule(char *opt) {
|
||||
|
||||
if (uwsgi_endswith(opt, ".py")) {
|
||||
UWSGI_GET_GIL;
|
||||
uwsgi_pyimport_by_filename("__main__", opt);
|
||||
UWSGI_RELEASE_GIL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_plugin python_plugin = {
|
||||
@@ -1369,7 +1416,7 @@ struct uwsgi_plugin python_plugin = {
|
||||
.post_fork = uwsgi_python_post_fork,
|
||||
.options = uwsgi_python_options,
|
||||
.manage_opt = uwsgi_python_manage_options,
|
||||
.short_options = "w:O:H:j:",
|
||||
.short_options = "w:O:H:J:",
|
||||
.request = uwsgi_request_wsgi,
|
||||
.after_request = uwsgi_after_request_wsgi,
|
||||
.init_apps = uwsgi_python_init_apps,
|
||||
@@ -1385,8 +1432,10 @@ struct uwsgi_plugin python_plugin = {
|
||||
|
||||
.magic = uwsgi_python_magic,
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
.suspend = uwsgi_python_suspend,
|
||||
.resume = uwsgi_python_resume,
|
||||
#endif
|
||||
|
||||
.hijack_worker = uwsgi_python_hijack,
|
||||
.spooler_init = uwsgi_python_spooler_init,
|
||||
@@ -1394,6 +1443,8 @@ struct uwsgi_plugin python_plugin = {
|
||||
.signal_handler = uwsgi_python_signal_handler,
|
||||
.rpc = uwsgi_python_rpc,
|
||||
|
||||
.mule = uwsgi_python_mule,
|
||||
|
||||
.spooler = uwsgi_python_spooler,
|
||||
|
||||
.code_string = uwsgi_python_code_string,
|
||||
|
||||
@@ -72,8 +72,9 @@ void init_pyargv() {
|
||||
up.py_argv[0] = "uwsgi";
|
||||
#endif
|
||||
|
||||
if (up.argv != NULL && !up.argc) {
|
||||
up.argc++;
|
||||
up.argc = 1;
|
||||
|
||||
if (up.argv != NULL) {
|
||||
#ifdef PYTHREE
|
||||
wchar_t *wcargv = malloc( sizeof( wchar_t ) * (strlen(up.argv)+1));
|
||||
if (!wcargv) {
|
||||
@@ -104,7 +105,20 @@ void init_pyargv() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
PySys_SetArgv(up.argc, up.py_argv);
|
||||
#endif
|
||||
|
||||
PyObject *sys_dict = get_uwsgi_pydict("sys");
|
||||
if (!sys_dict) {
|
||||
uwsgi_log("unable to load python sys module !!!\n");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef PYTHREE
|
||||
PyDict_SetItemString(sys_dict, "executable", PyUnicode_FromString(uwsgi.binary_path));
|
||||
#else
|
||||
PyDict_SetItemString(sys_dict, "executable", PyString_FromString(uwsgi.binary_path));
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "uwsgi_python.h"
|
||||
|
||||
#ifndef PYTHREE
|
||||
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
@@ -363,7 +363,7 @@ static PyMethodDef symzipimporter_methods[] = {
|
||||
};
|
||||
|
||||
static void uwsgi_symimporter_free(struct _symimporter *self) {
|
||||
PyObject_Del(self);
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
|
||||
@@ -406,7 +406,7 @@ static PyTypeObject SymImporter_Type = {
|
||||
0, /* tp_init */
|
||||
PyType_GenericAlloc, /* tp_alloc */
|
||||
PyType_GenericNew, /* tp_new */
|
||||
PyObject_GC_Del, /* tp_free */
|
||||
0, /* tp_free */
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -424,7 +424,7 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
|
||||
// avoid GC !!!
|
||||
name = uwsgi_concat2(name, "");
|
||||
|
||||
if (!uwsgi_startswith(name, "http://", 7) || !uwsgi_startswith(name, "data://", 7) || !uwsgi_startswith(name, "sym://", 6) ) {
|
||||
if (uwsgi_check_scheme(name)) {
|
||||
prefix = uwsgi_get_last_char(name, '/');
|
||||
prefix = uwsgi_get_last_char(prefix, ':');
|
||||
}
|
||||
@@ -442,34 +442,44 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *stringio = PyImport_ImportModule("StringIO");
|
||||
if (!stringio) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PyObject *stringio_dict = PyModule_GetDict(stringio);
|
||||
if (!stringio_dict) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PyObject *stringio_stringio = PyDict_GetItemString(stringio_dict, "StringIO");
|
||||
if (!stringio_stringio) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PyObject *stringio_args = PyTuple_New(1);
|
||||
PyTuple_SetItem(stringio_args, 0, PyString_FromStringAndSize(body, len));
|
||||
|
||||
|
||||
PyObject *source_code = PyInstance_New(stringio_stringio, stringio_args, NULL);
|
||||
if (!source_code) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PyObject *zipfile = PyImport_ImportModule("zipfile");
|
||||
|
||||
if (!zipfile) {
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PyObject *zipfile_dict = PyModule_GetDict(zipfile);
|
||||
if (!zipfile_dict) {
|
||||
return -1;
|
||||
@@ -480,6 +490,7 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PyObject *zipfile_args = PyTuple_New(1);
|
||||
PyTuple_SetItem(zipfile_args, 0, source_code);
|
||||
|
||||
@@ -644,7 +655,7 @@ static PyTypeObject SymZipImporter_Type = {
|
||||
(initproc) symzipimporter_init, /* tp_init */
|
||||
PyType_GenericAlloc, /* tp_alloc */
|
||||
PyType_GenericNew, /* tp_new */
|
||||
PyObject_GC_Del, /* tp_free */
|
||||
0, /* tp_free */
|
||||
};
|
||||
|
||||
static PyTypeObject ZipImporter_Type = {
|
||||
@@ -686,7 +697,7 @@ static PyTypeObject ZipImporter_Type = {
|
||||
(initproc) zipimporter_init, /* tp_init */
|
||||
PyType_GenericAlloc, /* tp_alloc */
|
||||
PyType_GenericNew, /* tp_new */
|
||||
PyObject_GC_Del, /* tp_free */
|
||||
0, /* tp_free */
|
||||
};
|
||||
|
||||
|
||||
|
||||
+375
-36
@@ -29,6 +29,9 @@ PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
||||
UWSGI_RELEASE_GIL;
|
||||
|
||||
pfd[0].fd = uwsgi.signal_socket;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = uwsgi.my_signal_socket;
|
||||
@@ -55,6 +58,7 @@ cycle:
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
|
||||
if (uwsgi_signal_handler(received_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on worker %d\n", received_signal, uwsgi.mywid);
|
||||
}
|
||||
@@ -64,8 +68,11 @@ cycle:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UWSGI_GET_GIL;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
}
|
||||
#endif
|
||||
@@ -827,7 +834,7 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *what;
|
||||
char *filename;
|
||||
size_t chunk;
|
||||
size_t chunk = 0;
|
||||
off_t pos = 0;
|
||||
size_t filesize = 0;
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
@@ -883,7 +890,20 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
||||
wsgi_req->sendfile_fd_pos = pos;
|
||||
|
||||
// do sendfile
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
if (uwsgi.async > 1) {
|
||||
ssize_t sf_len = uwsgi_sendfile(wsgi_req);
|
||||
if (sf_len > 0) {
|
||||
wsgi_req->response_size += sf_len;
|
||||
while((size_t)wsgi_req->sendfile_fd_pos < wsgi_req->sendfile_fd_size) {
|
||||
sf_len = uwsgi_sendfile(wsgi_req);
|
||||
if (sf_len <= 0) break;
|
||||
wsgi_req->response_size += sf_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
}
|
||||
|
||||
// revert to old values
|
||||
wsgi_req->sendfile_fd = tmp_fd;
|
||||
@@ -961,15 +981,38 @@ PyObject *py_uwsgi_log(PyObject * self, PyObject * args) {
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
|
||||
|
||||
int lock_num = 0;
|
||||
|
||||
// the spooler cannot lock resources
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
|
||||
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
||||
}
|
||||
#endif
|
||||
uwsgi_lock(uwsgi.user_lock);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|i:lock", &lock_num)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
||||
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
|
||||
}
|
||||
|
||||
uwsgi_lock(uwsgi.user_lock[lock_num]);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
@@ -977,12 +1020,23 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
|
||||
|
||||
int lock_num = 0;
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
|
||||
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|i:unlock", &lock_num)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
||||
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
|
||||
}
|
||||
|
||||
|
||||
uwsgi_unlock(uwsgi.user_lock);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
@@ -1018,6 +1072,200 @@ 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;
|
||||
ssize_t len;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#|i:mule_msg", &message, &message_len, &mule_id)) {
|
||||
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 (len <= 0) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_mule_get_msg(PyObject * self, PyObject * args) {
|
||||
|
||||
ssize_t len;
|
||||
// this buffer will be configurable
|
||||
char message[65536];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return PyString_FromStringAndSize(message, len);
|
||||
}
|
||||
|
||||
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 mule 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;
|
||||
int len;
|
||||
char *buf;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:extract", &name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = uwsgi_open_and_read(name, &len, 0, NULL);
|
||||
if (buf && len > 0) {
|
||||
return PyString_FromStringAndSize(buf, len);
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
|
||||
PyObject *py_uwsgi_sharedarea_inclong(PyObject * self, PyObject * args) {
|
||||
uint64_t pos = 0;
|
||||
uint64_t value = 1;
|
||||
@@ -1480,7 +1728,6 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *arg_modifier1, *arg_modifier2, *arg_timeout;
|
||||
|
||||
PyObject *marshalled;
|
||||
PyObject *retobject;
|
||||
|
||||
|
||||
@@ -1549,6 +1796,8 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
PyObject *marshalled;
|
||||
switch (PyInt_AsLong(arg_modifier1)) {
|
||||
case UWSGI_MODIFIER_MESSAGE_MARSHAL:
|
||||
marshalled = PyMarshal_WriteObjectToString(arg_message, 1);
|
||||
@@ -1563,6 +1812,7 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
@@ -1890,7 +2140,7 @@ PyObject *py_uwsgi_async_connect(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *pyobj = NULL, *marshalled = NULL;
|
||||
PyObject *pyobj = NULL;
|
||||
|
||||
int uwsgi_fd;
|
||||
int modifier1 = 0;
|
||||
@@ -1919,8 +2169,9 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
|
||||
esize = PyString_Size(pyobj);
|
||||
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
|
||||
}
|
||||
#ifndef UWSGI_PYPY
|
||||
else {
|
||||
marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
|
||||
PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
|
||||
if (!marshalled) {
|
||||
PyErr_Print();
|
||||
goto clear;
|
||||
@@ -1930,6 +2181,7 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
|
||||
esize = PyString_Size(marshalled);
|
||||
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
UWSGI_GET_GIL clear:
|
||||
|
||||
@@ -2030,7 +2282,7 @@ PyObject *py_uwsgi_fcgi(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *destination = NULL, *pyobj = NULL, *marshalled = NULL;
|
||||
PyObject *destination = NULL, *pyobj = NULL;
|
||||
|
||||
int modifier1 = 0;
|
||||
int modifier2 = 0;
|
||||
@@ -2075,8 +2327,9 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) {
|
||||
esize = PyString_Size(pyobj);
|
||||
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout);
|
||||
}
|
||||
#ifndef UWSGI_PYPY
|
||||
else {
|
||||
marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
|
||||
PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
|
||||
if (!marshalled) {
|
||||
PyErr_Print();
|
||||
goto clear;
|
||||
@@ -2086,6 +2339,7 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) {
|
||||
esize = PyString_Size(marshalled);
|
||||
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
UWSGI_GET_GIL
|
||||
|
||||
@@ -2132,7 +2386,7 @@ PyObject *py_uwsgi_masterpid(PyObject * self, PyObject * args) {
|
||||
|
||||
/* uWSGI total_requests */
|
||||
PyObject *py_uwsgi_total_requests(PyObject * self, PyObject * args) {
|
||||
return PyInt_FromLong(uwsgi.workers[0].requests);
|
||||
return PyLong_FromUnsignedLongLong(uwsgi.workers[0].requests);
|
||||
}
|
||||
|
||||
/* uWSGI workers */
|
||||
@@ -2162,31 +2416,57 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyInt_FromLong(uwsgi.workers[i + 1].requests);
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].requests);
|
||||
if (PyDict_SetItemString(worker_dict, "requests", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyInt_FromLong(uwsgi.workers[i + 1].exceptions);
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].signals);
|
||||
if (PyDict_SetItemString(worker_dict, "signals", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].exceptions);
|
||||
if (PyDict_SetItemString(worker_dict, "exceptions", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyInt_FromLong(uwsgi.workers[i + 1].rss_size);
|
||||
if (uwsgi.workers[i + 1].cheaped) {
|
||||
zero = PyString_FromString("cheap");
|
||||
}
|
||||
else {
|
||||
if (uwsgi.workers[i + 1].sig) {
|
||||
zero = PyString_FromFormat("sig%d",uwsgi.workers[i + 1].signum);
|
||||
}
|
||||
else if (uwsgi.workers[i + 1].busy) {
|
||||
zero = PyString_FromString("busy");
|
||||
}
|
||||
else {
|
||||
zero = PyString_FromString("idle");
|
||||
}
|
||||
}
|
||||
if (PyDict_SetItemString(worker_dict, "status", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].rss_size);
|
||||
if (PyDict_SetItemString(worker_dict, "rss", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyInt_FromLong(uwsgi.workers[i + 1].vsz_size);
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].vsz_size);
|
||||
if (PyDict_SetItemString(worker_dict, "vsz", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyFloat_FromDouble(uwsgi.workers[i + 1].running_time);
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].running_time);
|
||||
if (PyDict_SetItemString(worker_dict, "running_time", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
@@ -2198,20 +2478,23 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyLong_FromLong(uwsgi.workers[i + 1].respawn_count);
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].respawn_count-1);
|
||||
if (PyDict_SetItemString(worker_dict, "respawn_count", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
/* return a tuple of current status ! (in_request, blocking, locking, )
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].tx);
|
||||
if (PyDict_SetItemString(worker_dict, "tx", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
zero = PyLong_FromLong(uwsgi.workers[i+1].in_request);
|
||||
if (PyDict_SetItemString(worker_dict, "in_request", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
*/
|
||||
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].avg_response_time);
|
||||
if (PyDict_SetItemString(worker_dict, "avg_rt", zero)) {
|
||||
goto clear;
|
||||
}
|
||||
Py_DECREF(zero);
|
||||
|
||||
apps_tuple = PyTuple_New(uwsgi.workers[i+1].apps_cnt);
|
||||
|
||||
@@ -2230,8 +2513,8 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
|
||||
PyDict_SetItemString(apps_dict, "interpreter", PyInt_FromLong((long)ua->interpreter));
|
||||
PyDict_SetItemString(apps_dict, "callable", PyInt_FromLong((long)ua->interpreter));
|
||||
|
||||
PyDict_SetItemString(apps_dict, "requests", PyInt_FromLong(ua->requests));
|
||||
PyDict_SetItemString(apps_dict, "exceptions", PyInt_FromLong(ua->exceptions));
|
||||
PyDict_SetItemString(apps_dict, "requests", PyLong_FromUnsignedLongLong(ua->requests));
|
||||
PyDict_SetItemString(apps_dict, "exceptions", PyLong_FromUnsignedLongLong(ua->exceptions));
|
||||
|
||||
if (ua->chdir) {
|
||||
zero = PyString_FromString(ua->chdir);
|
||||
@@ -2278,6 +2561,20 @@ PyObject *py_uwsgi_reload(PyObject * self, PyObject * args) {
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
/* uWSGI stop */
|
||||
PyObject *py_uwsgi_stop(PyObject * self, PyObject * args) {
|
||||
|
||||
if (kill(uwsgi.workers[0].pid, SIGQUIT)) {
|
||||
uwsgi_error("kill()");
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
|
||||
/* blocking hint */
|
||||
PyObject *py_uwsgi_set_blocking(PyObject * self, PyObject * args) {
|
||||
|
||||
@@ -2293,25 +2590,30 @@ PyObject *py_uwsgi_set_blocking(PyObject * self, PyObject * args) {
|
||||
|
||||
|
||||
PyObject *py_uwsgi_request_id(PyObject * self, PyObject * args) {
|
||||
return PyInt_FromLong(uwsgi.workers[uwsgi.mywid].requests);
|
||||
return PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].requests);
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_worker_id(PyObject * self, PyObject * args) {
|
||||
return PyInt_FromLong(uwsgi.mywid);
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_mule_id(PyObject * self, PyObject * args) {
|
||||
return PyInt_FromLong(uwsgi.muleid);
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_logsize(PyObject * self, PyObject * args) {
|
||||
return PyInt_FromLong(uwsgi.shared->logsize);
|
||||
return PyLong_FromUnsignedLongLong(uwsgi.shared->logsize);
|
||||
}
|
||||
|
||||
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_FromLong(uwsgi.workers[uwsgi.mywid].rss_size));
|
||||
PyTuple_SetItem(ml, 1, PyLong_FromLong(uwsgi.workers[uwsgi.mywid].vsz_size));
|
||||
PyTuple_SetItem(ml, 0, PyLong_FromUnsignedLongLong(rss));
|
||||
PyTuple_SetItem(ml, 1, PyLong_FromUnsignedLongLong(vsz));
|
||||
|
||||
return ml;
|
||||
|
||||
@@ -2321,7 +2623,7 @@ PyObject *py_uwsgi_cl(PyObject * self, PyObject * args) {
|
||||
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
|
||||
return PyLong_FromLong(wsgi_req->post_cl);
|
||||
return PyLong_FromUnsignedLongLong(wsgi_req->post_cl);
|
||||
|
||||
}
|
||||
|
||||
@@ -2463,6 +2765,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()");
|
||||
@@ -2615,6 +2918,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"send_message", py_uwsgi_send_message, METH_VARARGS, ""},
|
||||
{"send_multi_message", py_uwsgi_send_multi_message, METH_VARARGS, ""},
|
||||
{"reload", py_uwsgi_reload, METH_VARARGS, ""},
|
||||
{"stop", py_uwsgi_stop, METH_VARARGS, ""},
|
||||
{"workers", py_uwsgi_workers, METH_VARARGS, ""},
|
||||
{"masterpid", py_uwsgi_masterpid, METH_VARARGS, ""},
|
||||
{"total_requests", py_uwsgi_total_requests, METH_VARARGS, ""},
|
||||
@@ -2625,6 +2929,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"sorry_i_need_to_block", py_uwsgi_set_blocking, METH_VARARGS, ""},
|
||||
{"request_id", py_uwsgi_request_id, METH_VARARGS, ""},
|
||||
{"worker_id", py_uwsgi_worker_id, METH_VARARGS, ""},
|
||||
{"mule_id", py_uwsgi_mule_id, METH_VARARGS, ""},
|
||||
{"log", py_uwsgi_log, METH_VARARGS, ""},
|
||||
{"log_this_request", py_uwsgi_log_this, METH_VARARGS, ""},
|
||||
{"disconnect", py_uwsgi_disconnect, METH_VARARGS, ""},
|
||||
@@ -2634,6 +2939,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, ""},
|
||||
@@ -2684,11 +2991,19 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""},
|
||||
{"recv_frame", py_uwsgi_recv_frame, METH_VARARGS, ""},
|
||||
{"close", py_uwsgi_close, METH_VARARGS, ""},
|
||||
{"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""},
|
||||
|
||||
{"fcgi", py_uwsgi_fcgi, METH_VARARGS, ""},
|
||||
|
||||
{"parsefile", py_uwsgi_parse_file, METH_VARARGS, ""},
|
||||
{"embedded_data", py_uwsgi_embedded_data, METH_VARARGS, ""},
|
||||
{"extract", py_uwsgi_extract, METH_VARARGS, ""},
|
||||
|
||||
{"mule_msg", py_uwsgi_mule_msg, METH_VARARGS, ""},
|
||||
{"farm_msg", py_uwsgi_farm_msg, METH_VARARGS, ""},
|
||||
{"mule_get_msg", py_uwsgi_mule_get_msg, METH_VARARGS, ""},
|
||||
{"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},
|
||||
@@ -2902,12 +3217,12 @@ PyObject *py_uwsgi_queue_set(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_queue_slot(PyObject * self, PyObject * args) {
|
||||
|
||||
return PyInt_FromLong(uwsgi.queue_header->pos);
|
||||
return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pos);
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_queue_pull_slot(PyObject * self, PyObject * args) {
|
||||
|
||||
return PyInt_FromLong(uwsgi.queue_header->pull_pos);
|
||||
return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pull_pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -2996,23 +3311,44 @@ PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
|
||||
long num = 0;
|
||||
uint64_t size = 0;
|
||||
char *message;
|
||||
PyObject *res, *zero;
|
||||
PyObject *res = NULL, *zero;
|
||||
uint64_t base;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l:queue_last", &num)) {
|
||||
if (!PyArg_ParseTuple(args, "|l:queue_last", &num)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi.queue_size) {
|
||||
res = PyList_New(0);
|
||||
|
||||
if (num > 0) {
|
||||
res = PyList_New(0);
|
||||
}
|
||||
|
||||
uwsgi_rlock(uwsgi.queue_lock);
|
||||
|
||||
if (uwsgi.queue_header->pos > 0) {
|
||||
base = uwsgi.queue_header->pos-1;
|
||||
}
|
||||
else {
|
||||
base = uwsgi.queue_size-1;
|
||||
}
|
||||
|
||||
if (num == 0) {
|
||||
message = uwsgi_queue_get(base, &size);
|
||||
if (message && size) {
|
||||
res = PyString_FromStringAndSize(message, size);
|
||||
}
|
||||
else {
|
||||
Py_INCREF(Py_None);
|
||||
res = Py_None;
|
||||
}
|
||||
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
|
||||
|
||||
while(num) {
|
||||
message = uwsgi_queue_get(base, &size);
|
||||
if (message && size) {
|
||||
@@ -3064,6 +3400,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize16, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (valsize16 > 0) {
|
||||
value = buffer;
|
||||
valsize = valsize16;
|
||||
}
|
||||
}
|
||||
else if (uwsgi.cache_max_items) {
|
||||
@@ -3196,7 +3533,7 @@ void init_uwsgi_module_queue(PyObject * current_uwsgi_module) {
|
||||
Py_DECREF(func);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyInt_FromLong(uwsgi.queue_size));
|
||||
PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyLong_FromUnsignedLongLong(uwsgi.queue_size));
|
||||
}
|
||||
|
||||
|
||||
@@ -3217,6 +3554,7 @@ void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
PyObject *py_snmp_counter32(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t oid_num;
|
||||
@@ -3337,6 +3675,7 @@ void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) {
|
||||
|
||||
uwsgi_log( "SNMP python functions initialized.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define LONG_ARGS_WSGI_LITE LONG_ARGS_PYTHON_BASE + 10
|
||||
#define LONG_ARGS_PYSHELL LONG_ARGS_PYTHON_BASE + 11
|
||||
#define LONG_ARGS_SPOOLER_PYIMPORT LONG_ARGS_PYTHON_BASE + 12
|
||||
#define LONG_ARGS_PYTHON_RUN LONG_ARGS_PYTHON_BASE + 13
|
||||
|
||||
#define PYTHON_APP_TYPE_WSGI 0
|
||||
#define PYTHON_APP_TYPE_WEB3 1
|
||||
@@ -29,6 +30,7 @@
|
||||
|
||||
#if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2
|
||||
#define Py_ssize_t ssize_t
|
||||
#define UWSGI_PYTHON_OLD
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
|
||||
@@ -94,9 +96,11 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
|
||||
|
||||
#define LOADER_MAX 8
|
||||
|
||||
#define UWSGI_PY_READLINE_BUFSIZE 1024
|
||||
|
||||
typedef struct uwsgi_Input {
|
||||
PyObject_HEAD
|
||||
char readline[1024];
|
||||
char readline[UWSGI_PY_READLINE_BUFSIZE];
|
||||
size_t readline_size;
|
||||
size_t readline_max_size;
|
||||
size_t readline_pos;
|
||||
@@ -264,6 +268,12 @@ void uwsgi_python_reset_random_seed(void);
|
||||
|
||||
char *uwsgi_pythonize(char *);
|
||||
|
||||
#ifdef UWSGI_PYPY
|
||||
#undef UWSGI_MINTERPRETERS
|
||||
#endif
|
||||
|
||||
#define uwsgi_pyexit {PyErr_Print();exit(1);}
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef PYTHREE
|
||||
int uwsgi_init_symbol_import(void);
|
||||
|
||||
@@ -4,28 +4,36 @@ from distutils import sysconfig
|
||||
|
||||
NAME='python'
|
||||
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter']
|
||||
#OBJ_LIST = ['/usr/lib/libpython2.6.a']
|
||||
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ]
|
||||
|
||||
if 'pypy_version_info' in sys.__dict__:
|
||||
CFLAGS.append('-DUWSGI_PYPY')
|
||||
|
||||
LDFLAGS = []
|
||||
|
||||
LIBS = sysconfig.get_config_var('LIBS').split() + sysconfig.get_config_var('SYSLIBS').split()
|
||||
if not sysconfig.get_config_var('Py_ENABLE_SHARED'):
|
||||
if not 'UWSGI_PYTHON_NOLIB' in os.environ:
|
||||
LIBS = sysconfig.get_config_var('LIBS').split() + sysconfig.get_config_var('SYSLIBS').split()
|
||||
if not sysconfig.get_config_var('Py_ENABLE_SHARED'):
|
||||
LIBS.append('-L' + sysconfig.get_config_var('LIBPL'))
|
||||
else:
|
||||
try:
|
||||
LDFLAGS.append("-L%s" % sysconfig.get_config_var('LIBDIR'))
|
||||
os.environ['LD_RUN_PATH'] = "%s" % (sysconfig.get_config_var('LIBDIR'))
|
||||
except:
|
||||
LDFLAGS.append("-L%s/lib" % sysconfig.PREFIX)
|
||||
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
|
||||
|
||||
|
||||
version = sysconfig.get_config_var('VERSION')
|
||||
try:
|
||||
version = version + sys.abiflags
|
||||
except:
|
||||
pass
|
||||
LIBS.append('-lpython' + version)
|
||||
else:
|
||||
try:
|
||||
LDFLAGS.append("-L%s" % sysconfig.get_config_var('LIBDIR'))
|
||||
os.environ['LD_RUN_PATH'] = "%s" % (sysconfig.get_config_var('LIBDIR'))
|
||||
except:
|
||||
LDFLAGS.append("-L%s/lib" % sysconfig.PREFIX)
|
||||
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
|
||||
|
||||
|
||||
version = sysconfig.get_config_var('VERSION')
|
||||
try:
|
||||
version = version + sys.abiflags
|
||||
except:
|
||||
pass
|
||||
LIBS.append('-lpython' + version)
|
||||
LIBS = []
|
||||
|
||||
#if str(PYLIB_PATH) != '':
|
||||
# libs.insert(0,'-L' + PYLIB_PATH)
|
||||
|
||||
@@ -46,11 +46,11 @@ PyObject *uwsgi_Input_getline(uwsgi_Input *self) {
|
||||
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data");
|
||||
}
|
||||
|
||||
if (self->readline_max_size > 0 && self->readline_max_size < 1024) {
|
||||
if (self->readline_max_size > 0 && self->readline_max_size < UWSGI_PY_READLINE_BUFSIZE) {
|
||||
rlen = read(wsgi_req->poll.fd, self->readline, self->readline_max_size);
|
||||
}
|
||||
else {
|
||||
rlen = read(wsgi_req->poll.fd, self->readline, 1024);
|
||||
rlen = read(wsgi_req->poll.fd, self->readline, UWSGI_PY_READLINE_BUFSIZE);
|
||||
}
|
||||
if (rlen <= 0) {
|
||||
UWSGI_GET_GIL
|
||||
|
||||
@@ -191,9 +191,6 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
UWSGI_RELEASE_GIL
|
||||
iov_ret = wsgi_req->socket->proto_writev_header(wsgi_req, iov_ptr, iov_size);
|
||||
UWSGI_GET_GIL
|
||||
if (iov_ret < 0) {
|
||||
uwsgi_error("writev()");
|
||||
}
|
||||
wsgi_req->headers_size += iov_ret;
|
||||
iov_ptr += iov_size;
|
||||
remains -= iov_size;
|
||||
@@ -202,9 +199,6 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
UWSGI_RELEASE_GIL
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, j + 1);
|
||||
UWSGI_GET_GIL
|
||||
if (wsgi_req->headers_size < 0) {
|
||||
uwsgi_error("writev()");
|
||||
}
|
||||
#endif
|
||||
|
||||
//uwsgi_log("%d %p\n", wsgi_req->poll.fd, up.wsgi_writeout);
|
||||
|
||||
@@ -22,12 +22,15 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%p %d %p %d\n", pydictkey, wsgi_req->hvec[i].iov_len, pydictvalue, wsgi_req->hvec[i + 1].iov_len);
|
||||
#endif
|
||||
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
|
||||
Py_DECREF(pydictkey);
|
||||
Py_DECREF(pydictvalue);
|
||||
}
|
||||
|
||||
|
||||
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
|
||||
wsgi_req->uh.modifier1 = 0;
|
||||
pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
|
||||
@@ -44,6 +47,8 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef UWSGI_PYPY
|
||||
// if async_post is mapped as a file, directly use it as wsgi.input
|
||||
if (wsgi_req->async_post) {
|
||||
#ifdef PYTHREE
|
||||
@@ -62,7 +67,9 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
|
||||
}
|
||||
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input);
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SENDFILE
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile);
|
||||
@@ -78,12 +85,16 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version);
|
||||
|
||||
zero = PyFile_FromFile(stderr, "wsgi_input", "w", NULL);
|
||||
#ifndef UWSGI_PYPY
|
||||
zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero);
|
||||
Py_DECREF(zero);
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False);
|
||||
|
||||
|
||||
|
||||
if (uwsgi.threads > 1) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_True);
|
||||
}
|
||||
@@ -117,10 +128,13 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
|
||||
wsgi_req->async_app = wi->callable;
|
||||
|
||||
|
||||
// export .env only in non-threaded mode
|
||||
#ifndef UWSGI_PYPY
|
||||
if (uwsgi.threads < 2) {
|
||||
PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
|
||||
}
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);
|
||||
|
||||
@@ -180,7 +194,11 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
#ifdef UWSGI_SENDFILE
|
||||
#ifdef __FreeBSD__
|
||||
if ( ((wsgi_req->sendfile_obj == wsgi_req->async_result) || ( wsgi_req->sendfile_fd_size > 0 && wsgi_req->response_size < wsgi_req->sendfile_fd_size)) && wsgi_req->sendfile_fd != -1) {
|
||||
#else
|
||||
if (wsgi_req->sendfile_obj == wsgi_req->async_result && wsgi_req->sendfile_fd != -1) {
|
||||
#endif
|
||||
sf_len = uwsgi_sendfile(wsgi_req);
|
||||
if (sf_len < 1) goto clear;
|
||||
wsgi_req->response_size += sf_len;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "../python/uwsgi_python.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
extern char **environ;
|
||||
|
||||
PyObject *u_run(PyObject *self, PyObject *args) {
|
||||
|
||||
char **argv;
|
||||
size_t size = 2;
|
||||
int i;
|
||||
|
||||
if (PyTuple_Size(args) < 1) {
|
||||
return PyErr_Format(PyExc_ValueError, "you have to specify at least one uWSGI option to run() it");
|
||||
}
|
||||
|
||||
PyObject *the_arg = PyTuple_GetItem(args, 0);
|
||||
|
||||
if (PyList_Check(the_arg)) {
|
||||
size = PyList_Size(the_arg) + 2;
|
||||
}
|
||||
else if (PyTuple_Check(the_arg)) {
|
||||
size = PyTuple_Size(the_arg) + 2;
|
||||
}
|
||||
else if (PyString_Check(the_arg)) {
|
||||
size = 3;
|
||||
}
|
||||
|
||||
argv = uwsgi_malloc(sizeof(char *) * size);
|
||||
memset(argv, 0, sizeof(char *) * size);
|
||||
|
||||
// will be overwritten
|
||||
argv[0] = "uwsgi";
|
||||
|
||||
if (PyList_Check(the_arg)) {
|
||||
for(i=0;i<PyList_Size(the_arg);i++) {
|
||||
argv[i+1] = PyString_AsString( PyList_GetItem(the_arg, i) );
|
||||
}
|
||||
}
|
||||
else if (PyTuple_Check(the_arg)) {
|
||||
for(i=0;i<PyTuple_Size(the_arg);i++) {
|
||||
argv[i+1] = PyString_AsString( PyTuple_GetItem(the_arg, i) );
|
||||
}
|
||||
}
|
||||
else if (PyString_Check(the_arg)) {
|
||||
argv[1] = PyString_AsString( the_arg );
|
||||
}
|
||||
|
||||
uwsgi_init(size-1, argv, environ);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyMethodDef methods[] = {
|
||||
{"run", u_run, METH_VARARGS, "run the uWSGI server"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initpyuwsgi()
|
||||
{
|
||||
(void) Py_InitModule("pyuwsgi", methods);
|
||||
}
|
||||
|
||||
|
||||
int pyuwsgi_init() { return 0; }
|
||||
|
||||
struct uwsgi_plugin pyuwsgi_plugin = {
|
||||
|
||||
.name = "pyuwsgi",
|
||||
.init = pyuwsgi_init,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
from distutils import sysconfig
|
||||
import os
|
||||
|
||||
os.environ['UWSGI_PYTHON_NOLIB'] = '1'
|
||||
|
||||
NAME='pyuwsgi'
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['pyuwsgi']
|
||||
@@ -9,6 +9,7 @@ struct option uwsgi_rack_options[] = {
|
||||
{"rails", required_argument, 0, LONG_ARGS_RAILS},
|
||||
{"rack", required_argument, 0, LONG_ARGS_RACK},
|
||||
{"ruby-gc-freq", required_argument, 0, LONG_ARGS_RUBY_GC_FREQ},
|
||||
{"rbshell", optional_argument, 0, LONG_ARGS_RUBY_SHELL},
|
||||
|
||||
{0, 0, 0, 0},
|
||||
|
||||
@@ -920,6 +921,9 @@ int uwsgi_rack_mount_app(char *mountpoint, char *app) {
|
||||
}
|
||||
*/
|
||||
|
||||
void uwsgi_rack_hijack(void) {
|
||||
}
|
||||
|
||||
struct uwsgi_plugin rack_plugin = {
|
||||
|
||||
.name = "rack",
|
||||
@@ -932,6 +936,8 @@ struct uwsgi_plugin rack_plugin = {
|
||||
|
||||
.signal_handler = uwsgi_rack_signal_handler,
|
||||
|
||||
.hijack = uwsgi_rack_hijack,
|
||||
|
||||
.init_apps = uwsgi_rack_init_apps,
|
||||
//.mount_app = uwsgi_rack_mount_app,
|
||||
.manage_xml = uwsgi_rack_xml,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define LONG_ARGS_RAILS LONG_ARGS_RACK_BASE + 1
|
||||
#define LONG_ARGS_RUBY_GC_FREQ LONG_ARGS_RACK_BASE + 2
|
||||
#define LONG_ARGS_RACK LONG_ARGS_RACK_BASE + 3
|
||||
#define LONG_ARGS_RUBY_SHELL LONG_ARGS_RACK_BASE + 4
|
||||
|
||||
#ifndef RUBY19
|
||||
#define rb_errinfo() ruby_errinfo
|
||||
@@ -59,6 +60,8 @@ struct uwsgi_rack {
|
||||
|
||||
pthread_mutex_t gvl;
|
||||
|
||||
int rb_shell;
|
||||
|
||||
};
|
||||
|
||||
void uwsgi_ruby_exception(void);
|
||||
|
||||
+43
-8
@@ -46,6 +46,12 @@ static uint16_t http_add_uwsgi_header(struct wsgi_request *wsgi_req, char *hh, i
|
||||
wsgi_req->if_modified_since = val;
|
||||
wsgi_req->if_modified_since_len = vallen;
|
||||
}
|
||||
else if (!uwsgi_strncmp("X_FORWARDED_SSL", 15, hh, keylen)) {
|
||||
if (vallen == 2 && val[0] == 'o' && val[1] == 'n') {
|
||||
wsgi_req->scheme = "https";
|
||||
wsgi_req->scheme_len = 5;
|
||||
}
|
||||
}
|
||||
else if (uwsgi.vhost_host && !uwsgi_strncmp("HOST", 4, hh, keylen)) {
|
||||
wsgi_req->host = val;
|
||||
wsgi_req->host_len = vallen;
|
||||
@@ -100,6 +106,8 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
|
||||
char ip[INET_ADDRSTRLEN+1];
|
||||
struct sockaddr_in *http_sin = (struct sockaddr_in *) &wsgi_req->c_addr;
|
||||
|
||||
wsgi_req->path_info_pos = -1;
|
||||
|
||||
// REQUEST_METHOD
|
||||
while (ptr < watermark) {
|
||||
if (*ptr == ' ') {
|
||||
@@ -116,9 +124,19 @@ 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;
|
||||
}
|
||||
else if (*ptr == ' ') {
|
||||
@@ -127,9 +145,19 @@ 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);
|
||||
}
|
||||
else {
|
||||
@@ -161,7 +189,10 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
|
||||
}
|
||||
|
||||
// SCRIPT_NAME
|
||||
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SCRIPT_NAME", 11, "", 0);
|
||||
if (!uwsgi.manage_script_name) {
|
||||
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SCRIPT_NAME", 11, "", 0);
|
||||
}
|
||||
|
||||
|
||||
// SERVER_NAME
|
||||
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_NAME", 11, uwsgi.hostname, uwsgi.hostname_len);
|
||||
@@ -261,7 +292,11 @@ int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) {
|
||||
len = read(wsgi_req->poll.fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, uwsgi.buffer_size - wsgi_req->proto_parser_pos);
|
||||
if (len <= 0) {
|
||||
free(wsgi_req->proto_parser_buf);
|
||||
uwsgi_error("recv()");
|
||||
if (len < 0) {
|
||||
uwsgi_error("recv()");
|
||||
}
|
||||
// this is simple ping packet
|
||||
else { return -2; }
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
+24
-4
@@ -115,17 +115,37 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
ssize_t uwsgi_proto_uwsgi_writev_header(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
|
||||
return writev(wsgi_req->poll.fd, iovec, iov_len);
|
||||
ssize_t wlen = writev(wsgi_req->poll.fd, iovec, iov_len);
|
||||
if (wlen < 0) {
|
||||
uwsgi_req_error("writev()");
|
||||
return 0;
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
ssize_t uwsgi_proto_uwsgi_writev(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
|
||||
return writev(wsgi_req->poll.fd, iovec, iov_len);
|
||||
ssize_t wlen = writev(wsgi_req->poll.fd, iovec, iov_len);
|
||||
if (wlen < 0) {
|
||||
uwsgi_req_error("writev()");
|
||||
return 0;
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
ssize_t uwsgi_proto_uwsgi_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
|
||||
return write(wsgi_req->poll.fd, buf, len);
|
||||
ssize_t wlen = write(wsgi_req->poll.fd, buf, len);
|
||||
if (wlen < 0) {
|
||||
uwsgi_req_error("write()");
|
||||
return 0;
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
ssize_t uwsgi_proto_uwsgi_write_header(struct wsgi_request * wsgi_req, char *buf, size_t len) {
|
||||
return write(wsgi_req->poll.fd, buf, len);
|
||||
ssize_t wlen = write(wsgi_req->poll.fd, buf, len);
|
||||
if (wlen < 0) {
|
||||
uwsgi_req_error("write()");
|
||||
return 0;
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
+76
-12
@@ -355,7 +355,7 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
|
||||
exit(1);
|
||||
}
|
||||
else if (rlen == 0) {
|
||||
uwsgi_log( "timeout waiting for header. skip request.\n");
|
||||
uwsgi_log( "timeout. skip request.\n");
|
||||
//close(upoll->fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -366,7 +366,10 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
|
||||
status = uwsgi_proto_uwsgi_parser(wsgi_req);
|
||||
}
|
||||
if (status < 0) {
|
||||
uwsgi_log("error parsing request\n");
|
||||
if (status == -1)
|
||||
uwsgi_log("error parsing request\n");
|
||||
else if (status == -2)
|
||||
uwsgi_log("open-close packet (ping/check) received\n");
|
||||
//close(upoll->fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -496,7 +499,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
|
||||
ptrbuf = buffer;
|
||||
bufferend = ptrbuf + wsgi_req->uh.pktsize;
|
||||
int i, script_name= -1, path_info= -1;
|
||||
int i, script_name= -1;
|
||||
|
||||
/* set an HTTP 500 status as default */
|
||||
wsgi_req->status = 500;
|
||||
@@ -508,6 +511,8 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
return i;
|
||||
}
|
||||
|
||||
wsgi_req->path_info_pos = -1;
|
||||
|
||||
while (ptrbuf < bufferend) {
|
||||
if (ptrbuf + 2 < bufferend) {
|
||||
memcpy(&strsize, ptrbuf, 2);
|
||||
@@ -546,7 +551,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
else if (!uwsgi_strncmp("PATH_INFO", 9, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->path_info = ptrbuf;
|
||||
wsgi_req->path_info_len = strsize;
|
||||
path_info = wsgi_req->var_cnt + 1;
|
||||
wsgi_req->path_info_pos = wsgi_req->var_cnt + 1;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("PATH_INFO=%.*s\n", wsgi_req->path_info_len, wsgi_req->path_info);
|
||||
#endif
|
||||
@@ -567,7 +572,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->method = ptrbuf;
|
||||
wsgi_req->method_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("REMOTE_ADDR", 11, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!uwsgi.log_x_forwarded_for && !uwsgi_strncmp("REMOTE_ADDR", 11, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->remote_addr = ptrbuf;
|
||||
wsgi_req->remote_addr_len = strsize;
|
||||
}
|
||||
@@ -652,6 +657,10 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->if_modified_since = ptrbuf;
|
||||
wsgi_req->if_modified_since_len = strsize;
|
||||
}
|
||||
else if (uwsgi.log_x_forwarded_for && !uwsgi_strncmp("HTTP_X_FORWARDED_FOR", 20, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->remote_addr = ptrbuf;
|
||||
wsgi_req->remote_addr_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("CONTENT_TYPE", 12, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->content_type = ptrbuf;
|
||||
wsgi_req->content_type_len = strsize;
|
||||
@@ -749,7 +758,7 @@ next:
|
||||
}
|
||||
|
||||
if (uwsgi.manage_script_name) {
|
||||
if (uwsgi_apps_cnt > 0 && wsgi_req->path_info_len > 1) {
|
||||
if (uwsgi_apps_cnt > 0 && wsgi_req->path_info_len > 1 && wsgi_req->path_info_pos != -1) {
|
||||
// starts with 1 as the 0 app is the default (/) one
|
||||
int best_found = 0;
|
||||
char *orig_path_info = wsgi_req->path_info;
|
||||
@@ -760,12 +769,15 @@ next:
|
||||
uwsgi_log( "max vec size reached. skip this var.\n");
|
||||
return -1;
|
||||
}
|
||||
wsgi_req->var_cnt++;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = "SCRIPT_NAME";
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = 11;
|
||||
wsgi_req->var_cnt++;
|
||||
script_name = wsgi_req->var_cnt;
|
||||
wsgi_req->hvec[script_name].iov_base = "";
|
||||
wsgi_req->hvec[script_name].iov_len = 0;
|
||||
wsgi_req->var_cnt++;
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi_apps_cnt;i++) {
|
||||
//uwsgi_log("app mountpoint = %.*s\n", uwsgi_apps[i].mountpoint_len, uwsgi_apps[i].mountpoint);
|
||||
if (orig_path_info_len >= uwsgi_apps[i].mountpoint_len) {
|
||||
@@ -779,8 +791,8 @@ next:
|
||||
wsgi_req->hvec[script_name].iov_base = wsgi_req->script_name;
|
||||
wsgi_req->hvec[script_name].iov_len = wsgi_req->script_name_len;
|
||||
|
||||
wsgi_req->hvec[path_info].iov_base = wsgi_req->path_info;
|
||||
wsgi_req->hvec[path_info].iov_len = wsgi_req->path_info_len;
|
||||
wsgi_req->hvec[wsgi_req->path_info_pos].iov_base = wsgi_req->path_info;
|
||||
wsgi_req->hvec[wsgi_req->path_info_pos].iov_len = wsgi_req->path_info_len;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("managed SCRIPT_NAME = %.*s PATH_INFO = %.*s\n", wsgi_req->script_name_len, wsgi_req->script_name, wsgi_req->path_info_len, wsgi_req->path_info);
|
||||
#endif
|
||||
@@ -1324,6 +1336,48 @@ int uwsgi_simple_send_string(char *socket_name, uint8_t modifier1, uint8_t modif
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *uwsgi_get_mime_type(char *name, int namelen, int *size) {
|
||||
|
||||
int i;
|
||||
int count = 0;
|
||||
char *ext = NULL;
|
||||
for(i=namelen-1;i>=0;i--) {
|
||||
if (!isalnum( (int)name[i])) {
|
||||
if (name[i] == '.') {
|
||||
ext = name+(namelen-count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
struct uwsgi_dyn_dict *udd = uwsgi.mimetypes;
|
||||
while(udd) {
|
||||
if (!uwsgi_strncmp(ext, count, udd->key, udd->keylen)) {
|
||||
udd->hits++;
|
||||
// auto optimization
|
||||
if (udd->prev) {
|
||||
if (udd->hits > udd->prev->hits) {
|
||||
struct uwsgi_dyn_dict *udd_parent = udd->prev->prev, *udd_prev = udd->prev;
|
||||
if (udd_parent) {
|
||||
udd_parent->next = udd;
|
||||
}
|
||||
udd_prev->prev = udd;
|
||||
udd_prev->next = udd->next;
|
||||
|
||||
udd->prev = udd_parent;
|
||||
udd->next = udd_prev;
|
||||
}
|
||||
}
|
||||
*size = udd->vallen;
|
||||
return udd->value;
|
||||
}
|
||||
udd = udd->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_t document_root_len, char *path_info, uint16_t path_info_len, char *orig_document_root, uint16_t orig_document_root_len) {
|
||||
|
||||
@@ -1348,6 +1402,8 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
return -1;
|
||||
}
|
||||
if (!stat(real_filename, &st)) {
|
||||
int mime_type_size = 0;
|
||||
char *mime_type = uwsgi_get_mime_type(path_info, path_info_len, &mime_type_size);
|
||||
if (wsgi_req->if_modified_since_len) {
|
||||
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
|
||||
if (st.st_mtime <= ims) {
|
||||
@@ -1380,11 +1436,19 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
while(ah) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ah->value, ah->len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
wsgi_req->header_cnt++;
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
if (mime_type_size > 0 && mime_type) {
|
||||
wsgi_req->header_cnt++;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "Content-Type: ", 14);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, mime_type, mime_type_size);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
}
|
||||
|
||||
if (uwsgi.file_serve_mode == 1) {
|
||||
wsgi_req->header_cnt = 2;
|
||||
wsgi_req->header_cnt += 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Accel-Redirect: ", 18);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, orig_document_root, orig_document_root_len);
|
||||
if (orig_document_root[orig_document_root_len-1] != '/') {
|
||||
@@ -1396,7 +1460,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
}
|
||||
else if (uwsgi.file_serve_mode == 2) {
|
||||
wsgi_req->header_cnt = 2;
|
||||
wsgi_req->header_cnt += 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Sendfile: ", 12);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, orig_document_root, orig_document_root_len);
|
||||
if (orig_document_root[orig_document_root_len-1] != '/') {
|
||||
@@ -1408,7 +1472,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
}
|
||||
else {
|
||||
wsgi_req->header_cnt = 1;
|
||||
wsgi_req->header_cnt += 1;
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
wsgi_req->sendfile_fd = open(real_filename, O_RDONLY);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import sys
|
||||
import os
|
||||
import pyuwsgi
|
||||
|
||||
orig_args = sys.argv
|
||||
orig_executable = sys.executable
|
||||
orig_args.insert(0, orig_executable)
|
||||
|
||||
uwsgi_args = []
|
||||
|
||||
for arg in sys.argv[2:]:
|
||||
uwsgi_args.append(arg)
|
||||
|
||||
#pyuwsgi.run('welcome.ini')
|
||||
pyuwsgi.run(uwsgi_args)
|
||||
|
||||
# if you are here uWSGI has been reloaded
|
||||
os.execv(orig_executable, orig_args)
|
||||
@@ -0,0 +1,22 @@
|
||||
import sys
|
||||
import os
|
||||
import pyuwsgi
|
||||
|
||||
orig_args = sys.argv
|
||||
orig_executable = sys.executable
|
||||
orig_args.insert(0, orig_executable)
|
||||
|
||||
uwsgi_args = []
|
||||
|
||||
uwsgi_args.append('--socket')
|
||||
uwsgi_args.append(':3031')
|
||||
#uwsgi_args.append('--master')
|
||||
uwsgi_args.append('--module')
|
||||
#uwsgi_args.append('welcome')
|
||||
uwsgi_args.append('hello')
|
||||
|
||||
#pyuwsgi.run('welcome.ini')
|
||||
pyuwsgi.run(uwsgi_args)
|
||||
|
||||
# if you are here uWSGI has been reloaded
|
||||
os.execv(orig_executable, orig_args)
|
||||
@@ -1,8 +1,30 @@
|
||||
#ifdef UWSGI_PCRE
|
||||
|
||||
#include "uwsgi.h"
|
||||
|
||||
#include <pcre.h>
|
||||
void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) {
|
||||
|
||||
const char *errstr;
|
||||
int erroff;
|
||||
|
||||
*pattern = pcre_compile( (const char *)re, 0, &errstr, &erroff, NULL);
|
||||
if (!*pattern) {
|
||||
uwsgi_log("pcre error: %s at offset %d\n", errstr, erroff);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*pattern_extra = (pcre_extra *) pcre_study((const pcre*)*pattern, 0, &errstr);
|
||||
if (!*pattern_extra) {
|
||||
uwsgi_log("pcre (study) error: %s\n", errstr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length) {
|
||||
|
||||
return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, NULL, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
+5
-3
@@ -56,9 +56,11 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
|
||||
sf_ret = sendfile(filefd, sockfd, 0, 0, NULL, &sf_len, 0);
|
||||
}
|
||||
|
||||
if (sf_ret) {
|
||||
uwsgi_error("sendfile()");
|
||||
return 0;
|
||||
if (sf_ret < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
uwsgi_error("sendfile()");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sf_len;
|
||||
|
||||
@@ -6,6 +6,7 @@ import shutil
|
||||
from setuptools import setup
|
||||
from setuptools.dist import Distribution
|
||||
from setuptools.command.install import install
|
||||
from setuptools.command.install_lib import install_lib
|
||||
from setuptools.command.build_ext import build_ext
|
||||
|
||||
def get_profile():
|
||||
@@ -42,22 +43,27 @@ class uWSGIBuilder(build_ext):
|
||||
class uWSGIInstall(install):
|
||||
|
||||
def run(self):
|
||||
# hack, hack and still hack. We need to find a solution...
|
||||
if self.record:
|
||||
record_file = open(self.record,'w')
|
||||
|
||||
conf = uc.uConf(get_profile())
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
install.run(self)
|
||||
|
||||
class uWSGIInstallLib(install_lib):
|
||||
|
||||
def run(self):
|
||||
conf = uc.uConf(get_profile())
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
|
||||
class uWSGIDistribution(Distribution):
|
||||
|
||||
def __init__(self, *attrs):
|
||||
Distribution.__init__(self, *attrs)
|
||||
self.cmdclass['install'] = uWSGIInstall
|
||||
self.cmdclass['install_lib'] = uWSGIInstallLib
|
||||
self.cmdclass['build_ext'] = uWSGIBuilder
|
||||
|
||||
|
||||
setup(name='uWSGI',
|
||||
version=uc.uwsgi_version,
|
||||
description='The uWSGI server',
|
||||
|
||||
@@ -12,7 +12,55 @@ int uwsgi_signal_handler(uint8_t sig) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
|
||||
// set harakiri here (if required and if i am a worker)
|
||||
|
||||
if (uwsgi.mywid > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].sig = 1;
|
||||
uwsgi.workers[uwsgi.mywid].signum = sig;
|
||||
uwsgi.workers[uwsgi.mywid].signals++;
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
|
||||
}
|
||||
}
|
||||
else if (uwsgi.muleid > 0) {
|
||||
uwsgi.mules[uwsgi.muleid-1].sig = 1;
|
||||
uwsgi.mules[uwsgi.muleid-1].signum = sig;
|
||||
uwsgi.mules[uwsgi.muleid-1].signals++;
|
||||
if(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI] > 0) {
|
||||
set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]);
|
||||
}
|
||||
}
|
||||
#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);
|
||||
|
||||
if (uwsgi.mywid > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].sig = 0;
|
||||
if(uwsgi.workers[uwsgi.mywid].harakiri > 0) {
|
||||
set_harakiri(0);
|
||||
}
|
||||
}
|
||||
else if (uwsgi.muleid > 0) {
|
||||
uwsgi.mules[uwsgi.muleid-1].sig = 0;
|
||||
if(uwsgi.mules[uwsgi.muleid-1].harakiri > 0) {
|
||||
set_mule_harakiri(0);
|
||||
}
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
int uwsgi_signal_registered(uint8_t sig) {
|
||||
@@ -166,7 +214,7 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
// send to all workers
|
||||
else if (!strcmp(use->receiver, "workers")) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (write(uwsgi.signal_pipe[i][0], &sig, 1) != 1) {
|
||||
if (write(uwsgi.workers[i].signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
@@ -178,7 +226,7 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
if (i > uwsgi.numproc) {
|
||||
uwsgi_log("invalid signal target: %s\n", use->receiver);
|
||||
}
|
||||
if (write(uwsgi.signal_pipe[i][0], &sig, 1) != 1) {
|
||||
if (write(uwsgi.workers[i].signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
@@ -187,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) {
|
||||
@@ -195,6 +244,47 @@ 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) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strncmp(use->receiver, "mule", 4)) {
|
||||
i = atoi(use->receiver+4);
|
||||
if (i > uwsgi.mules_cnt) {
|
||||
uwsgi_log("invalid signal target: %s\n", use->receiver);
|
||||
}
|
||||
else if (i == 0) {
|
||||
if (write(ushared->mule_signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to a mule\n", sig);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (write(uwsgi.mules[i-1].signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -474,7 +474,13 @@ socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *s
|
||||
sin_addr->sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
|
||||
char *resolved = uwsgi_resolve_ip(socket_name);
|
||||
if (resolved) {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(resolved);
|
||||
}
|
||||
else {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
|
||||
}
|
||||
}
|
||||
|
||||
return sizeof(struct sockaddr_in);
|
||||
@@ -749,6 +755,20 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) {
|
||||
|
||||
if (!name) return uwsgi_sock;
|
||||
|
||||
if (name[0] == '=') {
|
||||
int shared_socket = atoi(uwsgi_sock->name+1);
|
||||
if (shared_socket >= 0) {
|
||||
struct uwsgi_socket *uss = uwsgi_get_shared_socket_by_num(shared_socket);
|
||||
if (!uss) {
|
||||
uwsgi_log("unable to use shared socket %d\n", shared_socket);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_sock->shared = 1;
|
||||
uwsgi_sock->from_shared = shared_socket;
|
||||
return uwsgi_sock;
|
||||
}
|
||||
}
|
||||
char *tcp_port = strchr(name, ':');
|
||||
if (tcp_port) {
|
||||
// INET socket, check for 0 port
|
||||
@@ -951,6 +971,29 @@ int uwsgi_get_shared_socket_fd_by_num(int num) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int num) {
|
||||
|
||||
int counter = 0;
|
||||
|
||||
struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.shared_sockets;
|
||||
|
||||
while(uwsgi_sock) {
|
||||
if (counter == num) {
|
||||
found_sock = uwsgi_sock;
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
if (found_sock) {
|
||||
return found_sock;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_add_sockets_to_queue(int queue) {
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
|
||||
@@ -16,18 +16,7 @@ pid_t spooler_start() {
|
||||
|
||||
int i;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
|
||||
if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
|
||||
// setup internal signalling system
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.shared->spooler_signal_pipe)) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pid_t pid = fork();
|
||||
pid_t pid = uwsgi_fork("uWSGI spooler");
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
exit(1);
|
||||
@@ -36,23 +25,21 @@ pid_t spooler_start() {
|
||||
// USR1 will be used to wake up the spooler
|
||||
signal(SIGUSR1, spooler_wakeup);
|
||||
uwsgi.mywid = -1;
|
||||
uwsgi.mypid = pid;
|
||||
uwsgi.mypid = getpid();
|
||||
// avoid race conditions !!!
|
||||
uwsgi.shared->spooler_pid = uwsgi.mypid;
|
||||
|
||||
uwsgi_fixup_fds(0, 0);
|
||||
uwsgi_close_all_sockets();
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.shared->spooler_signal_pipe[0]);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.signal_pipe[i][0] != -1) {
|
||||
close(uwsgi.signal_pipe[i][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->post_fork) {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1];
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->spooler_init) {
|
||||
uwsgi.p[i]->spooler_init();
|
||||
@@ -64,12 +51,10 @@ pid_t spooler_start() {
|
||||
uwsgi.gp[i]->spooler_init();
|
||||
}
|
||||
}
|
||||
|
||||
spooler();
|
||||
}
|
||||
else if (pid > 0) {
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.shared->spooler_signal_pipe[1]);
|
||||
}
|
||||
uwsgi_log("spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid);
|
||||
}
|
||||
|
||||
@@ -251,6 +236,8 @@ void spooler() {
|
||||
if (uwsgi.spooler_ordered) {
|
||||
#ifdef __linux__
|
||||
spooler_scandir(uwsgi.spool_dir);
|
||||
#else
|
||||
spooler_readdir(uwsgi.spool_dir);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@@ -362,7 +349,12 @@ void spooler_manage_task(char *dir, char *task) {
|
||||
if (!access(task, R_OK | W_OK)) {
|
||||
uwsgi_log("managing spool request %s ...\n", task);
|
||||
|
||||
#ifdef __sun__
|
||||
// lockf needs write permission
|
||||
spool_fd = open(task, O_RDWR);
|
||||
#else
|
||||
spool_fd = open(task, O_RDONLY);
|
||||
#endif
|
||||
if (spool_fd < 0) {
|
||||
uwsgi_error_open(task);
|
||||
return;
|
||||
@@ -411,16 +403,29 @@ void spooler_manage_task(char *dir, char *task) {
|
||||
|
||||
close(spool_fd);
|
||||
|
||||
if (uwsgi.spooler_chdir) {
|
||||
if (chdir(uwsgi.spooler_chdir)) {
|
||||
uwsgi_error("chdir()");
|
||||
}
|
||||
}
|
||||
|
||||
int callable_found = 0;
|
||||
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);
|
||||
}
|
||||
if (ret == 0) continue;
|
||||
callable_found = 1;
|
||||
if (ret == -2) {
|
||||
|
||||
uwsgi_log("done with task/spool %s after %d seconds\n", task, time(NULL)-now);
|
||||
destroy_spool(dir, task);
|
||||
}
|
||||
@@ -428,6 +433,9 @@ void spooler_manage_task(char *dir, char *task) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!callable_found) {
|
||||
uwsgi_log("unable to find the spooler function, have you loaded it into the spooler process ?\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+24
-1
@@ -1,17 +1,39 @@
|
||||
import gevent
|
||||
import gevent.socket
|
||||
import sys
|
||||
import uwsgi
|
||||
from uwsgidecorators import *
|
||||
|
||||
if 'gettotalrefcount' in sys.__dict__:
|
||||
REFCNT = True
|
||||
else:
|
||||
REFCNT = False
|
||||
|
||||
@signal(17)
|
||||
def hello(signum):
|
||||
print "hello i am signal %d, i am here because the background job is finished" % signum
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
|
||||
@timer(10)
|
||||
def ten_seconds(signum):
|
||||
print "10 seconds elapsed, signal %d raised" % signum
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
|
||||
@filemon('/tmp')
|
||||
def tmp_modified(signum):
|
||||
print "/tmp has been touched, i am the greenlet %s running on worker %d" % (gevent.getcurrent(), uwsgi.worker_id())
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
|
||||
def bg_task():
|
||||
for i in range(1,10):
|
||||
print "background task", i
|
||||
gevent.sleep(2)
|
||||
gevent.sleep(1)
|
||||
|
||||
# task ended raise a signal !!!
|
||||
uwsgi.signal(17)
|
||||
|
||||
def long_task():
|
||||
for i in range(1,10):
|
||||
@@ -43,6 +65,7 @@ def application(e, sr):
|
||||
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
yield "%d" % sys.gettotalrefcount()
|
||||
|
||||
# this task will goes on after request end
|
||||
gevent.spawn(bg_task)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import uwsgi
|
||||
|
||||
print(uwsgi.opt)
|
||||
print(uwsgi.magic_table)
|
||||
from werkzeug.testapp import test_app as application
|
||||
+48
-2
@@ -1,5 +1,19 @@
|
||||
import uuid
|
||||
import uwsgi
|
||||
import os
|
||||
|
||||
|
||||
def application(env, start_response):
|
||||
|
||||
if env['PATH_INFO'].startswith('/progress/'):
|
||||
start_response('200 Ok', [('Content-type', 'application/json')])
|
||||
filename = 'foobar/' + env['PATH_INFO'][10:]
|
||||
print filename
|
||||
if os.path.exists(filename):
|
||||
return uwsgi.sendfile(filename)
|
||||
else:
|
||||
return "{ 'state': 'done' }"
|
||||
|
||||
|
||||
if env['REQUEST_METHOD'] == 'POST':
|
||||
start_response('200 Ok', [('Content-type', 'text/plain')])
|
||||
@@ -14,12 +28,44 @@ def application(env, start_response):
|
||||
return body
|
||||
else:
|
||||
start_response('200 Ok', [('Content-type', 'text/html')])
|
||||
x_progress_id = str(uuid.uuid4())
|
||||
return """
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<html>
|
||||
<head>
|
||||
<script src="/static/jquery-1.5.1.min.js" /></script>
|
||||
<script language="Javascript">
|
||||
var interval;
|
||||
function redrawProgressBar() {
|
||||
interval = setInterval(getData, 1000);
|
||||
}
|
||||
|
||||
function getData() {
|
||||
var jsr = $.getJSON("/progress/%s.js",
|
||||
function(data) {
|
||||
if (data) {
|
||||
if (data.state == 'uploading') {
|
||||
$('#progress').html(data.received + '/' + data.size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
alert("fine");
|
||||
clearInterval(interval);
|
||||
}
|
||||
);
|
||||
jsr.error(function() { clearInterval(interval); });
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
upload progress: <div id="progress"> 0%%</div>
|
||||
<form method="POST" enctype="multipart/form-data" action="?X-Progress-ID=%s" onsubmit="redrawProgressBar(); return true;">
|
||||
<textarea name="pluto">
|
||||
</textarea>
|
||||
<input type="file" name="pippo" />
|
||||
<input type="submit" value="invia" />
|
||||
</form>
|
||||
"""
|
||||
</body>
|
||||
</html>
|
||||
""" % (x_progress_id, x_progress_id)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern char **environ;
|
||||
|
||||
/* statistically ordered */
|
||||
struct http_status_codes hsc[] = {
|
||||
@@ -98,19 +99,44 @@ void inc_harakiri(int sec) {
|
||||
}
|
||||
|
||||
void set_harakiri(int sec) {
|
||||
if (uwsgi.master_process) {
|
||||
if (sec == 0) {
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = 0;
|
||||
}
|
||||
else {
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = time(NULL) + sec;
|
||||
}
|
||||
if (sec == 0) {
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = 0;
|
||||
}
|
||||
else {
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = time(NULL) + sec;
|
||||
}
|
||||
if (!uwsgi.master_process) {
|
||||
alarm(sec);
|
||||
}
|
||||
}
|
||||
|
||||
void set_mule_harakiri(int sec) {
|
||||
if (sec == 0) {
|
||||
uwsgi.mules[uwsgi.muleid-1].harakiri = 0;
|
||||
}
|
||||
else {
|
||||
uwsgi.mules[uwsgi.muleid-1].harakiri = time(NULL) + sec;
|
||||
}
|
||||
if (!uwsgi.master_process) {
|
||||
alarm(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;
|
||||
int fdin;
|
||||
@@ -195,7 +221,13 @@ void logto(char *logfile) {
|
||||
|
||||
udp_addr.sin_family = AF_INET;
|
||||
udp_addr.sin_port = htons(atoi(udp_port + 1));
|
||||
udp_addr.sin_addr.s_addr = inet_addr(logfile);
|
||||
char *resolved = uwsgi_resolve_ip(logfile);
|
||||
if (resolved) {
|
||||
udp_addr.sin_addr.s_addr = inet_addr(resolved);
|
||||
}
|
||||
else {
|
||||
udp_addr.sin_addr.s_addr = inet_addr(logfile);
|
||||
}
|
||||
|
||||
if (connect(fd, (const struct sockaddr *) &udp_addr, sizeof(struct sockaddr_in)) < 0) {
|
||||
uwsgi_error("connect()");
|
||||
@@ -204,7 +236,12 @@ void logto(char *logfile) {
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
if (uwsgi.log_truncate) {
|
||||
fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
}
|
||||
else {
|
||||
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
}
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open(logfile);
|
||||
exit(1);
|
||||
@@ -360,6 +397,8 @@ void create_logpipe(void) {
|
||||
|
||||
void log_syslog(char *syslog_opts) {
|
||||
|
||||
setlinebuf(stderr);
|
||||
|
||||
if (syslog_opts == NULL) {
|
||||
syslog_opts = "uwsgi";
|
||||
}
|
||||
@@ -433,13 +472,13 @@ void log_syslog(char *syslog_opts) {
|
||||
|
||||
char *uwsgi_get_cwd() {
|
||||
|
||||
int newsize = 256;
|
||||
char *cwd;
|
||||
// set this to static to avoid useless reallocations in stats mode
|
||||
static size_t newsize = 256;
|
||||
|
||||
cwd = uwsgi_malloc(newsize);
|
||||
char *cwd = uwsgi_malloc(newsize);
|
||||
|
||||
if (getcwd(cwd, newsize) == NULL) {
|
||||
newsize = errno;
|
||||
if (getcwd(cwd, newsize) == NULL && errno == ERANGE) {
|
||||
newsize += 256;
|
||||
uwsgi_log("need a bigger buffer (%d bytes) for getcwd(). doing reallocation.\n", newsize);
|
||||
free(cwd);
|
||||
cwd = uwsgi_malloc(newsize);
|
||||
@@ -552,6 +591,41 @@ void uwsgi_as_root() {
|
||||
uwsgi_log("uWSGI running as root, you can use --uid/--gid/--chroot options\n");
|
||||
}
|
||||
|
||||
#ifdef UWSGI_CAP
|
||||
if (uwsgi.cap && uwsgi.cap_count > 0 && !uwsgi.reloads) {
|
||||
|
||||
cap_value_t minimal_cap_values[] = { CAP_SYS_CHROOT, CAP_SETUID, CAP_SETGID, CAP_SETPCAP };
|
||||
|
||||
cap_t caps = cap_init();
|
||||
|
||||
if (!caps) {
|
||||
uwsgi_error("cap_init()");
|
||||
exit(1);
|
||||
}
|
||||
cap_clear(caps);
|
||||
|
||||
cap_set_flag(caps, CAP_EFFECTIVE, 4, minimal_cap_values, CAP_SET);
|
||||
|
||||
cap_set_flag(caps, CAP_PERMITTED, 4, minimal_cap_values, CAP_SET);
|
||||
cap_set_flag(caps, CAP_PERMITTED, uwsgi.cap_count, uwsgi.cap, CAP_SET);
|
||||
|
||||
cap_set_flag(caps, CAP_INHERITABLE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
|
||||
|
||||
if (cap_set_proc(caps) < 0) {
|
||||
uwsgi_error("cap_set_proc()");
|
||||
exit(1);
|
||||
}
|
||||
cap_free(caps);
|
||||
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
|
||||
uwsgi_error("prctl()");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.chroot && !uwsgi.reloads) {
|
||||
if (!uwsgi.master_as_root)
|
||||
uwsgi_log("chroot() to %s\n", uwsgi.chroot);
|
||||
@@ -615,8 +689,32 @@ void uwsgi_as_root() {
|
||||
}
|
||||
|
||||
if (!getuid()) {
|
||||
uwsgi_log(" *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n");
|
||||
uwsgi_log("*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n");
|
||||
}
|
||||
|
||||
#ifdef UWSGI_CAP
|
||||
|
||||
if (uwsgi.cap && uwsgi.cap_count > 0 && !uwsgi.reloads) {
|
||||
|
||||
cap_t caps = cap_init();
|
||||
|
||||
if (!caps) {
|
||||
uwsgi_error("cap_init()");
|
||||
exit(1);
|
||||
}
|
||||
cap_clear(caps);
|
||||
|
||||
cap_set_flag(caps, CAP_EFFECTIVE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
|
||||
cap_set_flag(caps, CAP_PERMITTED, uwsgi.cap_count, uwsgi.cap, CAP_SET);
|
||||
cap_set_flag(caps, CAP_INHERITABLE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
|
||||
|
||||
if (cap_set_proc(caps) < 0) {
|
||||
uwsgi_error("cap_set_proc()");
|
||||
exit(1);
|
||||
}
|
||||
cap_free(caps);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (uwsgi.chroot && !uwsgi.is_a_reload) {
|
||||
@@ -655,14 +753,21 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
int waitpid_status;
|
||||
int tmp_id;
|
||||
uint64_t tmp_rt, rss = 0, vsz = 0;
|
||||
|
||||
gettimeofday(&wsgi_req->end_of_request, NULL);
|
||||
//uwsgi.workers[uwsgi.mywid].running_time += (double) (((double) (wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec) - (double) (wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec)) / (double) 1000.0);
|
||||
|
||||
tmp_rt = (wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec) - (wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec);
|
||||
|
||||
uwsgi.workers[uwsgi.mywid].running_time += tmp_rt;
|
||||
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.reload_on_as || uwsgi.reload_on_rss)
|
||||
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
|
||||
@@ -685,10 +790,18 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
#endif
|
||||
|
||||
// leave harakiri mode
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
if (uwsgi.workers[uwsgi.mywid].harakiri > 0) {
|
||||
set_harakiri(0);
|
||||
}
|
||||
|
||||
// this is racy in multithread mode
|
||||
if (wsgi_req->response_size > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].tx += wsgi_req->response_size;
|
||||
}
|
||||
if (wsgi_req->headers_size > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].tx += wsgi_req->headers_size;
|
||||
}
|
||||
|
||||
// defunct process reaper
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_REAPER] == 1 || uwsgi.grunt) {
|
||||
while (waitpid(WAIT_ANY, &waitpid_status, WNOHANG) > 0);
|
||||
@@ -703,11 +816,11 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
goodbye_cruel_world();
|
||||
}
|
||||
|
||||
if (uwsgi.reload_on_as && (int) (uwsgi.workers[uwsgi.mywid].vsz_size / 1024 / 1024) >= uwsgi.reload_on_as) {
|
||||
if (uwsgi.reload_on_as && (rlim_t) vsz >= uwsgi.reload_on_as) {
|
||||
goodbye_cruel_world();
|
||||
}
|
||||
|
||||
if (uwsgi.reload_on_rss && (int) (uwsgi.workers[uwsgi.mywid].rss_size / 1024 / 1024) >= uwsgi.reload_on_rss) {
|
||||
if (uwsgi.reload_on_rss && (rlim_t) rss >= uwsgi.reload_on_rss) {
|
||||
goodbye_cruel_world();
|
||||
}
|
||||
|
||||
@@ -751,12 +864,14 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_so
|
||||
}
|
||||
|
||||
uwsgi.core[wsgi_req->async_id]->in_request = 0;
|
||||
uwsgi.workers[uwsgi.mywid].busy = 0;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
int wsgi_req_async_recv(struct wsgi_request *wsgi_req) {
|
||||
|
||||
uwsgi.core[wsgi_req->async_id]->in_request = 1;
|
||||
uwsgi.workers[uwsgi.mywid].busy = 1;
|
||||
|
||||
gettimeofday(&wsgi_req->start_of_request, NULL);
|
||||
|
||||
@@ -782,6 +897,7 @@ int wsgi_req_async_recv(struct wsgi_request *wsgi_req) {
|
||||
int wsgi_req_recv(struct wsgi_request *wsgi_req) {
|
||||
|
||||
uwsgi.core[wsgi_req->async_id]->in_request = 1;
|
||||
uwsgi.workers[uwsgi.mywid].busy = 1;
|
||||
|
||||
gettimeofday(&wsgi_req->start_of_request, NULL);
|
||||
|
||||
@@ -1343,15 +1459,31 @@ int uwsgi_get_app_id(char *app_name, int app_name_len, int modifier1) {
|
||||
|
||||
int i;
|
||||
struct stat st;
|
||||
int found;
|
||||
|
||||
for (i = 0; i < uwsgi_apps_cnt; i++) {
|
||||
// reset check
|
||||
found = 0;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("searching for %.*s in %.*s %p\n", app_name_len, app_name, uwsgi_apps[i].mountpoint_len, uwsgi_apps[i].mountpoint, uwsgi_apps[i].callable);
|
||||
#endif
|
||||
if (!uwsgi_apps[i].callable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_PCRE
|
||||
if (uwsgi_apps[i].pattern) {
|
||||
if (uwsgi_regexp_match(uwsgi_apps[i].pattern, uwsgi_apps[i].pattern_extra, app_name, app_name_len) >= 0) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!uwsgi_strncmp(uwsgi_apps[i].mountpoint, uwsgi_apps[i].mountpoint_len, app_name, app_name_len)) {
|
||||
found = 1;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (uwsgi_apps[i].touch_reload) {
|
||||
if (!stat(uwsgi_apps[i].touch_reload, &st)) {
|
||||
if (st.st_mtime != uwsgi_apps[i].touch_reload_mtime) {
|
||||
@@ -1507,18 +1639,18 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
|
||||
}
|
||||
// manage buffered data and upload progress
|
||||
while (post_remains > 0) {
|
||||
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
}
|
||||
|
||||
ret = poll(&wsgi_req->poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] * 1000);
|
||||
ret = uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (ret < 0) {
|
||||
uwsgi_error("poll()");
|
||||
goto end;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
uwsgi_log("buffering POST data timedout !!!\n");
|
||||
uwsgi_log("buffering POST data timed-out !!!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -1543,7 +1675,7 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
|
||||
goto end;
|
||||
}
|
||||
|
||||
// resue buf for json buffer
|
||||
// reuse buf for json buffer
|
||||
ret = snprintf(buf, len, "{ \"state\" : \"uploading\", \"received\" : %d, \"size\" : %d }\r\n", (int) (wsgi_req->post_cl - post_remains), (int) wsgi_req->post_cl);
|
||||
if (ret < 0) {
|
||||
uwsgi_log("unable to write JSON data in upload progress file %s\n", upload_progress_filename);
|
||||
@@ -1583,24 +1715,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, ";");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1692,6 +1845,32 @@ int uwsgi_file_exists(char *filename) {
|
||||
return !access(filename, R_OK);
|
||||
}
|
||||
|
||||
char *uwsgi_read_fd(int fd, int *size, int add_zero) {
|
||||
|
||||
char stack_buf[4096];
|
||||
ssize_t len;
|
||||
char *buffer = NULL;
|
||||
|
||||
len = 1;
|
||||
while(len > 0) {
|
||||
len = read(fd, stack_buf, 4096);
|
||||
if (len > 0) {
|
||||
*size += len;
|
||||
buffer = realloc(buffer, *size);
|
||||
memcpy(buffer+(*size-len), stack_buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
if (add_zero) {
|
||||
*size = *size+1;
|
||||
buffer = realloc(buffer, *size);
|
||||
buffer[*size-1] = 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[]) {
|
||||
|
||||
int fd;
|
||||
@@ -1707,23 +1886,12 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
|
||||
// stdin ?
|
||||
if (!strcmp(url, "-")) {
|
||||
char stack_buf[4096];
|
||||
len = 1;
|
||||
while(len > 0) {
|
||||
len = read(0, stack_buf, 4096);
|
||||
if (len > 0) {
|
||||
*size += len;
|
||||
buffer = realloc(buffer, *size);
|
||||
memcpy(buffer+(*size-len), stack_buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
if (add_zero) {
|
||||
*size = *size+1;
|
||||
buffer = realloc(buffer, *size);
|
||||
buffer[*size-1] = 0;
|
||||
}
|
||||
|
||||
buffer = uwsgi_read_fd(0, size, add_zero);
|
||||
}
|
||||
// fd ?
|
||||
else if (!strncmp("fd://", url, 5)) {
|
||||
fd = atoi(url+5);
|
||||
buffer = uwsgi_read_fd(fd, size, add_zero);
|
||||
}
|
||||
// http url ?
|
||||
else if (!strncmp("http://", url, 7)) {
|
||||
@@ -1966,6 +2134,10 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (S_ISFIFO(sb.st_mode)) {
|
||||
buffer = uwsgi_read_fd(fd, size, add_zero);
|
||||
goto end;
|
||||
}
|
||||
|
||||
buffer = malloc(sb.st_size + add_zero);
|
||||
|
||||
@@ -1989,6 +2161,8 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
buffer[sb.st_size] = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (magic_table) {
|
||||
|
||||
magic_buf = magic_sub(buffer, *size, size, magic_table);
|
||||
@@ -2090,8 +2264,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;
|
||||
@@ -2154,6 +2333,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()");
|
||||
}
|
||||
@@ -2282,6 +2467,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;
|
||||
@@ -2438,6 +2654,37 @@ char *uwsgi_netstring(char *buf, size_t len, char **netstring, size_t *netstring
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **dd, char *key, int keylen, char *val, int vallen) {
|
||||
|
||||
struct uwsgi_dyn_dict *uwsgi_dd = *dd, *old_dd;
|
||||
|
||||
if (!uwsgi_dd) {
|
||||
*dd = uwsgi_malloc(sizeof(struct uwsgi_dyn_dict));
|
||||
uwsgi_dd = *dd;
|
||||
uwsgi_dd->prev = NULL;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_dd) {
|
||||
old_dd = uwsgi_dd;
|
||||
uwsgi_dd = uwsgi_dd->next;
|
||||
}
|
||||
|
||||
uwsgi_dd = uwsgi_malloc(sizeof(struct uwsgi_dyn_dict));
|
||||
old_dd->next = uwsgi_dd;
|
||||
uwsgi_dd->prev = old_dd;
|
||||
}
|
||||
|
||||
uwsgi_dd->key = key;
|
||||
uwsgi_dd->keylen = keylen;
|
||||
uwsgi_dd->value = val;
|
||||
uwsgi_dd->vallen = vallen;
|
||||
uwsgi_dd->hits = 0;
|
||||
uwsgi_dd->next = NULL;
|
||||
|
||||
return uwsgi_dd;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list, char *value) {
|
||||
|
||||
struct uwsgi_string_list *uwsgi_string = *list, *old_uwsgi_string;
|
||||
@@ -2457,12 +2704,34 @@ struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list,
|
||||
}
|
||||
|
||||
uwsgi_string->value = value;
|
||||
uwsgi_string->len = strlen(value);
|
||||
uwsgi_string->len = 0;
|
||||
if (value) {
|
||||
uwsgi_string->len = strlen(value);
|
||||
}
|
||||
uwsgi_string->next = NULL;
|
||||
|
||||
return uwsgi_string;
|
||||
}
|
||||
|
||||
char *uwsgi_string_get_list(struct uwsgi_string_list **list, int pos, size_t *len) {
|
||||
|
||||
struct uwsgi_string_list *uwsgi_string = *list;
|
||||
int counter = 0;
|
||||
|
||||
while(uwsgi_string) {
|
||||
if (counter == pos) {
|
||||
*len = uwsgi_string->len;
|
||||
return uwsgi_string->value;
|
||||
}
|
||||
uwsgi_string = uwsgi_string->next;
|
||||
counter++;
|
||||
}
|
||||
|
||||
*len = 0;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_string_del_list(struct uwsgi_string_list **list, struct uwsgi_string_list *item) {
|
||||
|
||||
@@ -2721,14 +2990,15 @@ char *uwsgi_get_binary_path(char *argvzero) {
|
||||
}
|
||||
free(buf);
|
||||
#elif defined(__sun__)
|
||||
// do not free this value !!!
|
||||
char *buf = (char *)getexecname();
|
||||
if (buf) {
|
||||
// return only absolute path
|
||||
if (buf[0] == '/') {
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *newbuf = realpath(buf, NULL);
|
||||
free(buf);
|
||||
if (newbuf) {
|
||||
return newbuf;
|
||||
}
|
||||
@@ -2751,3 +3021,369 @@ char *uwsgi_get_binary_path(char *argvzero) {
|
||||
return argvzero;
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_get_line(char *ptr, char *watermark, int *size) {
|
||||
char *p = ptr;
|
||||
int count = 0;
|
||||
|
||||
while(p < watermark) {
|
||||
if (*p == '\n') {
|
||||
*size = count;
|
||||
return ptr+count;
|
||||
}
|
||||
count++;
|
||||
p++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void uwsgi_build_mime_dict(char *filename) {
|
||||
|
||||
int size = 0;
|
||||
char *buf = uwsgi_open_and_read(filename, &size, 1, NULL);
|
||||
char *watermark = buf+size;
|
||||
|
||||
int linesize = 0;
|
||||
char *line = buf;
|
||||
int i;
|
||||
int type_size = 0;
|
||||
int ext_start = 0;
|
||||
int found ;
|
||||
int entries = 0;
|
||||
|
||||
uwsgi_log("building mime-types dictionary from file %s...", filename);
|
||||
|
||||
while(uwsgi_get_line(line, watermark, &linesize) != NULL) {
|
||||
found = 0;
|
||||
if (isalnum((int)line[0])) {
|
||||
// get the type size
|
||||
for(i=0;i<linesize;i++) {
|
||||
if (isblank((int)line[i])) {
|
||||
type_size = i;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) { line += linesize+1; continue;}
|
||||
found = 0;
|
||||
for(i=type_size;i<linesize;i++) {
|
||||
if (!isblank((int)line[i])) {
|
||||
ext_start = i;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) { line += linesize+1; continue;}
|
||||
|
||||
char *current = line+ext_start;
|
||||
int ext_size = 0;
|
||||
for(i=ext_start;i<linesize;i++) {
|
||||
if (isblank((int)line[i])) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%.*s %.*s\n", ext_size, current, type_size, line);
|
||||
#endif
|
||||
uwsgi_dyn_dict_new(&uwsgi.mimetypes, current, ext_size, line, type_size);
|
||||
entries++;
|
||||
ext_size = 0;
|
||||
current = NULL;
|
||||
continue;
|
||||
}
|
||||
else if (current == NULL) {
|
||||
current = line+i;
|
||||
}
|
||||
ext_size++;
|
||||
}
|
||||
if (current && ext_size > 1) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%.*s %.*s\n", ext_size, current, type_size, line);
|
||||
#endif
|
||||
uwsgi_dyn_dict_new(&uwsgi.mimetypes, current, ext_size, line, type_size);
|
||||
entries++;
|
||||
}
|
||||
|
||||
}
|
||||
line += linesize+1;
|
||||
}
|
||||
|
||||
uwsgi_log("%d entry found\n", entries);
|
||||
|
||||
}
|
||||
|
||||
#ifdef UWSGI_CAP
|
||||
struct uwsgi_cap {
|
||||
char *name;
|
||||
cap_value_t value;
|
||||
};
|
||||
|
||||
static struct uwsgi_cap uwsgi_cap_list[] = {
|
||||
{ "chown", CAP_CHOWN},
|
||||
{ "dac_override", CAP_DAC_OVERRIDE},
|
||||
{ "dac_read_search", CAP_DAC_READ_SEARCH},
|
||||
{ "fowner", CAP_FOWNER},
|
||||
{ "fsetid", CAP_FSETID},
|
||||
{ "kill", CAP_KILL},
|
||||
{ "setgid", CAP_SETGID},
|
||||
{ "setuid", CAP_SETUID},
|
||||
{ "setpcap", CAP_SETPCAP},
|
||||
{ "linux_immutable", CAP_LINUX_IMMUTABLE},
|
||||
{ "net_bind_service", CAP_NET_BIND_SERVICE},
|
||||
{ "net_broadcast", CAP_NET_BROADCAST},
|
||||
{ "net_admin", CAP_NET_ADMIN},
|
||||
{ "net_raw", CAP_NET_RAW},
|
||||
{ "ipc_lock", CAP_IPC_LOCK},
|
||||
{ "ipc_owner", CAP_IPC_OWNER},
|
||||
{ "sys_module", CAP_SYS_MODULE},
|
||||
{ "sys_rawio", CAP_SYS_RAWIO},
|
||||
{ "sys_chroot", CAP_SYS_CHROOT},
|
||||
{ "sys_ptrace", CAP_SYS_PTRACE},
|
||||
{ "sys_pacct", CAP_SYS_PACCT},
|
||||
{ "sys_admin", CAP_SYS_ADMIN},
|
||||
{ "sys_boot", CAP_SYS_BOOT},
|
||||
{ "sys_nice", CAP_SYS_NICE},
|
||||
{ "sys_resource", CAP_SYS_RESOURCE},
|
||||
{ "sys_time", CAP_SYS_TIME},
|
||||
{ "sys_tty_config", CAP_SYS_TTY_CONFIG},
|
||||
{ "mknod", CAP_MKNOD},
|
||||
{ "lease", CAP_LEASE},
|
||||
{ "audit_write", CAP_AUDIT_WRITE},
|
||||
{ "audit_control", CAP_AUDIT_CONTROL},
|
||||
{ "setfcap", CAP_SETFCAP},
|
||||
{ "mac_override", CAP_MAC_OVERRIDE},
|
||||
{ "mac_admin", CAP_MAC_ADMIN},
|
||||
{ "syslog", CAP_SYSLOG},
|
||||
{ "wake_alarm", CAP_WAKE_ALARM},
|
||||
{ NULL, -1}
|
||||
};
|
||||
|
||||
static int uwsgi_get_cap_id(char *name) {
|
||||
|
||||
struct uwsgi_cap *ucl = uwsgi_cap_list;
|
||||
while(ucl->name) {
|
||||
if (!strcmp(ucl->name, name)) return ucl->value;
|
||||
ucl++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void uwsgi_build_cap(char *what) {
|
||||
|
||||
int cap_id;
|
||||
char *caps = uwsgi_str(what);
|
||||
int pos = 0;
|
||||
uwsgi.cap_count = 0;
|
||||
|
||||
char *p = strtok(caps, ",");
|
||||
while (p != NULL) {
|
||||
if (is_a_number(p)) {
|
||||
uwsgi.cap_count++;
|
||||
}
|
||||
else {
|
||||
cap_id = uwsgi_get_cap_id(p);
|
||||
if (cap_id != -1) {
|
||||
uwsgi.cap_count++;
|
||||
}
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
free(caps);
|
||||
|
||||
uwsgi.cap = uwsgi_malloc( sizeof(cap_value_t) * uwsgi.cap_count);
|
||||
|
||||
caps = uwsgi_str(what);
|
||||
p = strtok(caps, ",");
|
||||
while (p != NULL) {
|
||||
if (is_a_number(p)) {
|
||||
cap_id = atoi(p);
|
||||
}
|
||||
else {
|
||||
cap_id = uwsgi_get_cap_id(p);
|
||||
}
|
||||
if (cap_id != -1) {
|
||||
uwsgi.cap[pos] = cap_id;
|
||||
uwsgi_log("setting capability %s [%d]\n", p, cap_id);
|
||||
pos++;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
free(caps);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void uwsgi_apply_config_pass(char symbol, char*(*hook)(char *) ) {
|
||||
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
int has_symbol = 0;
|
||||
char *magic_key = NULL;
|
||||
char *magic_val = NULL;
|
||||
if (uwsgi.exported_opts[i]->value && !uwsgi.exported_opts[i]->configured) {
|
||||
for (j = 0; j < (int) strlen(uwsgi.exported_opts[i]->value); j++) {
|
||||
if (uwsgi.exported_opts[i]->value[j] == symbol) {
|
||||
has_symbol = 1;
|
||||
}
|
||||
else if (uwsgi.exported_opts[i]->value[j] == '(' && has_symbol == 1) {
|
||||
has_symbol = 2;
|
||||
magic_key = uwsgi.exported_opts[i]->value + j + 1;
|
||||
}
|
||||
else if (has_symbol > 1) {
|
||||
if (uwsgi.exported_opts[i]->value[j] == ')') {
|
||||
if (has_symbol <= 2) {
|
||||
magic_key = NULL;
|
||||
has_symbol = 0;
|
||||
continue;
|
||||
}
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("need to interpret the %.*s tag\n", has_symbol - 2, magic_key);
|
||||
#endif
|
||||
char *tmp_magic_key = uwsgi_concat2n(magic_key, has_symbol - 2, "", 0);
|
||||
magic_val = hook(tmp_magic_key);
|
||||
free(tmp_magic_key);
|
||||
if (!magic_val) {
|
||||
magic_key = NULL;
|
||||
has_symbol = 0;
|
||||
continue;
|
||||
}
|
||||
uwsgi.exported_opts[i]->value = uwsgi_concat4n(uwsgi.exported_opts[i]->value, (magic_key - 2) - uwsgi.exported_opts[i]->value, magic_val, strlen(magic_val), magic_key + (has_symbol - 1), strlen(magic_key + (has_symbol - 1)), "", 0);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("computed new value = %s\n", uwsgi.exported_opts[i]->value);
|
||||
#endif
|
||||
magic_key = NULL;
|
||||
has_symbol = 0;
|
||||
j = 0;
|
||||
}
|
||||
else {
|
||||
has_symbol++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
has_symbol = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ extern "C" {
|
||||
#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__);
|
||||
#define uwsgi_req_error(x) if (wsgi_req->uri_len > 0 && wsgi_req->method_len > 0 && wsgi_req->remote_addr_len > 0) uwsgi_log_verbose("%s: %s [%s line %d] during %.*s %.*s (%.*s)\n", x, strerror(errno), __FILE__, __LINE__,\
|
||||
wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr); else uwsgi_log_verbose("%s %s [%s line %d] \n",x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
|
||||
#define uwsgi_rawlog(x) if (write(2, x, strlen(x)) != strlen(x)) uwsgi_error("write()")
|
||||
#define uwsgi_str(x) uwsgi_concat2(x, "")
|
||||
@@ -26,6 +28,8 @@ extern "C" {
|
||||
#define thunder_lock if (uwsgi.threads > 1) {pthread_mutex_lock(&uwsgi.thunder_mutex);}
|
||||
#define thunder_unlock if (uwsgi.threads > 1) {pthread_mutex_unlock(&uwsgi.thunder_mutex);}
|
||||
|
||||
#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5))
|
||||
|
||||
#define ushared uwsgi.shared
|
||||
|
||||
#define MAX_APPS 64
|
||||
@@ -112,6 +116,9 @@ extern char UWSGI_EMBED_CONFIG_END;
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#ifndef __USE_ISOC99
|
||||
#define __USE_ISOC99
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
@@ -145,10 +152,10 @@ extern char UWSGI_EMBED_CONFIG_END;
|
||||
#include <sys/reg.h>
|
||||
#endif
|
||||
extern int pivot_root(const char *new_root, const char *put_old);
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef UWSGI_SCTP
|
||||
@@ -222,6 +229,10 @@ extern int pivot_root(const char *new_root, const char *put_old);
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_CAP
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <kernel/OS.h>
|
||||
#endif
|
||||
@@ -278,9 +289,23 @@ struct uwsgi_string_list {
|
||||
|
||||
char *value;
|
||||
size_t len;
|
||||
uint64_t custom;
|
||||
struct uwsgi_string_list *next;
|
||||
};
|
||||
|
||||
struct uwsgi_dyn_dict {
|
||||
|
||||
char *key;
|
||||
int keylen;
|
||||
char *value;
|
||||
int vallen;
|
||||
|
||||
uint64_t hits;
|
||||
|
||||
struct uwsgi_dyn_dict *prev;
|
||||
struct uwsgi_dyn_dict *next;
|
||||
};
|
||||
|
||||
|
||||
union uwsgi_sockaddr {
|
||||
struct sockaddr sa;
|
||||
@@ -486,6 +511,28 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_FASTCGI_SOCKET 17133
|
||||
#define LONG_ARGS_THREADS_STACKSIZE 17134
|
||||
#define LONG_ARGS_EMPEROR_THROTTLE 17135
|
||||
#define LONG_ARGS_STOP 17136
|
||||
#define LONG_ARGS_RELOAD 17137
|
||||
#define LONG_ARGS_REGEXP_MOUNT 17138
|
||||
#define LONG_ARGS_MIMEFILE 17139
|
||||
#define LONG_ARGS_CHEAPER 17140
|
||||
#define LONG_ARGS_CAP 17141
|
||||
#define LONG_ARGS_STATS 17142
|
||||
#define LONG_ARGS_MULE 17143
|
||||
#define LONG_ARGS_LOG_MAXSIZE 17144
|
||||
#define LONG_ARGS_LOG_BACKUPNAME 17145
|
||||
#define LONG_ARGS_EVIL_RELOAD_ON_AS 17146
|
||||
#define LONG_ARGS_EVIL_RELOAD_ON_RSS 17147
|
||||
#define LONG_ARGS_SPOOLER_HARAKIRI 17148
|
||||
#define LONG_ARGS_MULE_HARAKIRI 17149
|
||||
#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 UWSGI_OK 0
|
||||
@@ -524,6 +571,8 @@ struct uwsgi_opt {
|
||||
#define UWSGI_OPTION_LOG_SENDFILE 14
|
||||
#define UWSGI_OPTION_BACKLOG_STATUS 15
|
||||
#define UWSGI_OPTION_BACKLOG_ERRORS 16
|
||||
#define UWSGI_OPTION_SPOOLER_HARAKIRI 17
|
||||
#define UWSGI_OPTION_MULE_HARAKIRI 18
|
||||
|
||||
#define UWSGI_MODIFIER_ADMIN_REQUEST 10
|
||||
#define UWSGI_MODIFIER_SPOOL_REQUEST 17
|
||||
@@ -582,6 +631,8 @@ struct uwsgi_socket {
|
||||
int disabled;
|
||||
|
||||
struct uwsgi_socket *next;
|
||||
int shared;
|
||||
int from_shared;
|
||||
};
|
||||
|
||||
struct uwsgi_server;
|
||||
@@ -605,7 +656,7 @@ struct uwsgi_plugin {
|
||||
void (*init_apps) (void);
|
||||
void (*fixup) (void);
|
||||
void (*master_fixup) (int);
|
||||
int (*mount_app) (char *, char *);
|
||||
int (*mount_app) (char *, char *, int);
|
||||
int (*manage_udp) (char *, int, char *, int);
|
||||
int (*manage_xml) (char *, char *);
|
||||
void (*suspend) (struct wsgi_request *);
|
||||
@@ -623,14 +674,22 @@ struct uwsgi_plugin {
|
||||
|
||||
int (*spooler) (char *, char *, uint16_t, char *, size_t);
|
||||
|
||||
uint16_t(*rpc) (void *, uint8_t, char **, char *);
|
||||
uint16_t(*rpc) (void *, uint8_t, char **, char *);
|
||||
|
||||
void (*jail) (int (*)(void *), char **);
|
||||
|
||||
int (*mule)(char *);
|
||||
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_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
struct uwsgi_app {
|
||||
|
||||
@@ -639,6 +698,11 @@ struct uwsgi_app {
|
||||
char *mountpoint;
|
||||
int mountpoint_len;
|
||||
|
||||
#ifdef UWSGI_PCRE
|
||||
pcre *pattern;
|
||||
pcre_extra *pattern_extra;
|
||||
#endif
|
||||
|
||||
void *interpreter;
|
||||
void *callable;
|
||||
|
||||
@@ -673,6 +737,7 @@ struct uwsgi_app {
|
||||
void *uwsgi_version;
|
||||
void *uwsgi_node;
|
||||
|
||||
uint64_t avg_response_time;
|
||||
};
|
||||
|
||||
|
||||
@@ -763,6 +828,7 @@ struct wsgi_request {
|
||||
|
||||
char *path_info;
|
||||
uint16_t path_info_len;
|
||||
int path_info_pos;
|
||||
|
||||
char *script;
|
||||
uint16_t script_len;
|
||||
@@ -901,39 +967,81 @@ struct uwsgi_signal_rb_timer {
|
||||
struct uwsgi_server {
|
||||
|
||||
|
||||
// store the machine hostname
|
||||
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;
|
||||
|
||||
// enable threads
|
||||
int has_threads;
|
||||
|
||||
// default app id
|
||||
int default_app;
|
||||
|
||||
char *logto2;
|
||||
|
||||
// autoload plugins
|
||||
int autoload;
|
||||
|
||||
int snapshot;
|
||||
|
||||
// enable auto-snapshotting
|
||||
int auto_snapshot;
|
||||
pid_t restore_snapshot;
|
||||
|
||||
|
||||
int respawn_workers;
|
||||
unsigned int reloads;
|
||||
|
||||
// leave master running as root
|
||||
int master_as_root;
|
||||
// kill the stack on SIGTERM (instead of brutal reloading)
|
||||
int die_on_term;
|
||||
|
||||
// disable fd passing on unix socket
|
||||
int no_fd_passing;
|
||||
|
||||
// store the current time
|
||||
time_t current_time;
|
||||
|
||||
uint64_t master_cycles;
|
||||
|
||||
int reuse_port;
|
||||
|
||||
// enable lazy mode
|
||||
int lazy;
|
||||
// enable cheap mode
|
||||
int cheap;
|
||||
// enable cheaper mode
|
||||
int cheaper;
|
||||
// minimal number of running workers in cheaper mode
|
||||
int cheaper_count;
|
||||
// enable idle mode
|
||||
int idle;
|
||||
|
||||
// destroy the stack when idle
|
||||
int die_on_idle;
|
||||
|
||||
// store the screen session
|
||||
char *screen_session;
|
||||
|
||||
// true if run under the emperor
|
||||
int has_emperor;
|
||||
int emperor_fd;
|
||||
int emperor_tyrant;
|
||||
int emperor_fd_config;
|
||||
int early_emperor;
|
||||
int emperor_throttle;
|
||||
@@ -941,50 +1049,77 @@ struct uwsgi_server {
|
||||
pid_t emperor_pid;
|
||||
int emperor_broodlord;
|
||||
int emperor_broodlord_count;
|
||||
char *emperor_stats;
|
||||
int emperor_stats_fd;
|
||||
struct uwsgi_config_template *vassals_templates;
|
||||
// true if loyal to the emperor
|
||||
int loyal;
|
||||
|
||||
// amqp support
|
||||
char *emperor_amqp_vhost;
|
||||
char *emperor_amqp_username;
|
||||
char *emperor_amqp_password;
|
||||
|
||||
// emperor hook (still in development)
|
||||
char *vassals_start_hook;
|
||||
char *vassals_stop_hook;
|
||||
|
||||
struct uwsgi_string_list *additional_headers;
|
||||
|
||||
// maximum time to wait after a reload
|
||||
time_t master_mercy;
|
||||
|
||||
// set cpu affinity
|
||||
int cpu_affinity;
|
||||
|
||||
int reload_mercy;
|
||||
// map reloads to death
|
||||
int exit_on_reload;
|
||||
|
||||
// store options
|
||||
int option_index;
|
||||
struct option *long_options;
|
||||
struct uwsgi_opt **exported_opts;
|
||||
int exported_opts_cnt;
|
||||
|
||||
// dump the whole set of options
|
||||
int dump_options;
|
||||
// show ini representation of the current config
|
||||
int show_config;
|
||||
|
||||
//base for all the requests(even on async mode)
|
||||
struct wsgi_request **wsgi_requests;
|
||||
struct wsgi_request *wsgi_req;
|
||||
|
||||
char *remap_modifier;
|
||||
|
||||
// enable zerg mode
|
||||
int *zerg;
|
||||
char *zerg_server;
|
||||
int zerg_server_fd;
|
||||
|
||||
// security
|
||||
char *chroot;
|
||||
gid_t gid;
|
||||
uid_t uid;
|
||||
char *uidname;
|
||||
char *gidname;
|
||||
|
||||
#ifdef UWSGI_CAP
|
||||
cap_value_t *cap;
|
||||
int cap_count;
|
||||
#endif
|
||||
|
||||
// still working on it
|
||||
char *profiler;
|
||||
|
||||
// mostly useless
|
||||
char *mode;
|
||||
|
||||
// binary path the worker image
|
||||
char *worker_exec;
|
||||
|
||||
// gateways
|
||||
struct uwsgi_gateway gateways[MAX_GATEWAYS];
|
||||
int gateways_cnt;
|
||||
|
||||
@@ -992,13 +1127,22 @@ struct uwsgi_server {
|
||||
int ignore_script_name;
|
||||
int manage_script_name;
|
||||
int no_default_app;
|
||||
|
||||
int logdate;
|
||||
int log_micros;
|
||||
char *log_strftime;
|
||||
int log_x_forwarded_for;
|
||||
|
||||
int honour_stdin;
|
||||
|
||||
// route all of the logs to the master process
|
||||
int log_master;
|
||||
|
||||
int log_reopen;
|
||||
int log_truncate;
|
||||
off_t log_maxsize;
|
||||
char *log_backupname;
|
||||
|
||||
int log_syslog;
|
||||
int original_log_fd;
|
||||
|
||||
@@ -1007,15 +1151,21 @@ struct uwsgi_server {
|
||||
union uwsgi_sockaddr *log_socket_addr;
|
||||
socklen_t log_socket_size;
|
||||
|
||||
|
||||
// static file serving
|
||||
char *check_static;
|
||||
size_t check_static_len;
|
||||
int file_serve_mode;
|
||||
|
||||
int build_mime_dict;
|
||||
char *mime_file;
|
||||
struct uwsgi_static_map *static_maps;
|
||||
struct uwsgi_dyn_dict *mimetypes;
|
||||
|
||||
char *logfile;
|
||||
int logfile_chown;
|
||||
|
||||
// enable vhost mode
|
||||
int vhost;
|
||||
int vhost_host;
|
||||
|
||||
@@ -1023,6 +1173,7 @@ struct uwsgi_server {
|
||||
char **async_buf;
|
||||
char **async_post_buf;
|
||||
|
||||
// async commodity
|
||||
struct wsgi_request **async_waiting_fd_table;
|
||||
struct wsgi_request **async_proto_fd_table;
|
||||
struct uwsgi_async_request *async_runqueue;
|
||||
@@ -1039,19 +1190,27 @@ struct uwsgi_server {
|
||||
int **async_ovector;
|
||||
#endif
|
||||
|
||||
// store rlimit
|
||||
struct rlimit rl;
|
||||
size_t limit_post;
|
||||
|
||||
// set process priority
|
||||
int prio;
|
||||
|
||||
int reload_on_as;
|
||||
int reload_on_rss;
|
||||
char *touch_reload;
|
||||
time_t last_touch_reload_mtime;
|
||||
// funny reload systems
|
||||
int force_get_memusage;
|
||||
rlim_t reload_on_as;
|
||||
rlim_t reload_on_rss;
|
||||
rlim_t evil_reload_on_as;
|
||||
rlim_t evil_reload_on_rss;
|
||||
struct uwsgi_string_list *touch_reload;
|
||||
|
||||
int propagate_touch;
|
||||
|
||||
// enable grunt mode
|
||||
int grunt;
|
||||
|
||||
// store the binary path
|
||||
char *binary_path;
|
||||
|
||||
int is_a_reload;
|
||||
@@ -1067,7 +1226,9 @@ struct uwsgi_server {
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
char *spool_dir;
|
||||
char *spooler_chdir;
|
||||
int spooler_ordered;
|
||||
uint64_t spooler_respawned;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
@@ -1085,6 +1246,7 @@ struct uwsgi_server {
|
||||
|
||||
int buffer_size;
|
||||
|
||||
// post buffering
|
||||
int post_buffering;
|
||||
int post_buffering_harakiri;
|
||||
int post_buffering_bufsize;
|
||||
@@ -1092,6 +1254,7 @@ struct uwsgi_server {
|
||||
int master_process;
|
||||
int master_queue;
|
||||
|
||||
// mainly iseful for broodlord mode
|
||||
int vassal_sos_backlog;
|
||||
|
||||
int no_defer_accept;
|
||||
@@ -1116,10 +1279,12 @@ struct uwsgi_server {
|
||||
int max_vars;
|
||||
int vec_size;
|
||||
|
||||
// shared area
|
||||
char *sharedarea;
|
||||
uint64_t sharedareasize;
|
||||
|
||||
#ifdef UWSGI_THREADING
|
||||
// avoid thundering herd in threaded modes
|
||||
pthread_mutex_t six_feet_under_lock;
|
||||
#endif
|
||||
|
||||
@@ -1127,12 +1292,19 @@ struct uwsgi_server {
|
||||
/* the list of workers */
|
||||
struct uwsgi_worker *workers;
|
||||
|
||||
/* the dedicated signal_pipe */
|
||||
int **signal_pipe;
|
||||
/* 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;
|
||||
|
||||
struct timeval start_tv;
|
||||
@@ -1172,7 +1344,7 @@ struct uwsgi_server {
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_INI
|
||||
char *ini;
|
||||
struct uwsgi_string_list *ini;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SQLITE3
|
||||
@@ -1203,6 +1375,7 @@ struct uwsgi_server {
|
||||
|
||||
char *cwd;
|
||||
|
||||
// conditional logging
|
||||
int log_slow_requests;
|
||||
int log_zero_headers;
|
||||
int log_empty_body;
|
||||
@@ -1304,6 +1477,10 @@ struct uwsgi_server {
|
||||
int cache_server_fd;
|
||||
pthread_mutex_t cache_server_lock;
|
||||
|
||||
// the stats server
|
||||
char *stats;
|
||||
int stats_fd;
|
||||
|
||||
uint64_t queue_size;
|
||||
uint64_t queue_blocksize;
|
||||
void *queue;
|
||||
@@ -1314,9 +1491,11 @@ struct uwsgi_server {
|
||||
|
||||
pthread_mutex_t thunder_mutex;
|
||||
|
||||
int locks;
|
||||
|
||||
void *cache_lock;
|
||||
void *queue_lock;
|
||||
void *user_lock;
|
||||
void **user_lock;
|
||||
void *signal_table_lock;
|
||||
void *fmon_table_lock;
|
||||
void *timer_table_lock;
|
||||
@@ -1333,6 +1512,7 @@ struct uwsgi_server {
|
||||
char *startup_daemons[MAX_DAEMONS];
|
||||
int startup_daemons_cnt;
|
||||
|
||||
// subscription client
|
||||
char *subscriptions[MAX_SUBSCRIPTIONS];
|
||||
int subscriptions_cnt;
|
||||
|
||||
@@ -1433,6 +1613,7 @@ struct uwsgi_shared {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
pid_t spooler_pid;
|
||||
int spooler_frequency;
|
||||
time_t spooler_harakiri;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
@@ -1454,6 +1635,8 @@ struct uwsgi_shared {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
int spooler_signal_pipe[2];
|
||||
#endif
|
||||
int mule_signal_pipe[2];
|
||||
|
||||
struct uwsgi_signal_entry signal_table[256];
|
||||
|
||||
struct uwsgi_fmon files_monitored[64];
|
||||
@@ -1524,8 +1707,7 @@ struct uwsgi_worker {
|
||||
uint64_t vsz_size;
|
||||
uint64_t rss_size;
|
||||
|
||||
double running_time;
|
||||
double last_running_time;
|
||||
uint64_t running_time;
|
||||
|
||||
int manage_next_request;
|
||||
|
||||
@@ -1536,9 +1718,64 @@ struct uwsgi_worker {
|
||||
int apps_cnt;
|
||||
struct uwsgi_app apps[MAX_APPS];
|
||||
|
||||
uint64_t tx;
|
||||
|
||||
int busy;
|
||||
int cheaped;
|
||||
int sig;
|
||||
uint8_t signum;
|
||||
|
||||
// signals managed by this worker
|
||||
uint64_t signals;
|
||||
|
||||
int signal_pipe[2];
|
||||
|
||||
uint64_t avg_response_time;
|
||||
|
||||
char name[0xff];
|
||||
};
|
||||
|
||||
|
||||
struct uwsgi_mule {
|
||||
int id;
|
||||
pid_t pid;
|
||||
|
||||
int signal_pipe[2];
|
||||
int queue_pipe[2];
|
||||
|
||||
time_t last_spawn;
|
||||
uint64_t respawn_count;
|
||||
|
||||
char *patch;
|
||||
|
||||
// signals managed by this mule
|
||||
uint64_t signals;
|
||||
int sig;
|
||||
uint8_t signum;
|
||||
|
||||
time_t harakiri;
|
||||
|
||||
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);
|
||||
|
||||
void warn_pipe(void);
|
||||
@@ -1565,7 +1802,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);
|
||||
@@ -1588,6 +1825,8 @@ pid_t spooler_start(void);
|
||||
#endif
|
||||
|
||||
void set_harakiri(int);
|
||||
void set_mule_harakiri(int);
|
||||
void set_spooler_harakiri(int);
|
||||
void inc_harakiri(int);
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
@@ -1706,7 +1945,7 @@ char *uwsgi_concat4n(char *, int, char *, int, char *, int, char *, int);
|
||||
int uwsgi_get_app_id(char *, int, int);
|
||||
char *uwsgi_strncopy(char *, int);
|
||||
|
||||
void master_loop(char **, char **);
|
||||
int master_loop(char **, char **);
|
||||
|
||||
|
||||
int find_worker_id(pid_t);
|
||||
@@ -1908,6 +2147,9 @@ struct uwsgi_dict {
|
||||
|
||||
void *data;
|
||||
void *lock;
|
||||
|
||||
uint64_t count;
|
||||
|
||||
struct uwsgi_dict_item *items;
|
||||
};
|
||||
|
||||
@@ -2113,6 +2355,7 @@ socklen_t socket_to_in_addr(char *, char *, struct sockaddr_in *);
|
||||
socklen_t socket_to_un_addr(char *, struct sockaddr_un *);
|
||||
|
||||
int uwsgi_get_shared_socket_fd_by_num(int);
|
||||
struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int);
|
||||
|
||||
int uwsgi_get_shared_socket_num(struct uwsgi_socket *);
|
||||
|
||||
@@ -2155,6 +2398,34 @@ char *uwsgi_str_contains(char *, int, char);
|
||||
|
||||
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_send_stats(int);
|
||||
|
||||
void uwsgi_apply_config_pass(char symbol, char*(*)(char *) );
|
||||
|
||||
void uwsgi_mule(int);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef UWSGI_CAP
|
||||
void uwsgi_build_cap(char *);
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
int uwsgi_init(int, char **, char **);
|
||||
#endif
|
||||
|
||||
@@ -264,20 +264,36 @@ $(document).ready(function() {
|
||||
<a name="workers"></a>
|
||||
<h3>Workers</h3>
|
||||
<div class="info">
|
||||
<table width="400">
|
||||
<table width="600">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>pid</th>
|
||||
<th>status</th>
|
||||
<th>requests</th>
|
||||
<th>exceptions</th>
|
||||
<th>signals</th>
|
||||
<th>running time</th>
|
||||
<th>avg response time</th>
|
||||
{% if 'memory-report' in uwsgi.opt %}
|
||||
<th>rss</th>
|
||||
<th>vsz</th>
|
||||
{% endif %}
|
||||
<th># respawn</th>
|
||||
</tr>
|
||||
{% for w in uwsgi.workers() %}
|
||||
<tr class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td>{{w.id}}</td>
|
||||
<td>{{w.pid}}</td>
|
||||
<td>{{w.status}}</td>
|
||||
<td>{{w.requests}}</td>
|
||||
<td>{{w.exceptions}}</td>
|
||||
<td>{{w.signals}}</td>
|
||||
<td>{{w.running_time/1000}}</td>
|
||||
<td>{{w.avg_rt/1000}}</td>
|
||||
{% if 'memory-report' in uwsgi.opt %}
|
||||
<td>{{(w.rss/1000/1000)|round(2,'floor')}}MB</td>
|
||||
<td>{{(w.vsz/1000/1000)|round(2,'floor')}}MB</td>
|
||||
{% endif %}
|
||||
<td>{{w.respawn_count}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -294,7 +310,7 @@ $(document).ready(function() {
|
||||
<div class="info">
|
||||
{% for w in uwsgi.workers() %}
|
||||
worker {{w.id}}
|
||||
<table width="400">
|
||||
<table width="600">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>modifier1</th>
|
||||
|
||||
+111
-22
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '0.9.9-dev'
|
||||
uwsgi_version = '1.0-dev'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -25,13 +25,15 @@ GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
|
||||
if not GCC:
|
||||
GCC = 'gcc'
|
||||
|
||||
CPP = os.environ.get('CPP', 'cpp')
|
||||
|
||||
binary_list = []
|
||||
|
||||
def binarize(name):
|
||||
return name.replace('/', '_').replace('.','_').replace('-','_')
|
||||
|
||||
def spcall(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=open('/dev/null','w'))
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=open('uwsgibuild.log','w'))
|
||||
|
||||
if p.wait() == 0:
|
||||
if sys.version_info[0] > 2:
|
||||
@@ -57,10 +59,22 @@ def spcall2(cmd):
|
||||
else:
|
||||
return None
|
||||
|
||||
def spcall3(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdin=open('/dev/null'), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
|
||||
if p.wait() == 0:
|
||||
if sys.version_info[0] > 2:
|
||||
return p.stderr.read().rstrip().decode()
|
||||
return p.stderr.read().rstrip()
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def add_o(x):
|
||||
if x == 'uwsgi':
|
||||
x = 'main'
|
||||
elif x.endswith('.a'):
|
||||
return x
|
||||
x = x + '.o'
|
||||
return x
|
||||
|
||||
@@ -100,7 +114,7 @@ def build_uwsgi(uc):
|
||||
epc = "-DUWSGI_DECLARE_EMBEDDED_PLUGINS=\""
|
||||
eplc = "-DUWSGI_LOAD_EMBEDDED_PLUGINS=\""
|
||||
for p in ep:
|
||||
p = p.rstrip().lstrip()
|
||||
p = p.strip()
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
continue
|
||||
@@ -117,7 +131,8 @@ def build_uwsgi(uc):
|
||||
objfile = file
|
||||
if objfile == 'uwsgi':
|
||||
objfile = 'main'
|
||||
compile(' '.join(cflags), objfile + '.o', file + '.c')
|
||||
if not objfile.endswith('.a'):
|
||||
compile(' '.join(cflags), objfile + '.o', file + '.c')
|
||||
|
||||
if uc.get('embedded_plugins'):
|
||||
ep = uc.get('embedded_plugins').split(',')
|
||||
@@ -125,7 +140,7 @@ def build_uwsgi(uc):
|
||||
if len(ep) > 0:
|
||||
print("*** uWSGI compiling embedded plugins ***")
|
||||
for p in ep:
|
||||
p = p.rstrip().lstrip()
|
||||
p = p.strip()
|
||||
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
@@ -140,10 +155,18 @@ def build_uwsgi(uc):
|
||||
p_cflags = cflags[:]
|
||||
p_cflags += up.CFLAGS
|
||||
|
||||
try:
|
||||
p_cflags.remove('-Wdeclaration-after-statement')
|
||||
except:
|
||||
pass
|
||||
|
||||
for cfile in up.GCC_LIST:
|
||||
compile(' '.join(p_cflags),
|
||||
path + '/' + cfile + '.o', path + '/' + cfile + '.c')
|
||||
gcc_list.append('%s/%s' % (path, cfile))
|
||||
if not cfile.endswith('.a'):
|
||||
compile(' '.join(p_cflags),
|
||||
path + '/' + cfile + '.o', path + '/' + cfile + '.c')
|
||||
gcc_list.append('%s/%s' % (path, cfile))
|
||||
else:
|
||||
gcc_list.append(cfile)
|
||||
|
||||
libs += up.LIBS
|
||||
ldflags += up.LDFLAGS
|
||||
@@ -160,7 +183,7 @@ def build_uwsgi(uc):
|
||||
print("*** uWSGI building plugins ***")
|
||||
|
||||
for p in plugins:
|
||||
p = p.rstrip().lstrip()
|
||||
p = p.strip()
|
||||
print("*** building plugin: %s ***" % p)
|
||||
build_plugin("plugins/%s" % p, uc, cflags, ldflags, libs)
|
||||
|
||||
@@ -195,25 +218,62 @@ class uConf(object):
|
||||
print("using profile: %s" % filename)
|
||||
if not os.path.exists(filename):
|
||||
raise Exception("profile not found !!!")
|
||||
|
||||
if os.path.exists('uwsgibuild.lastprofile'):
|
||||
ulp = open('uwsgibuild.lastprofile','r')
|
||||
last_profile = ulp.read()
|
||||
ulp.close()
|
||||
if last_profile != filename:
|
||||
os.environ['UWSGI_FORCE_REBUILD'] = '1'
|
||||
|
||||
ulp = open('uwsgibuild.lastprofile','w')
|
||||
ulp.write(filename)
|
||||
ulp.close()
|
||||
|
||||
self.config.read(filename)
|
||||
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify',
|
||||
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify', 'mule',
|
||||
'plugins', 'lock', 'cache', 'queue', 'event', 'signal', 'rpc', 'gateway', 'loop', 'lib/rbtree', 'lib/amqp', 'rb_timers', 'uwsgi']
|
||||
# add protocols
|
||||
self.gcc_list.append('proto/base')
|
||||
self.gcc_list.append('proto/uwsgi')
|
||||
self.gcc_list.append('proto/http')
|
||||
self.gcc_list.append('proto/fastcgi')
|
||||
self.include_path = []
|
||||
if uwsgi_os == 'Linux':
|
||||
self.gcc_list.append('lib/linux_ns')
|
||||
self.gcc_list.append('lib/netlink')
|
||||
self.cflags = ['-O2', '-Wall', '-Werror', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] + os.environ.get("CFLAGS", "").split()
|
||||
|
||||
try:
|
||||
gcc_version = str(spcall("%s -dumpversion" % GCC))
|
||||
except:
|
||||
print("*** you need a c compiler to build uWSGI ***")
|
||||
sys.exit(1)
|
||||
gcc_major = int(gcc_version.split('.')[0])
|
||||
gcc_minor = int(gcc_version.split('.')[1])
|
||||
|
||||
try:
|
||||
add_it = False
|
||||
cpp_include_list = str(spcall3("%s -v" % CPP)).split("\n")
|
||||
for line in cpp_include_list:
|
||||
if line.startswith('#include <...> search starts here:'):
|
||||
add_it = True
|
||||
elif line.startswith('End of search list.'):
|
||||
add_it = False
|
||||
elif add_it:
|
||||
self.include_path.append(line.strip().split()[0])
|
||||
|
||||
if not self.include_path:
|
||||
raise
|
||||
except:
|
||||
self.include_path = ['/usr/include', '/usr/local/include']
|
||||
|
||||
|
||||
print("detected include path: %s" % self.include_path)
|
||||
|
||||
try:
|
||||
gcc_major = int(gcc_version.split('.')[0])
|
||||
gcc_minor = int(gcc_version.split('.')[1])
|
||||
except:
|
||||
raise Exception("you need a C compiler to build uWSGI")
|
||||
if (sys.version_info[0] == 2) or (gcc_major < 4) or (gcc_major == 4 and gcc_minor < 3):
|
||||
self.cflags = self.cflags + ['-fno-strict-aliasing']
|
||||
# add -fno-strict-aliasing only on python2 and gcc < 4.3
|
||||
@@ -266,6 +326,12 @@ class uConf(object):
|
||||
print("%s needs %s support." % (what, d))
|
||||
sys.exit(1)
|
||||
|
||||
def has_include(self, what):
|
||||
for include in self.include_path:
|
||||
if os.path.exists("%s/%s" %(include, what)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_gcll(self):
|
||||
|
||||
global uwsgi_version
|
||||
@@ -273,7 +339,7 @@ class uConf(object):
|
||||
self.cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
|
||||
kvm_list = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly']
|
||||
|
||||
if os.path.exists('/usr/include/ifaddrs.h') or os.path.exists('/usr/local/include/ifaddrs.h'):
|
||||
if self.has_include('ifaddrs.h'):
|
||||
self.cflags.append('-DUWSGI_HAS_IFADDRS')
|
||||
|
||||
if uwsgi_os == 'SunOS':
|
||||
@@ -369,7 +435,7 @@ class uConf(object):
|
||||
|
||||
if timer_mode == 'timerfd':
|
||||
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_TIMERFD')
|
||||
if not os.path.exists('/usr/include/sys/timerfd.h') and not os.path.exists('/usr/local/include/sys/timerfd.h'):
|
||||
if not self.has_include('sys/timerfd.h'):
|
||||
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_TIMERFD_NOINC')
|
||||
elif timer_mode == 'kqueue':
|
||||
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_KQUEUE')
|
||||
@@ -412,6 +478,9 @@ class uConf(object):
|
||||
self.ldflags.append('-shared')
|
||||
self.ldflags.append('-fPIC')
|
||||
self.cflags.append('-DUWSGI_AS_SHARED_LIBRARY')
|
||||
if uwsgi_os == 'Darwin':
|
||||
self.ldflags.append('-dynamiclib')
|
||||
self.ldflags.append('-undefined dynamic_lookup')
|
||||
|
||||
if self.get('embedded'):
|
||||
self.cflags.append('-DUWSGI_EMBEDDED')
|
||||
@@ -420,7 +489,7 @@ class uConf(object):
|
||||
self.cflags.append("-DUWSGI_UDP")
|
||||
|
||||
# re-enable after pcre fix
|
||||
if self.get('pcreOFF'):
|
||||
if self.get('pcre'):
|
||||
if self.get('pcre') == 'auto':
|
||||
pcreconf = spcall('pcre-config --libs')
|
||||
if pcreconf:
|
||||
@@ -442,10 +511,14 @@ class uConf(object):
|
||||
self.gcc_list.append('regexp')
|
||||
self.cflags.append("-DUWSGI_PCRE")
|
||||
|
||||
if self.has_include('sys/capability.h'):
|
||||
self.cflags.append("-DUWSGI_CAP")
|
||||
self.libs.append('-lcap')
|
||||
|
||||
has_json = False
|
||||
has_uuid = False
|
||||
|
||||
if os.path.exists('/usr/include/uuid/uuid.h') or os.path.exists('/usr/local/include/uuid/uuid.h'):
|
||||
if self.has_include('uuid/uuid.h'):
|
||||
has_uuid = True
|
||||
self.cflags.append("-DUWSGI_UUID")
|
||||
if os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
|
||||
@@ -550,7 +623,7 @@ class uConf(object):
|
||||
self.cflags.append("-DUWSGI_LIBYAML")
|
||||
self.libs.append('-lyaml')
|
||||
if self.get('yaml_implementation') == 'auto':
|
||||
if os.path.exists('/usr/include/yaml.h') or os.path.exists('/usr/local/include/yaml.h'):
|
||||
if self.has_include('yaml.h'):
|
||||
self.cflags.append("-DUWSGI_LIBYAML")
|
||||
self.libs.append('-lyaml')
|
||||
|
||||
@@ -563,7 +636,7 @@ class uConf(object):
|
||||
self.gcc_list.append('json')
|
||||
self.libs.append(spcall("pkg-config --libs jansson"))
|
||||
has_json = True
|
||||
elif os.path.exists('/usr/include/jansson.h') or os.path.exists('/usr/local/include/jansson.h'):
|
||||
elif self.has_include('jansson.h'):
|
||||
self.cflags.append("-DUWSGI_JSON")
|
||||
self.gcc_list.append('json')
|
||||
self.libs.append('-ljansson')
|
||||
@@ -576,7 +649,7 @@ class uConf(object):
|
||||
|
||||
if self.get('ldap'):
|
||||
if self.get('ldap') == 'auto':
|
||||
if os.path.exists('/usr/include/ldap.h'):
|
||||
if self.has_include('ldap.h'):
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
@@ -587,7 +660,7 @@ class uConf(object):
|
||||
|
||||
if has_uuid and self.get('zeromq'):
|
||||
if self.get('zeromq') == 'auto':
|
||||
if os.path.exists('/usr/include/zmq.h') or os.path.exists('/usr/local/include/zmq.h'):
|
||||
if self.has_include('zmq.h'):
|
||||
self.cflags.append("-DUWSGI_ZEROMQ")
|
||||
self.gcc_list.append('proto/zeromq')
|
||||
self.libs.append('-lzmq')
|
||||
@@ -635,7 +708,7 @@ class uConf(object):
|
||||
|
||||
if self.get('sqlite3'):
|
||||
if self.get('sqlite3') == 'auto':
|
||||
if os.path.exists('/usr/include/sqlite3.h') or os.path.exists('/usr/local/include/sqlite3.h'):
|
||||
if self.has_include('sqlite3.h'):
|
||||
self.cflags.append("-DUWSGI_SQLITE3")
|
||||
self.libs.append('-lsqlite3')
|
||||
self.gcc_list.append('sqlite3')
|
||||
@@ -683,6 +756,12 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
else:
|
||||
p_cflags.append("-D%s_plugin=%s_plugin" % (up.NAME, name))
|
||||
|
||||
try:
|
||||
for opt in uc.config.options(name):
|
||||
p_cflags.append('-DUWSGI_PLUGIN_%s_%s="%s"' % (name.upper(), opt.upper(), uc.config.get(name, opt, '1')))
|
||||
except:
|
||||
pass
|
||||
|
||||
plugin_dest = uc.get('plugin_dir') + '/' + name + '_plugin'
|
||||
|
||||
shared_flag = '-shared'
|
||||
@@ -693,7 +772,9 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
shared_flag = '-dynamiclib -undefined dynamic_lookup'
|
||||
|
||||
for cfile in up.GCC_LIST:
|
||||
if not cfile.endswith('.c') and not cfile.endswith('.cc'):
|
||||
if cfile.endswith('.a'):
|
||||
gcc_list.append(cfile)
|
||||
elif not cfile.endswith('.c') and not cfile.endswith('.cc'):
|
||||
gcc_list.append(path + '/' + cfile + '.c')
|
||||
else:
|
||||
gcc_list.append(path + '/' + cfile)
|
||||
@@ -703,6 +784,14 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
p_cflags.remove('-Wdeclaration-after-statement')
|
||||
except:
|
||||
pass
|
||||
|
||||
#for ofile in up.OBJ_LIST:
|
||||
# gcc_list.insert(0,ofile)
|
||||
|
||||
gccline = "%s -fPIC %s -o %s.so %s %s %s %s" % (GCC, shared_flag, plugin_dest, ' '.join(p_cflags), ' '.join(p_ldflags), ' '.join(gcc_list), ' '.join(p_libs) )
|
||||
print(gccline)
|
||||
|
||||
|
||||
@@ -84,6 +84,30 @@ 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 signal(object):
|
||||
|
||||
def __init__(self, num, **kwargs):
|
||||
@@ -153,6 +177,9 @@ class lock(object):
|
||||
self.f = f
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
# ensure the spooler will not call it
|
||||
if uwsgi.i_am_the_spooler():
|
||||
return
|
||||
uwsgi.lock()
|
||||
try:
|
||||
return self.f(*args, **kwargs)
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
[uwsgi]
|
||||
socket = :$(PORT)
|
||||
socket = /tmp/uwsgi_welcome.socket
|
||||
vacuum = true
|
||||
appname = welcome
|
||||
module = %(appname)
|
||||
numproc = 4
|
||||
master = %(vacuum)
|
||||
processes = %(numproc)
|
||||
mount = /werkzeug=tests/werkzeug.py
|
||||
manage-script-name = true
|
||||
+63
-1
@@ -1,5 +1,23 @@
|
||||
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
|
||||
|
||||
try:
|
||||
if sys.argv[1] == 'debug':
|
||||
DEBUG = True
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
DEBUG = False
|
||||
|
||||
|
||||
|
||||
def xsendfile(e, sr):
|
||||
sr('200 OK', [('Content-Type', 'image/png'), ('X-Sendfile', os.path.abspath('logo_uWSGI.png'))])
|
||||
@@ -25,13 +43,48 @@ 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)
|
||||
|
||||
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()
|
||||
|
||||
if routes.has_key(env['PATH_INFO']):
|
||||
return routes[env['PATH_INFO']](env, start_response)
|
||||
|
||||
start_response('200 OK', [('Content-Type', 'text/html')])
|
||||
|
||||
if DEBUG:
|
||||
print env['wsgi.input'].fileno()
|
||||
|
||||
gc.collect(2)
|
||||
|
||||
if DEBUG:
|
||||
print len(gc.get_objects())
|
||||
|
||||
workers = ''
|
||||
for w in uwsgi.workers():
|
||||
apps = '<table border="1"><tr><th>id</th><th>mountpoint</th><th>requests</th></tr>'
|
||||
for app in w['apps']:
|
||||
apps += '<tr><td>%d</td><td>%s</td><td>%d</td></tr>' % (app['id'], app['mountpoint'], app['requests'])
|
||||
apps += '</table>'
|
||||
workers += """
|
||||
<tr>
|
||||
<td>%d</td><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td><td>%s</td>
|
||||
</tr>
|
||||
""" % (w['id'], w['pid'], w['status'], w['running_time']/1000, w['avg_rt']/1000, w['tx'], apps)
|
||||
|
||||
return """
|
||||
<img src="/logo"/> version %s<br/>
|
||||
<hr size="1"/>
|
||||
@@ -44,7 +97,16 @@ Configuration<br/>
|
||||
Dynamic options<br/>
|
||||
<iframe src="/options"></iframe><br/>
|
||||
|
||||
""" % (uwsgi.version)
|
||||
<br/>
|
||||
Workers and applications<br/>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th>wid</th><th>pid</th><th>status</th><th>running time</th><th>average</th><th>tx</th><th>apps</th>
|
||||
</tr>
|
||||
%s
|
||||
</table>
|
||||
|
||||
""" % (uwsgi.version, workers)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, int app_tag
|
||||
char *xml_content;
|
||||
int xml_size = 0;
|
||||
|
||||
if (!uwsgi_startswith(filename, "http://", 7) || !uwsgi_startswith(filename, "data://", 7) || !uwsgi_startswith(filename, "sym://", 6)) {
|
||||
if (uwsgi_check_scheme(filename)) {
|
||||
colon = uwsgi_get_last_char(filename, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
if (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6)) {
|
||||
if (uwsgi_check_scheme(file)) {
|
||||
colon = uwsgi_get_last_char(file, '/');
|
||||
colon = uwsgi_get_last_char(colon, ':');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user