Compare commits

...
59 Commits
Author SHA1 Message Date
roberto@dexter 920d5d7416 Changelog for 0.9.9 2011-08-29 11:32:27 +02:00
roberto@dexter dcb654d7fb spooler reload fix 2011-08-29 10:50:09 +02:00
roberto@solarisexpress a563da1223 solaris fix for lockf() 2011-08-29 10:34:46 +00:00
roberto@sirius 1e26cda615 fixed a race condition 2011-08-29 10:30:01 +02:00
roberto@dexter 97133b27ce the decoratortest is fully working, ready for release 2011-08-29 09:54:07 +02:00
roberto@sirius b428bd3b87 another bunch of build fixes 2011-08-29 08:02:37 +02:00
roberto@dexter 05136e74b4 fixed build system 2011-08-29 07:55:46 +02:00
roberto@mrspurr 9f28a8bdf1 improved upload progress 2011-08-28 20:53:46 +02:00
roberta@mrspurr d9361f1fee added test for upload progress 2011-08-28 19:13:56 +02:00
roberto@debian32 835230b1a4 emperor-tyrant 2011-08-28 09:15:13 +02:00
roberto@debian32 f88f51c553 added welcome.ini 2011-08-28 08:33:49 +02:00
roberto@debian32 1996305eb1 allows multiple --ini options 2011-08-28 07:55:54 +02:00
roberto@solrisexpress c7ad50e950 do not free getexecname() ret value 2011-08-28 07:37:21 +00:00
roberto@debian32 0ec0c29d67 fixed an indentation 2011-08-28 07:21:49 +02:00
roberto@solarisexpress 75af117e8a better magic plugin loading on binary_path 2011-08-28 07:14:42 +00:00
roberto@debian32 2b04cefe4e added help for a bunch of options 2011-08-27 19:37:34 +02:00
roberto@debian32 0e41c4111a fixed upstart 2011-08-27 18:46:53 +02:00
roberto@debian32 5f5d382c64 signal framework ported to gevent 2011-08-27 07:15:44 +02:00
roberto@dexter 3e867fe401 resolve domain names in socket logging 2011-08-26 16:20:14 +02:00
roberto@dexter 153142b8b0 fixed django uwsgi_admin without spooler 2011-08-26 15:02:02 +02:00
roberto@dexter 5562c0c047 use hub.join() instead of hub.switch() 2011-08-26 14:05:03 +02:00
roberto@debian32 f4a1f800ba timeout handling in gevent plugin 2011-08-26 12:34:12 +02:00
roberto@debian32 bdbc5e5605 another gevent improvement suggested by denis 2011-08-26 11:35:32 +02:00
roberto@debian32 4104f825ff another improvement for sys.executable in python3 2011-08-26 10:28:34 +02:00
roberto@longshot efa01ea404 better sys.executable and sys.argv values 2011-08-26 10:08:01 +02:00
roberto@debian32 982559ae66 snmp fixes 2011-08-26 09:54:11 +02:00
roberto@gambit 60002e8de8 Added tag 0.9.9-rc2 for changeset 6aa667612019 2011-08-26 08:17:20 +02:00
roberto@debian32 25d671e0f6 fixed python snmp api 2011-08-26 08:13:14 +02:00
roberto@debian32 5a58281a3f various gevent fixes 2011-08-26 07:37:26 +02:00
roberto@debian32 c422231806 ops another grunt fix 2011-08-25 18:16:58 +02:00
roberto@debian32 4979883fe5 fixed a grunt bug 2011-08-25 17:51:04 +02:00
roberto@debian32 8158a624d3 check for loop engine 2011-08-25 14:34:18 +02:00
roberto@debian32 06403b5fce fixed stupid bug in setup.py 2011-08-25 14:15:55 +02:00
roberto@debian32 bc482652fc updated setup.py 2011-08-25 14:13:13 +02:00
roberto@debian32 58aa5755e0 fixed a typo 2011-08-25 14:04:57 +02:00
roberto@debian32 bca835c58a added UWSGI_PROFILE unix env 2011-08-25 14:03:43 +02:00
roberto@debian32 4b0f68a57a check gevent version 2011-08-25 13:53:38 +02:00
roberto@debian32 b693d73ebe gevent dedicated plugin 2011-08-25 13:46:42 +02:00
roberto@dexter dfab80447b added a check for Riccardo 2011-08-24 18:24:45 +02:00
roberto@dexter bbde0c866a a couple of fixes, and reintroduction of string-based multiapp 2011-08-24 17:48:27 +02:00
roberto@mrspurr 7b3514f757 --emperor-throttle 2011-08-24 13:03:25 +02:00
roberto@mrspurr 6d5fb3b252 export cache and queue functions only if available 2011-08-20 11:12:32 +02:00
roberto@debian32 87e8f118d3 fix refcnt in async-disabled compilation 2011-08-19 16:35:16 +02:00
roberto@debian32 3ae78cc0a8 another bufsize fix 2011-08-19 16:28:44 +02:00
roberto@debian32 7ef921356f updated sharedarea 2011-08-19 15:22:20 +02:00
roberto@debian32 378185d997 added a build profile for uwsgi_pypy integration 2011-08-19 12:24:38 +02:00
roberto@debian32 c4b15a8509 changed final banner in library mode 2011-08-19 12:15:18 +02:00
roberto@debian32 96ef9d155b uwsgi.magic_table 2011-08-19 11:44:40 +02:00
roberto@debian32 d5e6412b20 uWSGI 0.9.9-rc1 2011-08-19 09:57:58 +02:00
roberto@debian32 eebe757c16 Added tag 0.9.9-rc1 for changeset fb168b0b8616 2011-08-19 08:51:26 +02:00
roberto@debian32 43a21d32cb fixed a stupid bug 2011-08-19 08:49:39 +02:00
roberto@debian32 9f9eb5ef17 improved apache2 SCRIPT_NAME/PATH_INFo handling 2011-08-19 08:48:15 +02:00
roberto@debian32 0116c62980 another refcnt fix 2011-08-19 07:06:29 +02:00
roberto@debian32 fae446e495 fix for 3.0-arch 2011-08-19 06:46:07 +02:00
roberto@debian32 6f7054df18 more tolerant cache and queue size 2011-08-18 14:27:21 +02:00
roberto@debian32 0f31c21f4a completed queue subsystem with test 2011-08-18 09:46:32 +02:00
roberto@debian32 bd3e234703 another xml app tag fix 2011-08-18 07:06:27 +02:00
roberto@gambit 71bfd63623 fixed xml app tag 2011-08-18 07:01:13 +02:00
unbit@localhost 98b89dc83c Added tag 0.9.9-beta1 for changeset 6945ee03c7ea 2011-08-18 06:33:20 +02:00
53 changed files with 1618 additions and 414 deletions
+3
View File
@@ -28,3 +28,6 @@ e91bc724325e14c13b8f548c0b6a315c48a1c32a 0.9.8-rc2
fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
7169ef1d68d3dab4737bcc3f9e082839e5a06cc1 0.9.8.2
f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
6945ee03c7ea95eb19217ef1e1fb17d9ae26adbc 0.9.9-beta1
fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
6aa667612019fcff8e68af9469f73aff6fa378a8 0.9.9-rc2
+34
View File
@@ -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]
+12 -23
View File
@@ -161,6 +161,7 @@ static void *uwsgi_server_config(apr_pool_t *p, server_rec *s) {
c->modifier2 = 0 ;
c->cgi_mode = 0 ;
c->max_vars = 128;
c->script_name[0] = 0;
return c;
}
@@ -176,6 +177,12 @@ static void *uwsgi_dir_config(apr_pool_t *p, char *dir) {
c->modifier2 = 0 ;
c->cgi_mode = 0 ;
c->max_vars = 128;
c->script_name[0] = 0;
if (dir) {
if (strcmp(dir, "/")) {
strncpy(c->script_name, dir, 255);
}
}
return c;
}
@@ -347,31 +354,13 @@ static int uwsgi_handler(request_rec *r) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "UWSGI_SCHEME", c->scheme, &pkt_size) ;
}
if (c->script_name[0] == '/') {
if (c->script_name[1] == 0) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", "", &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri, &pkt_size) ;
}
else {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", c->script_name, &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri+strlen(c->script_name), &pkt_size) ;
}
if (c->script_name[0] != 0) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", c->script_name, &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri+strlen(c->script_name), &pkt_size) ;
}
else {
if (r->path_info) {
if (strlen(r->path_info) <= 0) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", "", &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri, &pkt_size) ;
}
else {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", apr_pstrndup(r->pool, r->uri, (strlen(r->uri) - strlen(r->path_info) )) , &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->path_info, &pkt_size) ;
}
}
else {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", "", &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri, &pkt_size) ;
}
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SCRIPT_NAME", "", &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "PATH_INFO", r->uri, &pkt_size) ;
}
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = python, ping, cache, nagios, rpc, fastrouter, http, gevent
+1 -1
View File
@@ -1,5 +1,5 @@
[uwsgi]
inherit = default
bin_name = libuwsgi.so
embedded_plugins = symcall
embedded_plugins = null
as_shared_library = true
+5
View File
@@ -0,0 +1,5 @@
[uwsgi]
inherit = default
bin_name = libuwsgi.so
embedded_plugins = symcall
as_shared_library = true
+1 -1
View File
@@ -8,7 +8,7 @@ void uwsgi_init_cache() {
if (!uwsgi.cache_blocksize)
uwsgi.cache_blocksize = UMAX16;
if (uwsgi.cache_blocksize % uwsgi.page_size != 0) {
if ((uwsgi.cache_blocksize * uwsgi.cache_max_items) % uwsgi.page_size != 0) {
uwsgi_log("invalid cache blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) uwsgi.cache_blocksize, uwsgi.page_size);
exit(1);
}
+3 -1
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
[uwsgi]
show-config = true
+21 -10
View File
@@ -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')
+4 -3
View File
@@ -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),
+54 -8
View File
@@ -32,6 +32,9 @@ struct uwsgi_instance {
int loyal;
int zerg;
uid_t uid;
gid_t gid;
};
@@ -169,7 +172,7 @@ 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;
@@ -181,7 +184,14 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
char *colon = NULL;
int i;
sleep(1);
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 +219,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 +265,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");
@@ -517,7 +547,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,7 +584,7 @@ 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);
@@ -583,7 +613,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 +650,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 +697,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 +775,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;
+8
View File
@@ -687,13 +687,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
+1
View File
@@ -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) {
+37 -2
View File
@@ -318,6 +318,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]);
@@ -476,7 +485,7 @@ void master_loop(char **argv, char **environ) {
}
if (uwsgi.queue_store && uwsgi.queue_filesize) {
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
if (msync(uwsgi.queue_header, uwsgi.queue_filesize, MS_ASYNC)) {
uwsgi_error("msync()");
}
}
@@ -1016,6 +1025,30 @@ 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);
@@ -1194,7 +1227,7 @@ void master_loop(char **argv, char **environ) {
}
if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((uwsgi.master_cycles % uwsgi.queue_store_sync) == 0)) {
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
if (msync(uwsgi.queue_header, uwsgi.queue_filesize, MS_ASYNC)) {
uwsgi_error("msync()");
}
}
@@ -1230,7 +1263,9 @@ 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;
}
}
+356
View File
@@ -0,0 +1,356 @@
#include "../python/uwsgi_python.h"
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
struct option gevent_options[] = {
{ 0, 0, 0, 0 }
};
#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 *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) {
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);
}
}
Py_INCREF(Py_None);
return Py_None;
}
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();
if (wsgi_req == NULL) {
uwsgi_log("async queue is full !!!\n");
goto clear;
}
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);
clear:
Py_INCREF(Py_None);
return Py_None;
}
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 ;
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;
// we can safely decref here as watcher and timer has got a +1 for start() method
Py_DECREF(ret);
if (ret == timer) {
uwsgi_log( "timeout. skip request.\n");
goto clear_and_stop;
}
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(;;) {
uwsgi.wsgi_req = wsgi_req;
wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req);
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);
uwsgi.wsgi_req = wsgi_req;
free_req_queue;
Py_INCREF(Py_None);
return Py_None;
}
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() {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
if (uwsgi.async < 2) {
uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n");
exit(1);
}
PyObject *gevent_dict = get_uwsgi_pydict("gevent");
if (!gevent_dict) uwsgi_pyexit;
PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
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");
exit(1);
}
ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
if (!ugevent.spawn) uwsgi_pyexit;
ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
if (!ugevent.greenlet_switch) uwsgi_pyexit;
ugevent.greenlet_switch_args = PyTuple_New(0);
Py_INCREF(ugevent.greenlet_switch_args);
PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");
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) uwsgi_pyexit;
ugevent.get_current_args = PyTuple_New(0);
Py_INCREF(ugevent.get_current_args);
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) uwsgi_pyexit;
// main greenlet waiting for connection
PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
Py_INCREF(uwsgi_gevent_main);
// 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_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 *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
if (!my_signal_watcher) uwsgi_pyexit;
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();
}
uwsgi_log("the gevent Hub is no more :(\n");
}
int gevent_init() {
uwsgi_register_loop( (char *) "gevent", gevent_loop);
return 0;
}
struct uwsgi_plugin gevent_plugin = {
.name = "gevent",
.init = gevent_init,
.options = gevent_options,
};
+8
View File
@@ -0,0 +1,8 @@
from distutils import sysconfig
NAME='gevent'
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
LDFLAGS = []
LIBS = []
GCC_LIST = ['gevent']
+24 -2
View File
@@ -170,8 +170,16 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
wi->mountpoint_len = strlen(wi->mountpoint);
wsgi_req->appid = wi->mountpoint;
wsgi_req->appid_len = wi->mountpoint_len;
#ifdef UWSGI_DEBUG
uwsgi_log("main mountpoint = %s\n", wi->mountpoint);
#endif
wi->callable = PyDict_GetItem(applications, app_mnt);
if (PyString_Check((PyObject *) wi->callable)) {
PyObject *callables_dict = get_uwsgi_pydict((char *)arg1);
if (callables_dict) {
wi->callable = PyDict_GetItem(callables_dict, (PyObject *)wi->callable);
}
}
}
Py_INCREF((PyObject *)wi->callable);
@@ -248,6 +256,8 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
}
#else
// add start_response on WSGI app
Py_INCREF((PyObject *)up.wsgi_spitout);
wi->wsgi_args = PyTuple_New(wi->argc);
if (app_type == PYTHON_APP_TYPE_WSGI) {
if (PyTuple_SetItem(wi->wsgi_args, 1, up.wsgi_spitout)) {
@@ -308,7 +318,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
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) {
if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
uwsgi_rawlog(" (default app)");
uwsgi.default_app = id;
}
@@ -327,7 +337,19 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
wsgi_req->appid = PyString_AsString(app_mnt);
wsgi_req->appid_len = strlen(wsgi_req->appid);
init_uwsgi_app(LOADER_CALLABLE, PyDict_GetItem(applications, app_mnt), wsgi_req, wi->interpreter, app_type);
PyObject *a_callable = PyDict_GetItem(applications, app_mnt);
if (PyString_Check(a_callable)) {
PyObject *callables_dict = get_uwsgi_pydict((char *)arg1);
if (callables_dict) {
a_callable = PyDict_GetItem(callables_dict, a_callable);
}
}
if (!a_callable) {
uwsgi_log("skipping broken app %s\n", wsgi_req->appid);
continue;
}
init_uwsgi_app(LOADER_CALLABLE, a_callable, wsgi_req, wi->interpreter, app_type);
}
}
+38 -8
View File
@@ -71,6 +71,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},
@@ -456,6 +457,8 @@ void init_uwsgi_embedded_module() {
exit(1);
}
Py_INCREF((PyObject *) &uwsgi_InputType);
up.embedded_dict = PyModule_GetDict(new_uwsgi_module);
if (!up.embedded_dict) {
uwsgi_log("could not get uwsgi module __dict__\n");
@@ -576,6 +579,23 @@ void init_uwsgi_embedded_module() {
exit(1);
}
PyObject *py_magic_table = PyDict_New();
uint8_t mtk;
for (i = 0; i <= 0xff; i++) {
// a bit of magic :P
mtk = i;
if (uwsgi.magic_table[i]) {
if (uwsgi.magic_table[i][0] != 0) {
PyDict_SetItem(py_magic_table, PyString_FromStringAndSize((char *) &mtk, 1), PyString_FromString(uwsgi.magic_table[i]));
}
}
}
if (PyDict_SetItemString(up.embedded_dict, "magic_table", py_magic_table)) {
PyErr_Print();
exit(1);
}
#ifdef UNBIT
if (PyDict_SetItemString(up.embedded_dict, "unbit", Py_True)) {
#else
@@ -654,9 +674,19 @@ void init_uwsgi_embedded_module() {
init_uwsgi_module_sharedarea(new_uwsgi_module);
}
init_uwsgi_module_cache(new_uwsgi_module);
if (uwsgi.cache_max_items > 0) {
init_uwsgi_module_cache(new_uwsgi_module);
}
init_uwsgi_module_queue(new_uwsgi_module);
if (uwsgi.queue_size > 0) {
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();
@@ -763,12 +793,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
@@ -825,7 +855,7 @@ char *uwsgi_pythonize(char *orig) {
name[i] = '_';
}
else if (name[i] == '/') {
name[i] = '.';
name[i] = '_';
}
}
@@ -842,7 +872,6 @@ void uwsgi_python_spooler_init(void) {
struct uwsgi_string_list *upli = up.spooler_import_list;
UWSGI_GET_GIL
while(upli) {
@@ -1184,6 +1213,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;
}
+14 -2
View File
@@ -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) {
@@ -106,5 +107,16 @@ void init_pyargv() {
PySys_SetArgv(up.argc, up.py_argv);
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
}
+9 -4
View File
@@ -351,13 +351,15 @@ clear:
}
static PyMethodDef symimporter_methods[] = {
{"find_module", symimporter_find_module, METH_VARARGS},
{"load_module", symimporter_load_module, METH_VARARGS},
{"find_module", symimporter_find_module, METH_VARARGS},
{"load_module", symimporter_load_module, METH_VARARGS},
{ NULL, NULL },
};
static PyMethodDef symzipimporter_methods[] = {
{"find_module", symzipimporter_find_module, METH_VARARGS},
{"load_module", symzipimporter_load_module, METH_VARARGS},
{"find_module", symzipimporter_find_module, METH_VARARGS},
{"load_module", symzipimporter_load_module, METH_VARARGS},
{ NULL, NULL },
};
static void uwsgi_symimporter_free(struct _symimporter *self) {
@@ -717,6 +719,7 @@ int uwsgi_init_symbol_import() {
exit(1);
}
Py_INCREF((PyObject *)&SymImporter_Type);
if (PyModule_AddObject(uwsgi_em, "SymbolsImporter",
(PyObject *)&SymImporter_Type) < 0) {
PyErr_Print();
@@ -724,6 +727,7 @@ int uwsgi_init_symbol_import() {
exit(1);
}
Py_INCREF((PyObject *)&ZipImporter_Type);
if (PyModule_AddObject(uwsgi_em, "ZipImporter",
(PyObject *)&ZipImporter_Type) < 0) {
PyErr_Print();
@@ -731,6 +735,7 @@ int uwsgi_init_symbol_import() {
exit(1);
}
Py_INCREF((PyObject *)&SymZipImporter_Type);
if (PyModule_AddObject(uwsgi_em, "SymbolsZipImporter",
(PyObject *)&SymZipImporter_Type) < 0) {
PyErr_Print();
+316 -47
View File
@@ -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
@@ -838,17 +845,29 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
return NULL;
}
if (PyString_Check(what)) {
filename = PyString_AsString(what);
fd = open(filename, O_RDONLY);
if (fd < 0) {
uwsgi_error("open");
uwsgi_error_open(filename);
goto clear;
}
}
#ifdef PYTHREE
else if (PyUnicode_Check(what)) {
filename = PyBytes_AsString(PyUnicode_AsASCIIString(what));
fd = open(filename, O_RDONLY);
if (fd < 0) {
uwsgi_error_open(filename);
goto clear;
}
}
#endif
else {
fd = PyObject_AsFileDescriptor(what);
if (fd < 0)
@@ -949,6 +968,18 @@ 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) {
// the spooler cannot lock resources
@@ -1007,81 +1038,102 @@ PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_sharedarea_inclong(PyObject * self, PyObject * args) {
int pos = 0;
long value = 0;
uint64_t pos = 0;
uint64_t value = 1;
uint64_t current_value = 0;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "ii:sharedarea_inclong", &pos, &value)) {
if (!PyArg_ParseTuple(args, "l|l:sharedarea_inclong", &pos, &value)) {
return NULL;
}
if (pos + 4 >= uwsgi.page_size * uwsgi.sharedareasize) {
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
memcpy(&value, uwsgi.sharedarea + pos, 4);
value++;
memcpy(uwsgi.sharedarea + pos, &value, 4);
uwsgi_wlock(uwsgi.sa_lock);
return PyInt_FromLong(value);
memcpy(&current_value, uwsgi.sharedarea + pos, 8);
value = current_value + value;
memcpy(uwsgi.sharedarea + pos, &value, 8);
PyObject *ret = PyInt_FromLong(value);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
PyObject *py_uwsgi_sharedarea_writelong(PyObject * self, PyObject * args) {
int pos = 0;
long value;
uint64_t pos = 0;
uint64_t value = 0;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "ii:sharedarea_writelong", &pos, &value)) {
if (!PyArg_ParseTuple(args, "ll:sharedarea_writelong", &pos, &value)) {
return NULL;
}
if (pos + 4 >= uwsgi.page_size * uwsgi.sharedareasize) {
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
memcpy(uwsgi.sharedarea + pos, &value, 4);
uwsgi_wlock(uwsgi.sa_lock);
return PyInt_FromLong(value);
memcpy(uwsgi.sharedarea + pos, &value, 8);
PyObject *ret = PyInt_FromLong(value);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
PyObject *py_uwsgi_sharedarea_write(PyObject * self, PyObject * args) {
int pos = 0;
uint64_t pos = 0;
char *value;
Py_ssize_t value_len = 0;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "is:sharedarea_write", &pos, &value)) {
if (!PyArg_ParseTuple(args, "ls#:sharedarea_write", &pos, &value, &value_len)) {
return NULL;
}
if (pos + (int) strlen(value) >= uwsgi.page_size * uwsgi.sharedareasize) {
if (pos + value_len >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
memcpy(uwsgi.sharedarea + pos, value, strlen(value));
uwsgi_wlock(uwsgi.sa_lock);
return PyInt_FromLong(strlen(value));
memcpy(uwsgi.sharedarea + pos, value, value_len);
PyObject *ret = PyInt_FromLong(value_len);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
PyObject *py_uwsgi_sharedarea_writebyte(PyObject * self, PyObject * args) {
int pos = 0;
uint64_t pos = 0;
char value;
if (uwsgi.sharedareasize <= 0) {
@@ -1090,7 +1142,7 @@ PyObject *py_uwsgi_sharedarea_writebyte(PyObject * self, PyObject * args) {
}
if (!PyArg_ParseTuple(args, "ib:sharedarea_writebyte", &pos, &value)) {
if (!PyArg_ParseTuple(args, "lb:sharedarea_writebyte", &pos, &value)) {
return NULL;
}
@@ -1099,46 +1151,58 @@ PyObject *py_uwsgi_sharedarea_writebyte(PyObject * self, PyObject * args) {
return Py_None;
}
uwsgi_wlock(uwsgi.sa_lock);
uwsgi.sharedarea[pos] = value;
return PyInt_FromLong(uwsgi.sharedarea[pos]);
PyObject *ret = PyInt_FromLong(uwsgi.sharedarea[pos]);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
PyObject *py_uwsgi_sharedarea_readlong(PyObject * self, PyObject * args) {
int pos = 0;
long value;
uint64_t pos = 0;
uint64_t value;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "i:sharedarea_readlong", &pos)) {
if (!PyArg_ParseTuple(args, "l:sharedarea_readlong", &pos)) {
return NULL;
}
if (pos + 4 >= uwsgi.page_size * uwsgi.sharedareasize) {
if (pos + 8 >= uwsgi.page_size * uwsgi.sharedareasize) {
Py_INCREF(Py_None);
return Py_None;
}
memcpy(&value, uwsgi.sharedarea + pos, 4);
uwsgi_wlock(uwsgi.sa_lock);
return PyInt_FromLong(value);
memcpy(&value, uwsgi.sharedarea + pos, 8);
PyObject *ret = PyLong_FromLong(value);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
PyObject *py_uwsgi_sharedarea_readbyte(PyObject * self, PyObject * args) {
int pos = 0;
uint64_t pos = 0;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "i:sharedarea_readbyte", &pos)) {
if (!PyArg_ParseTuple(args, "l:sharedarea_readbyte", &pos)) {
return NULL;
}
@@ -1147,20 +1211,26 @@ PyObject *py_uwsgi_sharedarea_readbyte(PyObject * self, PyObject * args) {
return Py_None;
}
return PyInt_FromLong(uwsgi.sharedarea[pos]);
uwsgi_wlock(uwsgi.sa_lock);
PyObject *ret = PyInt_FromLong(uwsgi.sharedarea[pos]);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) {
int pos = 0;
int len = 1;
uint64_t pos = 0;
uint64_t len = 1;
if (uwsgi.sharedareasize <= 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!PyArg_ParseTuple(args, "i|i:sharedarea_read", &pos, &len)) {
if (!PyArg_ParseTuple(args, "l|l:sharedarea_read", &pos, &len)) {
return NULL;
}
@@ -1169,7 +1239,13 @@ PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) {
return Py_None;
}
return PyString_FromStringAndSize(uwsgi.sharedarea + pos, len);
uwsgi_wlock(uwsgi.sa_lock);
PyObject *ret = PyString_FromStringAndSize(uwsgi.sharedarea + pos, len);
uwsgi_rwunlock(uwsgi.sa_lock);
return ret;
}
#ifdef UWSGI_SPOOLER
@@ -2276,7 +2352,9 @@ PyObject *py_uwsgi_disconnect(PyObject * self, PyObject * args) {
uwsgi_log("disconnecting worker %d (pid :%d) from session...\n", uwsgi.mywid, uwsgi.mypid);
#endif
fclose(wsgi_req->async_post);
if (wsgi_req->socket) {
wsgi_req->socket->proto_close(wsgi_req);
}
wsgi_req->fd_closed = 1;
Py_INCREF(Py_True);
@@ -2433,7 +2511,9 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
// close connection on the worker
if (PyTuple_Size(args) == 0) {
fclose(wsgi_req->async_post);
if (wsgi_req->socket) {
wsgi_req->socket->proto_close(wsgi_req);
}
wsgi_req->fd_closed = 1;
}
@@ -2623,6 +2703,7 @@ 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, ""},
@@ -2808,25 +2889,58 @@ PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_queue_set(PyObject * self, PyObject * args) {
Py_ssize_t msglen = 0;
uint64_t pos = 0;
char *message ;
PyObject *res;
if (!PyArg_ParseTuple(args, "ls#:queue_set", &pos, &message, &msglen)) {
return NULL;
}
if (uwsgi.queue_size) {
uwsgi_wlock(uwsgi.queue_lock);
if (uwsgi_queue_set(pos, message, msglen)) {
Py_INCREF(Py_True);
res = Py_True;
}
else {
Py_INCREF(Py_None);
res = Py_None;
}
uwsgi_rwunlock(uwsgi.queue_lock);
return res;
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_queue_slot(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.shared->queue_pos);
return PyInt_FromLong(uwsgi.queue_header->pos);
}
PyObject *py_uwsgi_queue_pull_slot(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.queue_header->pull_pos);
}
PyObject *py_uwsgi_queue_pull(PyObject * self, PyObject * args) {
char *message;
uint64_t size;
PyObject *res;
if (!PyArg_ParseTuple(args, ":queue_pull")) {
return NULL;
}
if (uwsgi.queue_size) {
uwsgi_wlock(uwsgi.queue_lock);
message = uwsgi_queue_pull(&size);
if (message) {
if (message && size > 0) {
res = PyString_FromStringAndSize(message, size);
}
else {
@@ -2842,6 +2956,32 @@ PyObject *py_uwsgi_queue_pull(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_queue_pop(PyObject * self, PyObject * args) {
char *message;
uint64_t size;
PyObject *res;
if (uwsgi.queue_size) {
uwsgi_wlock(uwsgi.queue_lock);
message = uwsgi_queue_pop(&size);
if (message && size > 0) {
res = PyString_FromStringAndSize(message, size);
}
else {
Py_INCREF(Py_None);
res = Py_None;
}
uwsgi_rwunlock(uwsgi.queue_lock);
return res;
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
long index = 0;
@@ -2856,7 +2996,7 @@ PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
if (uwsgi.queue_size) {
uwsgi_rlock(uwsgi.queue_lock);
message = uwsgi_queue_get(index, &size);
if (message) {
if (message && size > 0) {
res = PyString_FromStringAndSize(message, size);
}
else {
@@ -2886,8 +3026,8 @@ PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
if (uwsgi.queue_size) {
res = PyList_New(0);
uwsgi_rlock(uwsgi.queue_lock);
if (uwsgi.shared->queue_pos > 0) {
base = uwsgi.shared->queue_pos-1;
if (uwsgi.queue_header->pos > 0) {
base = uwsgi.queue_header->pos-1;
}
else {
base = uwsgi.queue_size-1;
@@ -2988,10 +3128,13 @@ static PyMethodDef uwsgi_cache_methods[] = {
static PyMethodDef uwsgi_queue_methods[] = {
{"queue_get", py_uwsgi_queue_get, METH_VARARGS, ""},
{"queue_set", py_uwsgi_queue_set, METH_VARARGS, ""},
{"queue_last", py_uwsgi_queue_last, METH_VARARGS, ""},
{"queue_push", py_uwsgi_queue_push, METH_VARARGS, ""},
{"queue_pull", py_uwsgi_queue_pull, METH_VARARGS, ""},
{"queue_pop", py_uwsgi_queue_pop, METH_VARARGS, ""},
{"queue_slot", py_uwsgi_queue_slot, METH_VARARGS, ""},
{"queue_pull_slot", py_uwsgi_queue_pull_slot, METH_VARARGS, ""},
{NULL, NULL},
};
@@ -3072,6 +3215,8 @@ void init_uwsgi_module_queue(PyObject * current_uwsgi_module) {
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
Py_DECREF(func);
}
PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyInt_FromLong(uwsgi.queue_size));
}
@@ -3092,4 +3237,128 @@ void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
}
}
#ifdef UWSGI_SNMP
PyObject *py_snmp_counter32(PyObject * self, PyObject * args) {
uint8_t oid_num;
uint32_t oid_val = 0;
if (!PyArg_ParseTuple(args, "bI:snmp_set_counter32", &oid_num, &oid_val)) {
return NULL;
}
if (oid_num > 100 || oid_num < 1)
goto clear;
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
Py_INCREF(Py_True);
return Py_True;
clear:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_snmp_counter64(PyObject * self, PyObject * args) {
uint8_t oid_num;
uint64_t oid_val = 0;
if (!PyArg_ParseTuple(args, "bK:snmp_set_counter64", &oid_num, &oid_val)) {
return NULL;
}
if (oid_num > 100 || oid_num < 1)
goto clear;
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
Py_INCREF(Py_True);
return Py_True;
clear:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_snmp_gauge(PyObject * self, PyObject * args) {
uint8_t oid_num;
uint32_t oid_val = 0;
if (!PyArg_ParseTuple(args, "bI:snmp_set_gauge", &oid_num, &oid_val)) {
return NULL;
}
if (oid_num > 100 || oid_num < 1)
goto clear;
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
Py_INCREF(Py_True);
return Py_True;
clear:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_snmp_community(PyObject * self, PyObject * args) {
char *snmp_community;
if (!PyArg_ParseTuple(args, "s:snmp_set_community", &snmp_community)) {
return NULL;
}
if (strlen(snmp_community) > 72) {
uwsgi_log( "*** warning the supplied SNMP community string will be truncated to 72 chars ***\n");
memcpy(uwsgi.shared->snmp_community, snmp_community, 72);
}
else {
memcpy(uwsgi.shared->snmp_community, snmp_community, strlen(snmp_community) + 1);
}
Py_INCREF(Py_True);
return Py_True;
}
static PyMethodDef uwsgi_snmp_methods[] = {
{"snmp_set_counter32", py_snmp_counter32, METH_VARARGS, ""},
{"snmp_set_counter64", py_snmp_counter64, METH_VARARGS, ""},
{"snmp_set_gauge", py_snmp_gauge, METH_VARARGS, ""},
{"snmp_set_community", py_snmp_community, METH_VARARGS, ""},
{NULL, NULL},
};
void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) {
PyMethodDef *uwsgi_function;
PyObject *uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
if (!uwsgi_module_dict) {
uwsgi_log("could not get uwsgi module __dict__\n");
exit(1);
}
for (uwsgi_function = uwsgi_snmp_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
Py_DECREF(func);
}
uwsgi_log( "SNMP python functions initialized.\n");
}
#endif
#endif
+3
View File
@@ -249,6 +249,7 @@ void init_uwsgi_module_spooler(PyObject *);
void init_uwsgi_module_sharedarea(PyObject *);
void init_uwsgi_module_cache(PyObject *);
void init_uwsgi_module_queue(PyObject *);
void init_uwsgi_module_snmp(PyObject *);
PyObject *uwsgi_pyimport_by_filename(char *, char *);
@@ -263,6 +264,8 @@ void uwsgi_python_reset_random_seed(void);
char *uwsgi_pythonize(char *);
#define uwsgi_pyexit {PyErr_Print();exit(1);}
#ifdef __linux__
#ifndef PYTHREE
int uwsgi_init_symbol_import(void);
+3 -2
View File
@@ -27,7 +27,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
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");
@@ -125,7 +124,9 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);
if (uwsgi.cores > 1) {
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id));
zero = PyInt_FromLong(wsgi_req->async_id);
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", zero);
Py_DECREF(zero);
}
// cache this ?
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python24'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python2.4-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python25'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python2.5-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python26'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python2.6-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python27'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python2.7-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python30'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python3.0-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python31'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python3.1-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+1 -1
View File
@@ -2,7 +2,7 @@ import os,sys
NAME='python32'
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler'])
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
CFLAGS = os.popen('python3.2-config --cflags').read().rstrip().split()
CFLAGS.append('-Wno-unused-parameter')
+4 -3
View File
@@ -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;
}
@@ -717,7 +717,7 @@ next:
}
// on tiny post use memory
else {
if (!uwsgi_read_whole_body_in_mem(wsgi_req, uwsgi.mem_post_buf[wsgi_req->async_id], uwsgi.post_buffering)) {
if (!uwsgi_read_whole_body_in_mem(wsgi_req, wsgi_req->post_buffering_buf)) {
wsgi_req->status = -1;
return -1;
}
@@ -766,8 +766,9 @@ next:
wsgi_req->var_cnt++;
script_name = 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);
//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) {
if (!uwsgi_startswith(orig_path_info, uwsgi_apps[i].mountpoint, uwsgi_apps[i].mountpoint_len) && uwsgi_apps[i].mountpoint_len > best_found) {
best_found = uwsgi_apps[i].mountpoint_len;
+53 -33
View File
@@ -6,17 +6,15 @@ void uwsgi_init_queue() {
if (!uwsgi.queue_blocksize)
uwsgi.queue_blocksize = 8192;
if (uwsgi.queue_blocksize % uwsgi.page_size != 0) {
uwsgi_log("invalid queue blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) uwsgi.queue_blocksize, uwsgi.page_size);
if ((uwsgi.queue_blocksize * uwsgi.queue_size) % uwsgi.page_size != 0) {
uwsgi_log("invalid queue size/blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) uwsgi.queue_blocksize, uwsgi.page_size);
exit(1);
}
uwsgi.shared->queue_pos = 0;
uwsgi.shared->queue_pull_pos = 0;
if (uwsgi.queue_store) {
uwsgi.queue_filesize = uwsgi.queue_blocksize * uwsgi.queue_size;
uwsgi.queue_filesize = uwsgi.queue_blocksize * uwsgi.queue_size + 16;
int queue_fd;
struct stat qst;
@@ -45,16 +43,26 @@ void uwsgi_init_queue() {
exit(1);
}
uwsgi.queue = mmap(NULL, uwsgi.queue_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, queue_fd, 0);
uwsgi_queue_fix();
// fix header
uwsgi.queue_header = uwsgi.queue;
uwsgi.queue+=16;
}
else {
uwsgi.queue = mmap(NULL, uwsgi.queue_blocksize * uwsgi.queue_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
uwsgi.queue = mmap(NULL, (uwsgi.queue_blocksize * uwsgi.queue_size)+16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
// fix header
uwsgi.queue_header = uwsgi.queue;
uwsgi.queue+=16;
uwsgi.queue_header->pos = 0;
uwsgi.queue_header->pull_pos = 0;
}
if (!uwsgi.queue) {
uwsgi_error("mmap()");
exit(1);
}
uwsgi.queue_lock = uwsgi_mmap_shared_rwlock();
uwsgi_rwlock_init(uwsgi.queue_lock);
@@ -78,33 +86,20 @@ char *uwsgi_queue_get(uint64_t index, uint64_t *size) {
}
void uwsgi_queue_fix() {
uint64_t i;
char *value;
uint64_t size;
for(i=0;i< uwsgi.queue_size;i++) {
// valid record ?
value = uwsgi_queue_get(i, &size);
if (value && size) {
uwsgi.shared->queue_pos++;
}
else {
return;
}
}
}
char *uwsgi_queue_pop(uint64_t *size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
if (uwsgi.shared->queue_pos > 0) uwsgi.shared->queue_pos--;
if (uwsgi.queue_header->pos == 0) {
uwsgi.queue_header->pos = uwsgi.queue_size-1;
}
else {
uwsgi.queue_header->pos--;
}
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.shared->queue_pos);
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.queue_header->pos);
uqi = (struct uwsgi_queue_item *) ptr;
if (!uqi->size) return NULL;
@@ -122,16 +117,16 @@ char *uwsgi_queue_pull(uint64_t *size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.shared->queue_pull_pos);
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.queue_header->pull_pos);
uqi = (struct uwsgi_queue_item *) ptr;
if (!uqi->size) return NULL;
*size = uqi->size;
uwsgi.shared->queue_pull_pos++;
uwsgi.queue_header->pull_pos++;
if (uwsgi.shared->queue_pull_pos >= uwsgi.queue_size) uwsgi.shared->queue_pull_pos = 0;
if (uwsgi.queue_header->pull_pos >= uwsgi.queue_size) uwsgi.queue_header->pull_pos = 0;
// remove item
uqi->size = 0;
@@ -150,7 +145,7 @@ int uwsgi_queue_push(char *message, uint64_t size) {
if (!size) return 0;
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.shared->queue_pos);
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.queue_header->pos);
uqi = (struct uwsgi_queue_item *) ptr;
ptr += sizeof(struct uwsgi_queue_item);
@@ -159,9 +154,34 @@ int uwsgi_queue_push(char *message, uint64_t size) {
uqi->ts = time(NULL);
memcpy(ptr, message, size);
uwsgi.shared->queue_pos++;
uwsgi.queue_header->pos++;
if (uwsgi.shared->queue_pos >= uwsgi.queue_size) uwsgi.shared->queue_pos = 0;
if (uwsgi.queue_header->pos >= uwsgi.queue_size) uwsgi.queue_header->pos = 0;
return 1;
}
int uwsgi_queue_set(uint64_t pos, char *message, uint64_t size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
return 0;
if (!size) return 0;
if (pos >= uwsgi.queue_size) return 0;
ptr = ptr + (uwsgi.queue_blocksize*pos);
uqi = (struct uwsgi_queue_item *) ptr;
ptr += sizeof(struct uwsgi_queue_item);
uqi->size = size;
uqi->ts = time(NULL);
memcpy(ptr, message, size);
return 1;
}
+10 -2
View File
@@ -8,6 +8,14 @@ from setuptools.dist import Distribution
from setuptools.command.install import install
from setuptools.command.build_ext import build_ext
def get_profile():
profile = os.environ.get('UWSGI_PROFILE','buildconf/default.ini')
if not profile.endswith('.ini'):
profile = "%s.ini" % profile
if not '/' in profile:
profile = "buildconf/%s" % profile
return profile
def patch_bin_path(cmd, conf):
@@ -26,7 +34,7 @@ def patch_bin_path(cmd, conf):
class uWSGIBuilder(build_ext):
def run(self):
conf = uc.uConf('buildconf/default.ini')
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
@@ -38,7 +46,7 @@ class uWSGIInstall(install):
if self.record:
record_file = open(self.record,'w')
conf = uc.uConf('buildconf/default.ini')
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
+10
View File
@@ -0,0 +1,10 @@
/* this is a skeleton to use libuwsgi in external projects */
extern char **environ;
int uwsgi_init(int, char **, char **);
int main(int argc, char **argv, char **environ) {
uwsgi_init(argc, argv, environ);
}
-117
View File
@@ -350,123 +350,6 @@ static int get_snmp_integer(uint8_t * ptr, uint64_t * val) {
return size + oid_sz;
}
/*
PyObject *py_snmp_counter32(PyObject * self, PyObject * args) {
uint8_t oid_num;
uint32_t oid_val = 0;
if (!PyArg_ParseTuple(args, "bI:snmp_set_counter32", &oid_num, &oid_val)) {
return NULL;
}
if (oid_num > 100 || oid_num < 1)
goto clear;
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
Py_INCREF(Py_True);
return Py_True;
clear:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_snmp_counter64(PyObject * self, PyObject * args) {
uint8_t oid_num;
uint64_t oid_val = 0;
if (!PyArg_ParseTuple(args, "bK:snmp_set_counter64", &oid_num, &oid_val)) {
return NULL;
}
if (oid_num > 100 || oid_num < 1)
goto clear;
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
Py_INCREF(Py_True);
return Py_True;
clear:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_snmp_gauge(PyObject * self, PyObject * args) {
uint8_t oid_num;
uint32_t oid_val = 0;
if (!PyArg_ParseTuple(args, "bI:snmp_set_gauge", &oid_num, &oid_val)) {
return NULL;
}
if (oid_num > 100 || oid_num < 1)
goto clear;
uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
Py_INCREF(Py_True);
return Py_True;
clear:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_snmp_community(PyObject * self, PyObject * args) {
char *snmp_community;
if (!PyArg_ParseTuple(args, "s:snmp_set_community", &snmp_community)) {
return NULL;
}
if (strlen(snmp_community) > 72) {
uwsgi_log( "*** warning the supplied SNMP community string will be truncated to 72 chars ***\n");
memcpy(uwsgi.shared->snmp_community, snmp_community, 72);
}
else {
memcpy(uwsgi.shared->snmp_community, snmp_community, strlen(snmp_community) + 1);
}
Py_INCREF(Py_True);
return Py_True;
}
static PyMethodDef uwsgi_snmp_methods[] = {
{"snmp_set_counter32", py_snmp_counter32, METH_VARARGS, ""},
{"snmp_set_counter64", py_snmp_counter64, METH_VARARGS, ""},
{"snmp_set_gauge", py_snmp_gauge, METH_VARARGS, ""},
{"snmp_set_community", py_snmp_community, METH_VARARGS, ""},
{NULL, NULL},
};
void snmp_init() {
PyMethodDef *uwsgi_function;
for (uwsgi_function = uwsgi_snmp_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
PyDict_SetItemString(uwsgi.embedded_dict, uwsgi_function->ml_name, func);
Py_DECREF(func);
}
uwsgi_log( "SNMP python functions initialized.\n");
}
*/
#else
#warning "*** SNMP support is disabled ***"
#endif
+7 -1
View File
@@ -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);
+17 -3
View File
@@ -17,8 +17,10 @@ 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]);
if (uwsgi.shared->spooler_signal_pipe[0] != -1) {close (uwsgi.shared->spooler_signal_pipe[0]); uwsgi.shared->spooler_signal_pipe[0] = -1;}
if (!uwsgi.spooler_respawned) {
if (uwsgi.shared->spooler_signal_pipe[1] != -1) {close (uwsgi.shared->spooler_signal_pipe[1]); uwsgi.shared->spooler_signal_pipe[1] = -1;}
}
// setup internal signalling system
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.shared->spooler_signal_pipe)) {
uwsgi_error("socketpair()\n");
@@ -36,7 +38,9 @@ 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_close_all_sockets();
if (uwsgi.master_process) {
close(uwsgi.shared->spooler_signal_pipe[0]);
@@ -52,7 +56,9 @@ pid_t spooler_start() {
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,6 +70,7 @@ pid_t spooler_start() {
uwsgi.gp[i]->spooler_init();
}
}
spooler();
}
else if (pid > 0) {
@@ -251,6 +258,8 @@ void spooler() {
if (uwsgi.spooler_ordered) {
#ifdef __linux__
spooler_scandir(uwsgi.spool_dir);
#else
spooler_readdir(uwsgi.spool_dir);
#endif
}
else {
@@ -362,7 +371,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;
+48
View File
@@ -0,0 +1,48 @@
# uwsgi --queue 10 --queue-store test.queue --master --module tests.queue --socket :3031
import uwsgi
import os
from flask import Flask,render_template,request,redirect,flash
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)
@app.route('/')
def index():
return render_template('queue.html', uwsgi=uwsgi)
@app.route('/push', methods=['POST'])
def push_item():
if uwsgi.queue_push(request.form['body']):
flash('item enqueued')
return redirect('/')
else:
flash('unable to enqueue item')
return render_template('queue.html', uwsgi=uwsgi)
@app.route('/get', methods=['POST'])
def get_item():
flash( "slot %s value = %s" % (request.form['slot'], uwsgi.queue_get( int(request.form['slot']) )))
return redirect('/')
@app.route('/pop', methods=['POST'])
def pop_item():
flash( "popped value = %s" % uwsgi.queue_pop() )
return redirect('/')
@app.route('/pull', methods=['POST'])
def pull_item():
flash( "pulled value = %s" % uwsgi.queue_pull() )
return redirect('/')
@app.route('/set', methods=['POST'])
def set_item():
if uwsgi.queue_set(int(request.form['pos']), request.form['body']):
flash('item set')
return redirect('/')
else:
flash('unable to set item')
return render_template('queue.html', uwsgi=uwsgi)
+6
View File
@@ -0,0 +1,6 @@
import sys
def application(e, sr):
sr('200 OK', [('Content-Type','text/html')])
print sys.gettotalrefcount()
yield '%s' % sys.gettotalrefcount()
+16
View File
@@ -0,0 +1,16 @@
import uwsgi
uwsgi.sharedarea_writelong(173, 30)
def application(e, sr):
sr('200 Ok', [('Content-Type','text/html')])
uwsgi.sharedarea_write(17, e['REQUEST_URI'])
uwsgi.sharedarea_inclong(173)
uwsgi.sharedarea_inclong(173, 17)
yield uwsgi.sharedarea_read(17, len(e['REQUEST_URI']))
yield "<br/>"
yield str(uwsgi.sharedarea_readlong(173))
+50
View File
@@ -0,0 +1,50 @@
<head>
<style>
.flash {
color: red;
}
</style>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="flash">
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endwith %}
<h1>next available slot: {{uwsgi.queue_slot()}}</h1>
<h1>next available pull slot: {{uwsgi.queue_pull_slot()}}</h1>
{% for item in range(0, uwsgi.queue_size) %}
slot {{item}} = {{uwsgi.queue_get(item)}}<br/>
{% endfor %}
<br/>
<form method="POST" action="/push">
<input type="text" name="body"><input type="submit" value="push value" /><br/>
</form>
<form method="POST" action="/get">
<input type="text" name="slot" size="9"><input type="submit" value="get value" /><br/>
</form>
<form method="POST" action="/pop">
<input type="submit" value="pop value" /><br/>
</form>
<form method="POST" action="/pull">
<input type="submit" value="pull value" /><br/>
</form>
<form method="POST" action="/set">
<input type="text" name="pos" size="5" /> <input type="text" name="body"><input type="submit" value="set value" /><br/>
</form>
</body>
+71
View File
@@ -0,0 +1,71 @@
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(1)
# task ended raise a signal !!!
uwsgi.signal(17)
def long_task():
for i in range(1,10):
print i
gevent.sleep()
def application(e, sr):
sr('200 OK', [('Content-Type','text/html')])
t = gevent.spawn(long_task)
t.join()
yield "sleeping for 3 seconds...<br/>"
gevent.sleep(3)
yield "done<br>"
yield "getting some ips...<br/>"
urls = ['www.google.com', 'www.example.com', 'www.python.org', 'projects.unbit.it']
jobs = [gevent.spawn(gevent.socket.gethostbyname, url) for url in urls]
gevent.joinall(jobs, timeout=2)
for j in jobs:
yield "ip = %s<br/>" % j.value
if REFCNT:
print sys.gettotalrefcount()
yield "%d" % sys.gettotalrefcount()
# this task will goes on after request end
gevent.spawn(bg_task)
+5
View File
@@ -0,0 +1,5 @@
import uwsgi
print(uwsgi.opt)
print(uwsgi.magic_table)
from werkzeug.testapp import test_app as application
+48 -2
View File
@@ -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)
+21 -19
View File
@@ -195,7 +195,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()");
@@ -433,10 +439,9 @@ void log_syslog(char *syslog_opts) {
char *uwsgi_get_cwd() {
int newsize = 256;
char *cwd;
size_t newsize = 256;
cwd = uwsgi_malloc(newsize);
char *cwd = uwsgi_malloc(newsize);
if (getcwd(cwd, newsize) == NULL) {
newsize = errno;
@@ -1391,14 +1396,14 @@ int count_options(struct option *lopt) {
return count;
}
int uwsgi_read_whole_body_in_mem(struct wsgi_request *wsgi_req, char *buf, size_t limit) {
int uwsgi_read_whole_body_in_mem(struct wsgi_request *wsgi_req, char *buf) {
size_t post_remains = wsgi_req->post_cl;
int ret;
ssize_t len;
char *ptr = buf;
while (post_remains) {
while (post_remains > 0) {
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
}
@@ -1413,12 +1418,8 @@ int uwsgi_read_whole_body_in_mem(struct wsgi_request *wsgi_req, char *buf, size_
return 0;
}
if (limit) {
len = read(wsgi_req->poll.fd, ptr, UMIN(post_remains, limit) );
}
else {
len = read(wsgi_req->poll.fd, ptr, post_remains);
}
len = read(wsgi_req->poll.fd, ptr, post_remains);
if (len <= 0) {
uwsgi_error("read()");
return 0;
@@ -1511,18 +1512,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;
}
@@ -1547,7 +1548,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);
@@ -2036,7 +2037,7 @@ char *magic_sub(char *buffer, int len, int *size, char *magic_table[]) {
void init_magic_table(char *magic_table[]) {
int i;
for (i = 0; i < 0xff; i++) {
for (i = 0; i <= 0xff; i++) {
magic_table[i] = "";
}
@@ -2725,14 +2726,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;
}
+131 -85
View File
@@ -72,11 +72,13 @@ static struct option long_base_options[] = {
{"single-interpreter", no_argument, 0, 'i'},
{"master", no_argument, 0, 'M'},
{"emperor", required_argument, 0, LONG_ARGS_EMPEROR},
{"emperor-tyrant", no_argument, &uwsgi.emperor_tyrant, 1},
{"early-emperor", no_argument, &uwsgi.early_emperor, 1},
{"emperor-broodlord", required_argument, 0, LONG_ARGS_EMPEROR_BROODLORD},
{"emperor-amqp-vhost", required_argument, 0, LONG_ARGS_EMPEROR_AMQP_VHOST},
{"emperor-amqp-username", required_argument, 0, LONG_ARGS_EMPEROR_AMQP_USERNAME},
{"emperor-amqp-password", required_argument, 0, LONG_ARGS_EMPEROR_AMQP_PASSWORD},
{"emperor-throttle", required_argument, 0, LONG_ARGS_EMPEROR_THROTTLE},
{"vassals-inherit", required_argument, 0, LONG_ARGS_VASSALS_INHERIT},
{"vassals-start-hook", required_argument, 0, LONG_ARGS_VASSALS_START_HOOK},
{"vassals-stop-hook", required_argument, 0, LONG_ARGS_VASSALS_STOP_HOOK},
@@ -808,19 +810,19 @@ int main(int argc, char *argv[], char *envp[]) {
#endif
char *emperor_env;
char *magic_table[0xff];
char *optname;
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, SIG_IGN);
init_magic_table(magic_table);
//initialize masterpid with a default value
masterpid = getpid();
memset(&uwsgi, 0, sizeof(struct uwsgi_server));
uwsgi.cwd = uwsgi_get_cwd();
init_magic_table(uwsgi.magic_table);
atexit(vacuum);
@@ -861,6 +863,7 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.cache_server_fd = -1;
uwsgi.emperor_fd_config = -1;
uwsgi.emperor_throttle = 1000;
uwsgi.emperor_pid = -1;
uwsgi.cluster_fd = -1;
@@ -940,11 +943,13 @@ int main(int argc, char *argv[], char *envp[]) {
//initialize embedded plugins
UWSGI_LOAD_EMBEDDED_PLUGINS
// now a bit of magic, if the argv[0] basename contains a 'uwsgi_' string,
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
// try to automatically load a plugin
//uwsgi_log("executable name: %s\n", argv[0]);
char *p = strrchr(argv[0], '/');
if (p == NULL) p = argv[0];
#ifdef UWSGI_DEBUG
uwsgi_log("executable name: %s\n", uwsgi.binary_path);
#endif
char *p = strrchr(uwsgi.binary_path, '/');
if (p == NULL) p = uwsgi.binary_path;
p = strstr(p, "uwsgi_");
if (p != NULL) {
plugins_requested = strchr(p, '_');
@@ -963,6 +968,7 @@ int main(int argc, char *argv[], char *envp[]) {
p = strtok(NULL, ",");
}
}
build_options();
if (gethostname(uwsgi.hostname, 255)) {
@@ -970,12 +976,11 @@ int main(int argc, char *argv[], char *envp[]) {
}
uwsgi.hostname_len = strlen(uwsgi.hostname);
magic_table['v'] = uwsgi.cwd;
magic_table['h'] = uwsgi.hostname;
uwsgi.magic_table['v'] = uwsgi.cwd;
uwsgi.magic_table['h'] = uwsgi.hostname;
#ifdef UWSGI_EMBED_CONFIG
uwsgi_ini_config("", magic_table);
uwsgi_ini_config("", uwsgi.magic_table);
#endif
uwsgi.option_index = -1;
@@ -998,102 +1003,114 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.option_index = -1;
}
#ifdef UWSGI_DEBUG
uwsgi_log("optind:%d argc:%d\n", optind,argc);
#endif
if (optind < argc) {
char *lazy = argv[optind];
if (lazy[0] != '[') {
if (0) {
}
for(i=optind;i<argc;i++) {
char *lazy = argv[i];
if (lazy[0] != '[') {
if (0) {
}
#ifdef UWSGI_XML
else if (!strcmp(lazy + strlen(lazy) - 4, ".xml")) {
uwsgi.xml_config = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 4, ".xml")) {
uwsgi.xml_config = lazy;
}
#endif
#ifdef UWSGI_INI
else if (!strcmp(lazy + strlen(lazy) - 4, ".ini")) {
uwsgi.ini = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 4, ".ini")) {
uwsgi_string_new_list(&uwsgi.ini, lazy);
}
#endif
#ifdef UWSGI_YAML
else if (!strcmp(lazy + strlen(lazy) - 4, ".yml")) {
uwsgi.yaml = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 5, ".yaml")) {
uwsgi.yaml = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 4, ".yml")) {
uwsgi.yaml = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 5, ".yaml")) {
uwsgi.yaml = lazy;
}
#endif
#ifdef UWSGI_JSON
else if (!strcmp(lazy + strlen(lazy) - 3, ".js")) {
uwsgi.json = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 3, ".js")) {
uwsgi.json = lazy;
}
#endif
#ifdef UWSGI_SQLITE3
else if (!strcmp(lazy + strlen(lazy) - 3, ".db")) {
uwsgi.sqlite3 = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 7, ".sqlite")) {
uwsgi.sqlite3 = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 8, ".sqlite3")) {
uwsgi.sqlite3 = lazy;
}
#endif
// manage magic mountpoint
else if ((lazy[0] == '/' || strchr(lazy, '|')) && strchr(lazy, '=')) {
}
else {
int magic = 0;
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->magic) {
if (uwsgi.gp[i]->magic(NULL, lazy)) {
magic = 1;
break;
}
}
else if (!strcmp(lazy + strlen(lazy) - 3, ".db")) {
uwsgi.sqlite3 = lazy;
}
if (!magic) {
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->magic) {
if (uwsgi.p[i]->magic(NULL, lazy)) {
else if (!strcmp(lazy + strlen(lazy) - 7, ".sqlite")) {
uwsgi.sqlite3 = lazy;
}
else if (!strcmp(lazy + strlen(lazy) - 8, ".sqlite3")) {
uwsgi.sqlite3 = lazy;
}
#endif
// manage magic mountpoint
else if ((lazy[0] == '/' || strchr(lazy, '|')) && strchr(lazy, '=')) {
}
else {
int magic = 0;
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->magic) {
if (uwsgi.gp[i]->magic(NULL, lazy)) {
magic = 1;
break;
}
}
}
if (!magic) {
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->magic) {
if (uwsgi.p[i]->magic(NULL, lazy)) {
magic = 1;
break;
}
}
}
}
}
}
}
}
struct uwsgi_string_list *config_file;
#ifdef UWSGI_XML
if (uwsgi.xml_config != NULL) {
config_magic_table_fill(uwsgi.xml_config, magic_table);
uwsgi_xml_config(uwsgi.xml_config, uwsgi.wsgi_req, 0, magic_table);
uwsgi.xml_config = magic_table['p'];
config_magic_table_fill(uwsgi.xml_config, uwsgi.magic_table);
uwsgi_xml_config(uwsgi.xml_config, uwsgi.wsgi_req, 0, uwsgi.magic_table);
uwsgi.xml_config = uwsgi.magic_table['p'];
}
#endif
#ifdef UWSGI_INI
if (uwsgi.ini != NULL) {
config_magic_table_fill(uwsgi.ini, magic_table);
uwsgi_ini_config(uwsgi.ini, magic_table);
config_file = uwsgi.ini;
while(config_file) {
config_magic_table_fill(config_file->value, uwsgi.magic_table);
uwsgi_ini_config(config_file->value, uwsgi.magic_table);
config_file = config_file->next;
}
}
#endif
#ifdef UWSGI_YAML
if (uwsgi.yaml != NULL) {
config_magic_table_fill(uwsgi.yaml, magic_table);
uwsgi_yaml_config(uwsgi.yaml, magic_table);
config_magic_table_fill(uwsgi.yaml, uwsgi.magic_table);
uwsgi_yaml_config(uwsgi.yaml, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_JSON
if (uwsgi.json != NULL) {
config_magic_table_fill(uwsgi.json, magic_table);
uwsgi_json_config(uwsgi.json, magic_table);
config_magic_table_fill(uwsgi.json, uwsgi.magic_table);
uwsgi_json_config(uwsgi.json, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_SQLITE3
if (uwsgi.sqlite3 != NULL) {
config_magic_table_fill(uwsgi.sqlite3, magic_table);
uwsgi_sqlite3_config(uwsgi.sqlite3, magic_table);
config_magic_table_fill(uwsgi.sqlite3, uwsgi.magic_table);
uwsgi_sqlite3_config(uwsgi.sqlite3, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_LDAP
@@ -1110,36 +1127,36 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_log("using %s as config template\n", uct->filename);
#ifdef UWSGI_XML
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".xml")) {
uwsgi_xml_config(uct->filename, uwsgi.wsgi_req, 0, magic_table);
uwsgi_xml_config(uct->filename, uwsgi.wsgi_req, 0, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_INI
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".ini")) {
uwsgi_ini_config(uct->filename, magic_table);
uwsgi_ini_config(uct->filename, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_YAML
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".yml")) {
uwsgi_yaml_config(uct->filename, magic_table);
uwsgi_yaml_config(uct->filename, uwsgi.magic_table);
}
if (!strcmp(uct->filename + strlen(uct->filename) - 5, ".yaml")) {
uwsgi_yaml_config(uct->filename, magic_table);
uwsgi_yaml_config(uct->filename, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_JSON
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".js")) {
uwsgi_json_config(uct->filename, magic_table);
uwsgi_json_config(uct->filename, uwsgi.magic_table);
}
#endif
#ifdef UWSGI_SQLITE3
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".db")) {
uwsgi_sqlite3_config(uct->filename, magic_table);
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
}
if (!strcmp(uct->filename + strlen(uct->filename) - 7, ".sqlite")) {
uwsgi_sqlite3_config(uct->filename, magic_table);
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
}
if (!strcmp(uct->filename + strlen(uct->filename) - 8, ".sqlite3")) {
uwsgi_sqlite3_config(uct->filename, magic_table);
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
}
#endif
uct = uct->next;
@@ -1199,6 +1216,7 @@ int main(int argc, char *argv[], char *envp[]) {
// ok, the options dictionary is available, lets manage it
uwsgi_configure();
/* uWSGI IS CONFIGURED !!! */
@@ -1443,7 +1461,7 @@ int uwsgi_start(void *v_argv) {
if (!uwsgi.no_initial_output) {
if (!uwsgi.master_process) {
uwsgi_log(" *** WARNING: you are running uWSGI without its master process manager ***\n");
uwsgi_log("*** WARNING: you are running uWSGI without its master process manager ***\n");
}
}
#ifndef __OpenBSD__
@@ -1578,15 +1596,16 @@ int uwsgi_start(void *v_argv) {
if (uwsgi.post_buffering > 0) {
uwsgi.async_post_buf = uwsgi_malloc(sizeof(char *) * uwsgi.cores);
uwsgi.mem_post_buf = uwsgi_malloc(sizeof(char *) * uwsgi.cores);
if (!uwsgi.post_buffering_bufsize) {
if (!uwsgi.post_buffering_bufsize)
uwsgi.post_buffering_bufsize = 8192;
if (uwsgi.post_buffering_bufsize < uwsgi.post_buffering) {
uwsgi.post_buffering_bufsize = uwsgi.post_buffering;
uwsgi_log("setting request body buffering size to %d bytes\n", uwsgi.post_buffering_bufsize);
}
}
for (i = 0; i < uwsgi.cores; i++) {
uwsgi.async_buf[i] = uwsgi_malloc(uwsgi.buffer_size);
if (uwsgi.post_buffering > 0) {
uwsgi.mem_post_buf[i] = uwsgi_malloc(uwsgi.post_buffering);
uwsgi.async_post_buf[i] = uwsgi_malloc(uwsgi.post_buffering_bufsize);
}
}
@@ -1654,18 +1673,18 @@ int uwsgi_start(void *v_argv) {
uwsgi_lock_init(uwsgi.rpc_table_lock);
if (uwsgi.sharedareasize > 0) {
uwsgi.sharedareamutex = uwsgi_mmap_shared_lock();
uwsgi.sharedarea = mmap(NULL, uwsgi.page_size * uwsgi.sharedareasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (uwsgi.sharedarea) {
uwsgi_log("shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea);
uwsgi_lock_init(uwsgi.sharedareamutex);
}
else {
uwsgi_error("mmap()");
exit(1);
}
uwsgi.sa_lock = uwsgi_mmap_shared_rwlock();
uwsgi_rwlock_init(uwsgi.sa_lock);
}
if (uwsgi.queue_size > 0) {
@@ -2575,9 +2594,15 @@ void uwsgi_ignition() {
if (uwsgi.loop) {
void (*u_loop) (void) = uwsgi_get_loop(uwsgi.loop);
uwsgi_log("running %s loop %p\n", uwsgi.loop, u_loop);
if (!u_loop) {
uwsgi_log("unavailable loop engine !!!\n");
exit(1);
}
if (uwsgi.mywid == 1) {
uwsgi_log("*** running %s loop engine [addr:%p] ***\n", uwsgi.loop, u_loop);
}
u_loop();
uwsgi_log("done\n");
uwsgi_log("your loop engine died. R.I.P.\n");
}
else {
#ifdef UWSGI_ZEROMQ
@@ -2742,6 +2767,9 @@ static int manage_base_opt(int i, char *optarg) {
case LONG_ARGS_EMPEROR_BROODLORD:
uwsgi.emperor_broodlord = atoi(optarg);
return 1;
case LONG_ARGS_EMPEROR_THROTTLE:
uwsgi.emperor_throttle = atoi(optarg);
return 1;
case LONG_ARGS_EMPEROR:
uwsgi.emperor_dir = optarg;
return 1;
@@ -3084,7 +3112,7 @@ static int manage_base_opt(int i, char *optarg) {
#endif
#ifdef UWSGI_INI
case LONG_ARGS_INI:
uwsgi.ini = optarg;
uwsgi_string_new_list(&uwsgi.ini, optarg);
return 1;
#endif
case LONG_ARGS_SOCKET_PROTOCOL:
@@ -3463,10 +3491,11 @@ void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) {
void build_options() {
int i;
struct option *lopt, *aopt;
int opt_count = count_options(long_base_options);
int short_opt_size = strlen(base_short_options);
char *so_ptr;
int opt_count = count_options(long_base_options);
size_t short_opt_size = strlen(base_short_options);
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->short_options) {
short_opt_size += strlen(uwsgi.p[i]->short_options);
@@ -3479,9 +3508,12 @@ void build_options() {
}
}
if (short_options) {
free(short_options);
}
short_options = uwsgi_malloc(short_opt_size + 1);
memcpy(short_options, base_short_options, strlen(base_short_options));
so_ptr = short_options + strlen(base_short_options);
@@ -3897,6 +3929,20 @@ struct uwsgi_help_item main_help[] = {
{"version", "print server version"},
{"attach-daemon <command>", "run <command> under the control of master process"},
{"daemonize <logfile|addr>", "daemonize and log into <logfile> or udp <addr>"},
{"loop <engine>", "use the <engine> loop engine"},
{"worker-exec <command>", "execve() <command> after each worker's fork()"},
{"autoload", "try to automatically load plugins"},
{"lazy", "load applications after each worker's fork()"},
{"cheap", "postpone workers startup until the first request"},
{"idle <secs>", "destroy workers (the server will go in cheap mode) after <secs> of inactivity"},
{"freebind (Linux only)", "allows binding on non-existent network address"},
{"xml <file>", "load config from an xml file"},
{"protocol <proto>", "set the default communication protocol (uwsgi, http, fastcgi)"},
{"reuse-port (BSD only)", "allows multiple instances bining on the same address"},
{"set KEY=VALUE", "set a placeholder"},
{"reload-mercy <secs>", "brutally kill workers not reloading in <secs>"},
{"emperor <dir|glob>", "start the emperor monitoring <dir|glob>"},
{"touch-reload <file>", "issue a graceful reload on <file> modifications/touch"},
{0, 0},
+18 -9
View File
@@ -323,6 +323,11 @@ struct uwsgi_daemon {
//int pipe[2];
};
struct uwsgi_queue_header {
uint64_t pos;
uint64_t pull_pos;
};
struct uwsgi_queue_item {
uint64_t size;
time_t ts;
@@ -480,6 +485,7 @@ struct uwsgi_opt {
#define LONG_ARGS_HTTP_SOCKET 17132
#define LONG_ARGS_FASTCGI_SOCKET 17133
#define LONG_ARGS_THREADS_STACKSIZE 17134
#define LONG_ARGS_EMPEROR_THROTTLE 17135
#define UWSGI_OK 0
@@ -928,8 +934,10 @@ struct uwsgi_server {
int has_emperor;
int emperor_fd;
int emperor_tyrant;
int emperor_fd_config;
int early_emperor;
int emperor_throttle;
char *emperor_dir;
pid_t emperor_pid;
int emperor_broodlord;
@@ -1015,7 +1023,6 @@ struct uwsgi_server {
struct iovec **async_hvec;
char **async_buf;
char **async_post_buf;
char **mem_post_buf;
struct wsgi_request **async_waiting_fd_table;
struct wsgi_request **async_proto_fd_table;
@@ -1062,6 +1069,7 @@ struct uwsgi_server {
#ifdef UWSGI_SPOOLER
char *spool_dir;
int spooler_ordered;
uint64_t spooler_respawned;
#endif
#ifdef UWSGI_SNMP
@@ -1097,6 +1105,8 @@ struct uwsgi_server {
int harakiri_verbose;
char *magic_table[256];
int numproc;
int async;
int async_running;
@@ -1109,8 +1119,7 @@ struct uwsgi_server {
int vec_size;
char *sharedarea;
void *sharedareamutex;
int sharedareasize;
uint64_t sharedareasize;
#ifdef UWSGI_THREADING
pthread_mutex_t six_feet_under_lock;
@@ -1165,7 +1174,7 @@ struct uwsgi_server {
#endif
#ifdef UWSGI_INI
char *ini;
struct uwsgi_string_list *ini;
#endif
#ifdef UWSGI_SQLITE3
@@ -1300,6 +1309,7 @@ struct uwsgi_server {
uint64_t queue_size;
uint64_t queue_blocksize;
void *queue;
struct uwsgi_queue_header *queue_header;
char *queue_store;
size_t queue_filesize;
int queue_store_sync;
@@ -1315,6 +1325,7 @@ struct uwsgi_server {
void *rb_timer_table_lock;
void *cron_table_lock;
void *rpc_table_lock;
void *sa_lock;
#ifdef UWSGI_SPOOLER
void *spooler_lock;
#endif
@@ -1440,8 +1451,6 @@ struct uwsgi_shared {
uint64_t cache_first_available_item;
uint64_t cache_unused_stack_ptr;
uint64_t queue_pos;
uint64_t queue_pull_pos;
int worker_signal_pipe[2];
#ifdef UWSGI_SPOOLER
@@ -1720,7 +1729,7 @@ struct wsgi_request *threaded_current_wsgi_req(void);
void build_options(void);
int uwsgi_read_whole_body(struct wsgi_request *, char *, size_t);
int uwsgi_read_whole_body_in_mem(struct wsgi_request *, char *, size_t);
int uwsgi_read_whole_body_in_mem(struct wsgi_request *, char *);
ssize_t uwsgi_sendfile(struct wsgi_request *);
@@ -1867,6 +1876,8 @@ void uwsgi_init_cache(void);
char *uwsgi_queue_get(uint64_t, uint64_t *);
char *uwsgi_queue_pull(uint64_t *);
int uwsgi_queue_push(char *, uint64_t);
char *uwsgi_queue_pop(uint64_t *);
int uwsgi_queue_set(uint64_t, char *, uint64_t);
// maintain alignment here !!!
struct uwsgi_dict_item {
@@ -1993,8 +2004,6 @@ inline int event_queue_write(void);
void uwsgi_help(void);
void uwsgi_queue_fix(void);
int uwsgi_str2_num(char *);
int uwsgi_str3_num(char *);
int uwsgi_str4_num(char *);
+64 -16
View File
@@ -25,6 +25,8 @@ 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):
@@ -57,6 +59,16 @@ 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':
@@ -100,7 +112,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
@@ -125,7 +137,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':
@@ -160,7 +172,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)
@@ -182,7 +194,10 @@ def build_uwsgi(uc):
if bin_name.find("/") < 0:
bin_name = './' + bin_name
print("*** uWSGI is ready, launch it with %s ***" % bin_name)
if uc.get('as_shared_library'):
print("*** uWSGI shared library (%s) is ready, move it to a library directory ***" % bin_name)
else:
print("*** uWSGI is ready, launch it with %s ***" % bin_name)
class uConf(object):
@@ -190,6 +205,8 @@ class uConf(object):
def __init__(self, filename):
self.config = ConfigParser.ConfigParser()
print("using profile: %s" % filename)
if not os.path.exists(filename):
raise Exception("profile not found !!!")
self.config.read(filename)
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify',
'plugins', 'lock', 'cache', 'queue', 'event', 'signal', 'rpc', 'gateway', 'loop', 'lib/rbtree', 'lib/amqp', 'rb_timers', 'uwsgi']
@@ -198,15 +215,37 @@ class uConf(object):
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)
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)
gcc_major = int(gcc_version.split('.')[0])
gcc_minor = int(gcc_version.split('.')[1])
if (sys.version_info[0] == 2) or (gcc_major < 4) or (gcc_major == 4 and gcc_minor < 3):
@@ -261,6 +300,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
@@ -268,7 +313,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':
@@ -342,7 +387,10 @@ class uConf(object):
k_all = uwsgi_os_k.split('.')
k_base = k_all[0]
k_major = k_all[1]
k_minor = k_all[2]
if len(k_all) > 2:
k_minor = k_all[2]
else:
k_minor = 0
if int(k_base) > 2:
timer_mode = 'timerfd'
elif int(k_minor) >= 25:
@@ -361,7 +409,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')
@@ -437,7 +485,7 @@ class uConf(object):
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'):
@@ -542,7 +590,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')
@@ -555,7 +603,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')
@@ -568,7 +616,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')
@@ -579,7 +627,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')
@@ -627,7 +675,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')
@@ -719,13 +767,13 @@ if __name__ == "__main__":
if cmd == '--libs':
print(' '.join(libs))
elif cmd == '--build':
bconf = 'default.ini'
bconf = os.environ.get('UWSGI_PROFILE','default.ini')
try:
bconf = sys.argv[2]
if not bconf.endswith('.ini'):
bconf += '.ini'
except:
pass
if not bconf.endswith('.ini'):
bconf += '.ini'
if not '/' in bconf:
bconf = 'buildconf/%s' % bconf
build_uwsgi(uConf(bconf))
+3
View File
@@ -153,6 +153,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)
+9
View File
@@ -0,0 +1,9 @@
[uwsgi]
socket = :3031
socket = /tmp/uwsgi_welcome.socket
vacuum = true
module = welcome
master = true
processes = 4
mount = /werkzeug=tests/werkzeug.py
manage-script-name = true
+57
View File
@@ -0,0 +1,57 @@
import uwsgi
import os
def xsendfile(e, sr):
sr('200 OK', [('Content-Type', 'image/png'), ('X-Sendfile', os.path.abspath('logo_uWSGI.png'))])
return b''
def serve_logo(e, sr):
sr('200 OK', [('Content-Type', 'image/png')])
return uwsgi.sendfile('logo_uWSGI.png')
def serve_options(e, sr):
sr('200 OK', [('Content-Type', 'text/html')])
for opt in range(0,256):
body = "{opt} = {optvalue}<br/>".format(opt=opt, optvalue=uwsgi.get_option(opt))
yield bytes(body.encode('ascii'))
def serve_config(e, sr):
sr('200 OK', [('Content-Type', 'text/html')])
for opt in uwsgi.opt.keys():
body = "{opt} = {optvalue}<br/>".format(opt=opt, optvalue=uwsgi.opt[opt].decode('ascii'))
yield bytes(body.encode('ascii'))
routes = {}
routes['/xsendfile'] = xsendfile
routes['/logo'] = serve_logo
routes['/config'] = serve_config
routes['/options'] = serve_options
def application(env, start_response):
if env['PATH_INFO'] in routes:
return routes[env['PATH_INFO']](env, start_response)
start_response('200 OK', [('Content-Type', 'text/html')])
body = """
<img src="/logo"/> version {version}<br/>
<hr size="1"/>
Configuration<br/>
<iframe src="/config"></iframe><br/>
<br/>
Dynamic options<br/>
<iframe src="/options"></iframe><br/>
""".format(version=uwsgi.version.decode('ascii'))
return bytes(body.encode('ascii'))
+3 -3
View File
@@ -141,12 +141,12 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, int app_tag
if (node->type == XML_ELEMENT_NODE) {
if (!strcmp((char *) node->name, "app")) {
wsgi_req->script_name_len = 0;
wsgi_req->appid_len = 0;
wsgi_req->host_len = 0;
xml_uwsgi_mountpoint = xmlGetProp(node, (const xmlChar *) "mountpoint");
if (xml_uwsgi_mountpoint) {
wsgi_req->script_name = (char *) xml_uwsgi_mountpoint;
wsgi_req->script_name_len = strlen(wsgi_req->script_name);
wsgi_req->appid = (char *) xml_uwsgi_mountpoint;
wsgi_req->appid_len = strlen(wsgi_req->appid);
}
xml_uwsgi_domain = xmlGetProp(node, (const xmlChar *) "domain");