mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
668c173969 | ||
|
|
4c19a941eb | ||
|
|
9761153ab0 | ||
|
|
140a1b1587 | ||
|
|
e5f5f40f3c | ||
|
|
2e13622ecc | ||
|
|
a4fb281859 | ||
|
|
75ba4e2220 | ||
|
|
24b17da2ea | ||
|
|
c4664fe6e3 | ||
|
|
a1ab298609 | ||
|
|
533f9f8323 | ||
|
|
6d5912f307 | ||
|
|
3d2b7c136a | ||
|
|
f25d147908 | ||
|
|
e119c8cc53 | ||
|
|
73e94350df | ||
|
|
9d8ee5aec8 | ||
|
|
c3bbd5f54f | ||
|
|
e17be93cb6 | ||
|
|
1013ca340a | ||
|
|
b87e7c0af8 | ||
|
|
615348c5a1 | ||
|
|
cae0f9bc2e | ||
|
|
93b23e3de0 | ||
|
|
eebb00d2b3 | ||
|
|
11f9b04fd1 | ||
|
|
bde996de75 | ||
|
|
552163a3bd | ||
|
|
2e6af966a9 | ||
|
|
c1775967c8 | ||
|
|
034a0a594d | ||
|
|
63a66ea82a | ||
|
|
6f155ebf17 | ||
|
|
f39d8cc5fb | ||
|
|
aecba7e710 | ||
|
|
c365eeec76 | ||
|
|
5bd06402de | ||
|
|
ec899a45d5 | ||
|
|
513c9cee3d | ||
|
|
850f2abd5c | ||
|
|
8d7940ebee | ||
|
|
195e9c398e | ||
|
|
c998d6bd1b | ||
|
|
34be14ece1 | ||
|
|
c0d6f33d54 | ||
|
|
d5210283ca | ||
|
|
545784d7af | ||
|
|
e9726b1e75 | ||
|
|
e08b2cccf9 | ||
|
|
0ba1b982d1 | ||
|
|
374c02c46e | ||
|
|
5ed59690a0 | ||
|
|
2de489f301 | ||
|
|
40a722294f | ||
|
|
9598c525cf | ||
|
|
3ed6c5e943 | ||
|
|
0f178c17ee | ||
|
|
1c963b72a3 | ||
|
|
bd1b3b8b12 | ||
|
|
f9a843dfd5 | ||
|
|
9df8f4ae2b | ||
|
|
87f649b71b | ||
|
|
3585bb0a6e | ||
|
|
750bbd64b2 | ||
|
|
19c567cef3 | ||
|
|
5024368854 | ||
|
|
3200f88363 | ||
|
|
650c77d0d1 | ||
|
|
3fa29515f2 | ||
|
|
012435747e | ||
|
|
733077a437 | ||
|
|
6b3fa74800 | ||
|
|
d673627c79 | ||
|
|
8b423d00e9 | ||
|
|
201086c854 | ||
|
|
2441cf36b3 |
@@ -25,3 +25,4 @@ e91bc724325e14c13b8f548c0b6a315c48a1c32a 0.9.8-rc2
|
||||
4fb424d52f226a0a087fea89709f5eb540e03f25 0.9.8-rc3
|
||||
0f1f3924ee5309a9990d9af1ffc68846e3dfb31b 0.9.8-rc4
|
||||
42efe1f329005618c8b44f901979ebcecd5216fb 0.9.8
|
||||
fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
- this is a incomplete list of all the contributors of the project -
|
||||
|
||||
Roberto De Ioris, Unbit, <roberto@unbit.it>
|
||||
Riccardo Magliocchetti, Unbit, <riccardo@unbit.it>
|
||||
Yann Malet, Lincoln Loop
|
||||
Simon Litchfield
|
||||
Masahiro Honma, <hiratara@cpan.org>
|
||||
Łukasz Wróblewski <admin@nri.pl>
|
||||
Giacomo Bagnoli, Asidev
|
||||
Guido Notari, Link I.T. S.p.a.
|
||||
Marco Beri, Link I.T. S.p.a.
|
||||
Leonid Borisenko
|
||||
Cal Leeming, Simplicity Media Ltd
|
||||
Luigi Scarso
|
||||
@@ -1,3 +1,25 @@
|
||||
*** july 2011 ***
|
||||
|
||||
* 0.9.8.2 [20110719]
|
||||
|
||||
- fixed an ini and yaml parsing bug spotted by Raffaele Colace
|
||||
- spooler has been extremely improved
|
||||
- new option --chown-socket
|
||||
- added uwsgidecorators for elegant uwsgi api access from python
|
||||
- the rack plugin is now stable
|
||||
- support for embedding config and generic files in the server binary
|
||||
- high-performance cache-server
|
||||
- accept() is now locked on all threads in the same workers
|
||||
- preliminary implementation of hooks in emperor
|
||||
- support for C++ in server core
|
||||
- tcp port auto-bind
|
||||
- implemented workers, workerN and spooler signal target
|
||||
- prefork/multithread uwsgi.signal_wait() implementation
|
||||
- export uwsgi.node in WSGI vars
|
||||
- new option --import (python plugin)
|
||||
- support for unlimited number of Linux cgroups
|
||||
- broodlord mode
|
||||
|
||||
*** june 2011 ***
|
||||
|
||||
* 0.9.8.1 [20110625]
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import sys
|
||||
import uwsgi
|
||||
|
||||
sys.meta_path.insert(0, uwsgi.SymbolsImporter())
|
||||
@@ -0,0 +1 @@
|
||||
object file for embedded files will be put here
|
||||
@@ -34,6 +34,10 @@ event = auto
|
||||
timer = auto
|
||||
filemonitor = auto
|
||||
|
||||
embed_files =
|
||||
|
||||
embed_config =
|
||||
|
||||
[python]
|
||||
paste = true
|
||||
web3 = true
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[uwsgi]
|
||||
inherit = default
|
||||
|
||||
embed_files = embedme.py,uwsgidecorators.py
|
||||
+13
-1
@@ -2,6 +2,9 @@
|
||||
xml = true
|
||||
ini = true
|
||||
yaml = true
|
||||
json = true
|
||||
sqlite3 = true
|
||||
zeromq = false
|
||||
snmp = false
|
||||
sctp = false
|
||||
spooler = true
|
||||
@@ -10,14 +13,23 @@ udp = true
|
||||
multicast = false
|
||||
threading = true
|
||||
sendfile = true
|
||||
nagios = false
|
||||
minterpreters = true
|
||||
async = true
|
||||
evdis = false
|
||||
ldap = true
|
||||
pcre = false
|
||||
debug = false
|
||||
unbit = true
|
||||
xml_implementation = libxml2
|
||||
yaml_implementation = auto
|
||||
malloc_implementation = libc
|
||||
plugins =
|
||||
bin_name = /opt/unbit/bin/uwsgi
|
||||
append_version = unbit
|
||||
plugin_dir = /opt/unbit/uwsgi_plugins
|
||||
embedded_plugins =
|
||||
|
||||
locking = auto
|
||||
event = auto
|
||||
timer = auto
|
||||
filemonitor = auto
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[uwsgi]
|
||||
inherit = unbit
|
||||
json = false
|
||||
embedded_plugins = python
|
||||
bin_name = ../bin/uwsgi
|
||||
plugin_dir = ../bin/uwsgi_plugins
|
||||
|
||||
@@ -582,3 +582,124 @@ end:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* THIS PART IS HEAVILY OPTIMIZED: PERFORMANCE NOT ELEGANCE !!! */
|
||||
|
||||
void *cache_thread_loop(void *fd_ptr) {
|
||||
|
||||
int *fd_tmp = (int *) fd_ptr;
|
||||
int fd = *fd_tmp;
|
||||
int i;
|
||||
ssize_t len;
|
||||
char uwsgi_packet[UMAX16+4];
|
||||
struct uwsgi_header *uh = (struct uwsgi_header *) uwsgi_packet;
|
||||
char *val;
|
||||
uint64_t vallen;
|
||||
char *key;
|
||||
uint16_t keylen;
|
||||
struct pollfd ctl_poll;
|
||||
char *watermark;
|
||||
struct sockaddr_un ctl_sun;
|
||||
socklen_t ctl_sun_len;
|
||||
|
||||
ctl_poll.events = POLLIN;
|
||||
|
||||
for(;;) {
|
||||
ctl_sun_len = sizeof(struct sockaddr_un);
|
||||
pthread_mutex_lock(&uwsgi.cache_server_lock);
|
||||
|
||||
ctl_poll.fd = accept(fd, (struct sockaddr *) &ctl_sun, &ctl_sun_len);
|
||||
|
||||
pthread_mutex_unlock(&uwsgi.cache_server_lock);
|
||||
|
||||
if (ctl_poll.fd < 0) {
|
||||
uwsgi_error("cache accept()");
|
||||
continue;
|
||||
}
|
||||
i = 0;
|
||||
while(i < 4) {
|
||||
len = poll(&ctl_poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("cache poll()");
|
||||
goto clear;
|
||||
}
|
||||
len = read(ctl_poll.fd, uwsgi_packet+i, 4-i);
|
||||
if (len < 0) {
|
||||
uwsgi_error("cache read()");
|
||||
goto clear;
|
||||
}
|
||||
i+=len;
|
||||
}
|
||||
|
||||
if (uh->pktsize == 0) goto clear;
|
||||
|
||||
while(i < 4+uh->pktsize) {
|
||||
len = poll(&ctl_poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("cache poll()");
|
||||
goto clear;
|
||||
}
|
||||
len = read(ctl_poll.fd, uwsgi_packet+i, (4+uh->pktsize)-i);
|
||||
if (len < 0) {
|
||||
uwsgi_error("cache read()");
|
||||
goto clear;
|
||||
}
|
||||
i+=len;
|
||||
}
|
||||
|
||||
watermark = uwsgi_packet+4+uh->pktsize;
|
||||
|
||||
// get first parameter
|
||||
memcpy(&keylen, uwsgi_packet+4, 2);
|
||||
#ifdef __BIG_ENDIAN__
|
||||
keylen = uwsgi_swap16(keylen);
|
||||
#endif
|
||||
if (uwsgi_packet+6+keylen > watermark) goto clear;
|
||||
key = uwsgi_packet+6+keylen+2;
|
||||
memcpy(&keylen, key-2, 2);
|
||||
#ifdef __BIG_ENDIAN__
|
||||
keylen = uwsgi_swap16(keylen);
|
||||
#endif
|
||||
|
||||
if (key+keylen > watermark) goto clear;
|
||||
|
||||
val = uwsgi_cache_get(key, keylen, &vallen);
|
||||
if (val && vallen > 0) {
|
||||
if (write(ctl_poll.fd, val, vallen) < 0) {
|
||||
uwsgi_error("cache write()");
|
||||
}
|
||||
}
|
||||
|
||||
clear:
|
||||
close(ctl_poll.fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_cache_server(char *socket, int threads) {
|
||||
|
||||
int *fd = uwsgi_malloc(sizeof(int));
|
||||
|
||||
int i;
|
||||
pthread_t thread_id;
|
||||
char *tcp_port = strchr(socket, ':');
|
||||
if (tcp_port) {
|
||||
*fd = bind_to_tcp(socket, uwsgi.listen_queue, tcp_port);
|
||||
}
|
||||
else {
|
||||
*fd = bind_to_unix(socket, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
|
||||
pthread_mutex_init(&uwsgi.cache_server_lock, NULL);
|
||||
|
||||
if (threads < 1) threads = 1;
|
||||
|
||||
uwsgi_log("*** cache-optimized server enabled on fd %d (%d threads) ***\n", *fd, threads);
|
||||
|
||||
for(i=0;i<threads;i++) {
|
||||
pthread_create(&thread_id, NULL, cache_thread_loop, (void *) fd);
|
||||
}
|
||||
|
||||
return *fd;
|
||||
}
|
||||
|
||||
|
||||
+97
-3
@@ -1,4 +1,6 @@
|
||||
#!./uwsgi --import decoratortest -s :3035 -M --spooler myspool --enable-threads -p 8 --spooler-ordered
|
||||
import uwsgi
|
||||
|
||||
from uwsgidecorators import *
|
||||
|
||||
from uwsgicc import app as application
|
||||
@@ -6,23 +8,115 @@ from uwsgicc import app as application
|
||||
import time
|
||||
|
||||
|
||||
# register rpc function helloworld
|
||||
@rpc("helloworld")
|
||||
def hello_world():
|
||||
return "Hello World"
|
||||
|
||||
# register signal 1
|
||||
@signal(1)
|
||||
def what_time_is_it(num):
|
||||
print(time.asctime())
|
||||
|
||||
# register signal 100
|
||||
@signal(100, target='workers')
|
||||
def what_time_is_it(num):
|
||||
print("*** I AM THE WORKER %d AT %s ***" % (uwsgi.worker_id(), time.asctime()))
|
||||
|
||||
@timer(2, 3)
|
||||
|
||||
# a 3 seconds timer
|
||||
@timer(3)
|
||||
def salut(num):
|
||||
print("Salut !!! 3 seconds elapsed and signal %d raised" % num)
|
||||
|
||||
@rbtimer(3, 10)
|
||||
# a 10 seconds red black timer (executed by the spooler)
|
||||
@rbtimer(10, target='spooler')
|
||||
def tenseconds(num):
|
||||
print("red black timer !!! 10 seconds elapsed and signal %d raised" % num)
|
||||
|
||||
@filemon(4, "/tmp")
|
||||
# monitor /tmp directory
|
||||
@filemon("/tmp")
|
||||
def tmpmodified(num):
|
||||
print("/tmp has been modified")
|
||||
|
||||
|
||||
# spool a long running task
|
||||
@spool
|
||||
def a_long_task(args):
|
||||
for i in xrange(1,10):
|
||||
print("%s = %d" % ( str(args), i))
|
||||
time.sleep(1)
|
||||
|
||||
# continuosly spool a long running task
|
||||
@spoolforever
|
||||
def an_infinite_task(args):
|
||||
for i in xrange(1,4):
|
||||
print("infinite: %d %s" % (i, str(args)))
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
# spool a task after 60 seconds
|
||||
@spool
|
||||
def delayed_task(args):
|
||||
print("*** I am a delayed spool job. It is %s [%s]***" % (time.asctime(), str(args)))
|
||||
# send a signal to all workers
|
||||
uwsgi.signal(100)
|
||||
|
||||
@spool
|
||||
def big_body_task(args):
|
||||
print("*** managing a task with a body of %d bytes ***" % len(args['body']))
|
||||
print(args['body'].swapcase())
|
||||
|
||||
# run a task every hour
|
||||
@cron(59, -1, -1, -1, -1)
|
||||
def one_hour_passed(num):
|
||||
print("received signal %d after 1 hour" % num)
|
||||
|
||||
@thread
|
||||
def a_running_thread():
|
||||
while True:
|
||||
time.sleep(2)
|
||||
print("i am a no-args thread")
|
||||
|
||||
@thread
|
||||
def a_running_thread_with_args(who):
|
||||
while True:
|
||||
time.sleep(2)
|
||||
print("Hello %s (from arged-thread)" % who)
|
||||
|
||||
@postfork
|
||||
@thread
|
||||
def a_post_fork_thread():
|
||||
while True:
|
||||
time.sleep(3)
|
||||
print("Hello from a thread in worker %d" % uwsgi.worker_id())
|
||||
|
||||
@postfork
|
||||
def fork_happened():
|
||||
print("fork() has been called [1]")
|
||||
|
||||
@postfork
|
||||
def fork_happened2():
|
||||
print("waiting for a signal...")
|
||||
uwsgi.signal_wait()
|
||||
print("signal received: %d" % 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)
|
||||
print("[locked %d] waiting..." % uwsgi.worker_id())
|
||||
print("done with locked function on worker %d" % uwsgi.worker_id())
|
||||
|
||||
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)
|
||||
a_running_thread()
|
||||
a_running_thread_with_args("uWSGI")
|
||||
uwsgi_source_file = open('uwsgi.c','r')
|
||||
print(big_body_task.spool(priority=9,filename='uwsgi.c',body=uwsgi_source_file.read()))
|
||||
uwsgi_source_file.close()
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
from django.template.base import TemplateDoesNotExist
|
||||
from django.template.loader import BaseLoader
|
||||
from django.conf import settings
|
||||
|
||||
try:
|
||||
import uwsgi
|
||||
on_uwsgi = True
|
||||
except:
|
||||
on_uwsgi = False
|
||||
|
||||
|
||||
|
||||
|
||||
class Loader(BaseLoader):
|
||||
|
||||
is_usable = on_uwsgi
|
||||
|
||||
def symbolize(self, name):
|
||||
return name.replace('.','_').replace('/','_').replace('-','_')
|
||||
|
||||
def load_template_source(self, template_name, template_dirs=None):
|
||||
filename = 'templates_' + self.symbolize(template_name)
|
||||
for app in settings.INSTALLED_APPS:
|
||||
try:
|
||||
symbol = "%s_%s" % (self.symbolize(app), filename)
|
||||
return (uwsgi.embedded_data(symbol), "sym://%s" % symbol)
|
||||
except:
|
||||
pass
|
||||
raise TemplateDoesNotExist(template_name)
|
||||
@@ -6,37 +6,71 @@ extern struct uwsgi_server uwsgi;
|
||||
extern char **environ;
|
||||
|
||||
int emperor_queue;
|
||||
char *emperor_absolute_dir;
|
||||
|
||||
struct uwsgi_instance {
|
||||
struct uwsgi_instance *ui_prev;
|
||||
struct uwsgi_instance *ui_next;
|
||||
|
||||
char name[0xff];
|
||||
pid_t pid;
|
||||
|
||||
int status;
|
||||
time_t born;
|
||||
time_t last_mod;
|
||||
time_t last_loyal;
|
||||
|
||||
uint64_t respawns;
|
||||
int use_config;
|
||||
|
||||
int pipe[2];
|
||||
int pipe_config[2];
|
||||
|
||||
char *config;
|
||||
uint32_t config_len;
|
||||
|
||||
int loyal;
|
||||
|
||||
int zerg;
|
||||
};
|
||||
|
||||
|
||||
struct uwsgi_instance *ui;
|
||||
|
||||
static void royal_death(int signum) {
|
||||
|
||||
|
||||
if (uwsgi.vassals_stop_hook) {
|
||||
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
|
||||
while (c_ui) {
|
||||
uwsgi_log("running vassal stop-hook: %s %s\n", uwsgi.vassals_stop_hook, c_ui->name);
|
||||
if (setenv("UWSGI_VASSALS_DIR", emperor_absolute_dir, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
int stop_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_stop_hook, c_ui->name);
|
||||
uwsgi_log("%s stop-hook returned %d\n", c_ui->name, stop_hook_ret);
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
}
|
||||
uwsgi_notify("The Emperor is buried.");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
struct uwsgi_instance {
|
||||
struct uwsgi_instance *ui_prev;
|
||||
struct uwsgi_instance *ui_next;
|
||||
|
||||
char name[0xff];
|
||||
pid_t pid;
|
||||
void emperor_stats() {
|
||||
|
||||
int status;
|
||||
time_t born;
|
||||
time_t last_mod;
|
||||
time_t last_loyal;
|
||||
struct uwsgi_instance *c_ui = ui->ui_next;
|
||||
|
||||
uint64_t respawns;
|
||||
int use_config;
|
||||
while (c_ui) {
|
||||
|
||||
int pipe[2];
|
||||
int pipe_config[2];
|
||||
uwsgi_log("vassal instance %s (last modified %d) status %d loyal %d zerg %d\n",c_ui->name, c_ui->last_mod, c_ui->status, c_ui->loyal, c_ui->zerg);
|
||||
|
||||
char *config;
|
||||
uint32_t config_len;
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
|
||||
int loyal;
|
||||
};
|
||||
|
||||
struct uwsgi_instance *ui;
|
||||
}
|
||||
|
||||
struct uwsgi_instance *emperor_get_by_fd(int fd) {
|
||||
|
||||
@@ -86,12 +120,19 @@ void emperor_del(struct uwsgi_instance *c_ui) {
|
||||
|
||||
if (uwsgi.vassals_stop_hook) {
|
||||
uwsgi_log("running vassal stop-hook: %s %s\n", uwsgi.vassals_stop_hook, c_ui->name);
|
||||
if (setenv("UWSGI_VASSALS_DIR", emperor_absolute_dir, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
int stop_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_stop_hook, c_ui->name);
|
||||
uwsgi_log("%s stop-hook returned %d\n", c_ui->name, stop_hook_ret);
|
||||
}
|
||||
|
||||
uwsgi_log("removed uwsgi instance %s\n", c_ui->name);
|
||||
|
||||
if (c_ui->zerg) {
|
||||
uwsgi.emperor_broodlord_count--;
|
||||
}
|
||||
|
||||
free(c_ui);
|
||||
|
||||
}
|
||||
@@ -137,6 +178,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
char *uef;
|
||||
char **uenvs;
|
||||
int counter;
|
||||
char *colon = NULL;
|
||||
int i;
|
||||
|
||||
sleep(1);
|
||||
@@ -159,6 +201,12 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
uwsgi_log("c_ui->ui_next = %p\n", c_ui->ui_next);
|
||||
#endif
|
||||
n_ui->ui_prev = c_ui;
|
||||
|
||||
if (strchr(name,':')) {
|
||||
n_ui->zerg = 1;
|
||||
uwsgi.emperor_broodlord_count++;
|
||||
}
|
||||
|
||||
memcpy(n_ui->name, name, strlen(name));
|
||||
n_ui->born = born;
|
||||
n_ui->last_mod = born;
|
||||
@@ -263,6 +311,13 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
argv = uwsgi_malloc(sizeof(char *) * counter);
|
||||
// set args
|
||||
argv[0] = uwsgi.binary_path;
|
||||
|
||||
if (uwsgi.emperor_broodlord) {
|
||||
colon = strchr(name, ':');
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
}
|
||||
}
|
||||
if (!strcmp(name + (strlen(name) - 4), ".xml"))
|
||||
argv[1] = "--xml";
|
||||
if (!strcmp(name + (strlen(name) - 4), ".ini"))
|
||||
@@ -273,6 +328,10 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
argv[1] = "--yaml";
|
||||
if (!strcmp(name + (strlen(name) - 3), ".js"))
|
||||
argv[1] = "--json";
|
||||
|
||||
if (colon) {
|
||||
colon[0] = ':';
|
||||
}
|
||||
argv[2] = name;
|
||||
counter = 3;
|
||||
uct = uwsgi.vassals_templates;
|
||||
@@ -293,6 +352,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
|
||||
if (uwsgi.vassals_start_hook) {
|
||||
uwsgi_log("running vassal start-hook: %s %s\n", uwsgi.vassals_start_hook, n_ui->name);
|
||||
if (setenv("UWSGI_VASSALS_DIR", emperor_absolute_dir, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
int start_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_start_hook, n_ui->name);
|
||||
uwsgi_log("%s start-hook returned %d\n", n_ui->name, start_hook_ret);
|
||||
}
|
||||
@@ -341,6 +403,8 @@ void emperor_loop() {
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
uwsgi_unix_signal(SIGINT, royal_death);
|
||||
uwsgi_unix_signal(SIGTERM, royal_death);
|
||||
uwsgi_unix_signal(SIGQUIT, royal_death);
|
||||
uwsgi_unix_signal(SIGUSR1, emperor_stats);
|
||||
|
||||
memset(&ui_base, 0, sizeof(struct uwsgi_instance));
|
||||
|
||||
@@ -395,6 +459,7 @@ reconnect:
|
||||
uwsgi_error("glob()");
|
||||
exit(1);
|
||||
}
|
||||
emperor_absolute_dir = realpath(".", NULL);
|
||||
}
|
||||
|
||||
ui = &ui_base;
|
||||
@@ -512,6 +577,15 @@ reconnect:
|
||||
|
||||
// TODO post-start hook
|
||||
}
|
||||
else if (byte == 22) {
|
||||
emperor_stop(ui_current);
|
||||
}
|
||||
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);
|
||||
free(zerg_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -643,7 +717,7 @@ reconnect:
|
||||
emperor_del(ui_current);
|
||||
break;
|
||||
}
|
||||
else if (!ui_current->use_config && strncmp(ui_current->name, "http://",7) && stat(ui_current->name, &st)) {
|
||||
else if (!ui_current->use_config && strncmp(ui_current->name, "http://",7) && stat(ui_current->name, &st) && !ui_current->zerg) {
|
||||
emperor_stop(ui_current);
|
||||
}
|
||||
else if (ui_current->pid == diedpid) {
|
||||
|
||||
@@ -820,8 +820,6 @@ int event_queue_add_timer(int eq, int *id, int sec) {
|
||||
*id = timer_id ;
|
||||
timer_id++;
|
||||
|
||||
uwsgi_log("registering timer %d\n", sec);
|
||||
|
||||
EV_SET(&kev, *id, EVFILT_TIMER, EV_ADD, 0, sec*1000, 0);
|
||||
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
||||
uwsgi_error("kevent()");
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import uwsgi
|
||||
uwsgi.cache_set('/', "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\nHello World from cache")
|
||||
def application(env, start_response):
|
||||
start_response('200 OK', [('Content-Type', 'text/html')])
|
||||
return "<h1>Hello World</h1>"
|
||||
@@ -67,6 +67,11 @@ char *ini_get_line(char *ini, off_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
// check if it is a stupid file without \n at the end
|
||||
if (ptr > ini) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
@@ -102,7 +107,9 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_log("[uWSGI] getting INI configuration from %s\n", file);
|
||||
if (file[0] != 0) {
|
||||
uwsgi_log("[uWSGI] getting INI configuration from %s\n", file);
|
||||
}
|
||||
|
||||
ini = uwsgi_open_and_read(file, &len, 1, magic_table);
|
||||
|
||||
@@ -143,6 +150,11 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
colon[0] = ':';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -72,6 +72,7 @@ void *simple_loop(void *arg1) {
|
||||
|
||||
if (uwsgi.signal_socket > -1) {
|
||||
event_queue_add_fd_read(main_queue, uwsgi.signal_socket);
|
||||
event_queue_add_fd_read(main_queue, uwsgi.my_signal_socket);
|
||||
}
|
||||
|
||||
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
@@ -115,7 +116,7 @@ void *zeromq_loop(void *arg1) {
|
||||
|
||||
struct wsgi_request *wsgi_req = uwsgi.wsgi_requests[core_id];
|
||||
uwsgi.zeromq_recv_flag = 0;
|
||||
zmq_pollitem_t zmq_poll_items[2];
|
||||
zmq_pollitem_t zmq_poll_items[3];
|
||||
char uwsgi_signal;
|
||||
|
||||
if (uwsgi.threads > 1) {
|
||||
@@ -159,6 +160,10 @@ void *zeromq_loop(void *arg1) {
|
||||
zmq_poll_items[1].socket = NULL;
|
||||
zmq_poll_items[1].fd = uwsgi.signal_socket;
|
||||
zmq_poll_items[1].events = ZMQ_POLLIN;
|
||||
|
||||
zmq_poll_items[2].socket = NULL;
|
||||
zmq_poll_items[2].fd = uwsgi.my_signal_socket;
|
||||
zmq_poll_items[2].events = ZMQ_POLLIN;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +176,7 @@ void *zeromq_loop(void *arg1) {
|
||||
|
||||
|
||||
if (uwsgi.signal_socket > -1) {
|
||||
if (zmq_poll(zmq_poll_items, 2, -1) < 0) {
|
||||
if (zmq_poll(zmq_poll_items, 3, -1) < 0) {
|
||||
uwsgi_error("zmq_poll()");
|
||||
continue;
|
||||
}
|
||||
@@ -184,7 +189,9 @@ void *zeromq_loop(void *arg1) {
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -192,6 +199,26 @@ void *zeromq_loop(void *arg1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zmq_poll_items[2].revents & ZMQ_POLLIN) {
|
||||
if (read(uwsgi.my_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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (zmq_poll_items[0].revents & ZMQ_POLLIN) {
|
||||
wsgi_req->poll.fd = wsgi_req->socket->proto_accept(wsgi_req, uwsgi.zmq_socket->fd);
|
||||
}
|
||||
|
||||
@@ -188,6 +188,18 @@ void get_linux_tcp_info(int fd) {
|
||||
}
|
||||
|
||||
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS] = uwsgi.shared->ti.tcpi_unacked;
|
||||
if (uwsgi.vassal_sos_backlog > 0 && uwsgi.has_emperor) {
|
||||
if ((int)uwsgi.shared->ti.tcpi_unacked >= uwsgi.vassal_sos_backlog) {
|
||||
// ask emperor for help
|
||||
char byte = 30;
|
||||
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("asking emperor for reinforcements (backlog: %d)...\n", (int) uwsgi.shared->ti.tcpi_unacked);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uwsgi.shared->ti.tcpi_unacked >= uwsgi.shared->ti.tcpi_sacked) {
|
||||
uwsgi_log_verbose("*** uWSGI listen queue of socket %d full !!! (%d/%d) ***\n", fd, uwsgi.shared->ti.tcpi_unacked, uwsgi.shared->ti.tcpi_sacked);
|
||||
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_ERRORS]++;
|
||||
@@ -976,7 +988,9 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("received uwsgi signal %d from a worker\n", uwsgi_signal);
|
||||
#endif
|
||||
uwsgi_route_signal(uwsgi_signal);
|
||||
}
|
||||
else {
|
||||
@@ -1026,6 +1040,21 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
else if (uwsgi.current_time - last_request_timecheck > uwsgi.idle) {
|
||||
uwsgi_log("workers have been inactive for more than %d seconds\n", uwsgi.idle);
|
||||
uwsgi.cheap = 1;
|
||||
master_has_children = 0;
|
||||
if (uwsgi.die_on_idle) {
|
||||
if (uwsgi.has_emperor) {
|
||||
char byte = 22;
|
||||
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
kill_them_all(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
kill_them_all(0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].pid == 0) continue;
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
@@ -1033,8 +1062,6 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("waitpid()");
|
||||
}
|
||||
}
|
||||
master_has_children = 0;
|
||||
uwsgi.cheap = 1;
|
||||
uwsgi_add_sockets_to_queue(uwsgi.master_queue);
|
||||
uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
|
||||
last_request_timecheck = 0;
|
||||
|
||||
+38
-8
@@ -37,12 +37,19 @@ int uwsgi_respawn_worker(int wid) {
|
||||
int respawns = uwsgi.workers[wid].respawn_count;
|
||||
int i;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
if (uwsgi.signal_pipe[wid][0] != -1) close(uwsgi.signal_pipe[wid][0]);
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.signal_pipe[wid])) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid == 0) {
|
||||
uwsgi.mywid = wid;
|
||||
// fix the communication pipe
|
||||
close(uwsgi.shared->worker_signal_pipe[0]);
|
||||
uwsgi.mypid = getpid();
|
||||
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
|
||||
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
|
||||
@@ -53,12 +60,32 @@ int uwsgi_respawn_worker(int wid) {
|
||||
uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
|
||||
|
||||
if (uwsgi.master_process && (uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
// close the cache server
|
||||
if (uwsgi.cache_server_fd != -1) {
|
||||
close(uwsgi.cache_server_fd);
|
||||
}
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
// fix the communication pipe
|
||||
close(uwsgi.shared->worker_signal_pipe[0]);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.signal_pipe[i][0] != -1) {
|
||||
close(uwsgi.signal_pipe[i][0]);
|
||||
}
|
||||
}
|
||||
uwsgi.my_signal_socket = uwsgi.signal_pipe[wid][1];
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
|
||||
}
|
||||
#endif
|
||||
if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -66,6 +93,9 @@ int uwsgi_respawn_worker(int wid) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.signal_pipe[wid][1]);
|
||||
}
|
||||
if (respawns > 0) {
|
||||
uwsgi_log("Respawned uWSGI worker %d (new pid: %d)\n", wid, (int) pid);
|
||||
}
|
||||
|
||||
Vendored
+3
@@ -9,6 +9,9 @@ void cache_command(char *key, uint16_t keylen, char *val, uint16_t vallen, void
|
||||
if (!uwsgi_strncmp(key, keylen, "key", 3)) {
|
||||
val = uwsgi_cache_get(val, vallen, &tmp_vallen);
|
||||
if (val && tmp_vallen > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("cache value size: %llu\n", tmp_vallen);
|
||||
#endif
|
||||
wsgi_req->response_size = wsgi_req->socket->proto_write(wsgi_req, val, tmp_vallen);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
class FakeClass {
|
||||
|
||||
public:
|
||||
char *foobar;
|
||||
uint16_t foobar_len;
|
||||
void hello_world(struct wsgi_request *);
|
||||
|
||||
};
|
||||
|
||||
void FakeClass::hello_world(struct wsgi_request *wsgi_req) {
|
||||
|
||||
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, (char *) "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n", 44);
|
||||
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, foobar, foobar_len);
|
||||
}
|
||||
|
||||
extern "C" int uwsgi_cplusplus_init(){
|
||||
uwsgi_log("Initializing example c++ plugin\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int uwsgi_cplusplus_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
FakeClass *fc;
|
||||
|
||||
// empty request ?
|
||||
if (!wsgi_req->uh.pktsize) {
|
||||
uwsgi_log( "Invalid request. skip.\n");
|
||||
goto clear;
|
||||
}
|
||||
|
||||
// get uwsgi variables
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
uwsgi_log("Invalid request. skip.\n");
|
||||
goto clear;
|
||||
}
|
||||
|
||||
fc = new FakeClass();
|
||||
// get PATH_INFO
|
||||
fc->foobar = uwsgi_get_var(wsgi_req, (char *) "PATH_INFO", &fc->foobar_len);
|
||||
|
||||
if (fc->foobar) {
|
||||
// send output
|
||||
fc->hello_world(wsgi_req);
|
||||
}
|
||||
|
||||
delete fc;
|
||||
|
||||
clear:
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void uwsgi_cplusplus_after_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("logging c++ request\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
|
||||
int uwsgi_cplusplus_init(void);
|
||||
int uwsgi_cplusplus_request(struct wsgi_request *);
|
||||
void uwsgi_cplusplus_after_request(struct wsgi_request *);
|
||||
|
||||
struct uwsgi_plugin cplusplus_plugin = {
|
||||
|
||||
.name = "cplusplus",
|
||||
.modifier1 = 250,
|
||||
.init = uwsgi_cplusplus_init,
|
||||
.request = uwsgi_cplusplus_request,
|
||||
.after_request = uwsgi_cplusplus_after_request,
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='cplusplus'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lstdc++']
|
||||
GCC_LIST = ['base.cc', 'plugin']
|
||||
@@ -2,21 +2,33 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_init(char *args){
|
||||
uwsgi_log("i am the example plugin initialization function with arg: %s\n", args);
|
||||
int uwsgi_example_init(){
|
||||
uwsgi_log("i am the example plugin initialization function\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_request(struct wsgi_request *wsgi_req) {
|
||||
int uwsgi_example_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
char *http = "HTTP/1.1 200 Ok\r\nContent-type: text/html\r\n\r\n<h1>Hello World</h1>";
|
||||
|
||||
wsgi_req->response_size += wsgi_req->socket_proto_write(wsgi_req, http, strlen(http));
|
||||
wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, http, strlen(http));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_after_request(struct wsgi_request *wsgi_req) {
|
||||
void uwsgi_example_after_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("i am the example plugin after request function\n");
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_plugin example_plugin = {
|
||||
|
||||
.name = "example",
|
||||
.modifier1 = 250,
|
||||
.init = uwsgi_example_init,
|
||||
.request = uwsgi_example_request,
|
||||
.after_request = uwsgi_example_after_request,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
NAME='example'
|
||||
CFLAGS = ''
|
||||
LDFLAGS = ''
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['example_plugin']
|
||||
|
||||
@@ -512,6 +512,10 @@ void fastrouter_loop() {
|
||||
iov[1].iov_base = fr_session->buffer;
|
||||
iov[1].iov_len = fr_session->uh.pktsize;
|
||||
|
||||
// increment node requests counter
|
||||
if (fr_session->un)
|
||||
fr_session->un->requests++;
|
||||
|
||||
// fd passing: PERFORMANCE EXTREME BOOST !!!
|
||||
if (fr_session->pass_fd && !uwsgi.no_fd_passing) {
|
||||
msg.msg_name = NULL;
|
||||
@@ -567,6 +571,10 @@ void fastrouter_loop() {
|
||||
close_session(fr_table, fr_session);
|
||||
break;
|
||||
}
|
||||
|
||||
// update transfer statistics
|
||||
if (fr_session->un)
|
||||
fr_session->un->transferred += len;
|
||||
}
|
||||
// body from client
|
||||
else if (interesting_fd == fr_session->fd) {
|
||||
|
||||
+1
-3
@@ -869,9 +869,7 @@ int http_init() {
|
||||
if (!uhttp.nevents) uhttp.nevents = 64;
|
||||
|
||||
if (!uhttp.base && !uhttp.use_cache && !uhttp.to && !uwsgi.sockets && !uhttp.subscription_server && !uhttp.use_cluster) {
|
||||
char *rand_name = uwsgi_malloc(64);
|
||||
snprintf(rand_name, 64, "%d_%d.sock", (int) time(NULL), (int) getpid());
|
||||
uwsgi.sockets = uwsgi_new_socket(rand_name);
|
||||
uwsgi_new_socket(uwsgi_concat2("127.0.0.1:0", ""));
|
||||
}
|
||||
|
||||
uhttp.server = bind_to_tcp(uhttp.socket_name, uwsgi.listen_queue, strchr(uhttp.socket_name,':'));
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
extern char **environ;
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#ifdef __APPLE__
|
||||
extern struct uwsgi_perl uperl;
|
||||
#else
|
||||
struct uwsgi_perl uperl;
|
||||
#endif
|
||||
|
||||
struct option uwsgi_perl_options[] = {
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ XS(XS_wait_fd_write) {
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
async_add_fd_read(wsgi_req, fd, timeout);
|
||||
async_add_fd_write(wsgi_req, fd, timeout);
|
||||
}
|
||||
|
||||
wsgi_req->async_force_again = 1;
|
||||
|
||||
+123
-36
@@ -21,6 +21,11 @@ struct option uwsgi_python_options[] = {
|
||||
{"pythonpath", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"python-path", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"pymodule-alias", required_argument, 0, LONG_ARGS_PYMODULE_ALIAS},
|
||||
{"post-pymodule-alias", required_argument, 0, LONG_ARGS_POST_PYMODULE_ALIAS},
|
||||
{"import", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"pyimport", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"py-import", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"python-import", required_argument, 0, LONG_ARGS_PYIMPORT},
|
||||
{"pp", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"pyargv", required_argument, 0, LONG_ARGS_PYARGV},
|
||||
{"optimize", required_argument, 0, 'O'},
|
||||
@@ -190,7 +195,7 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
char *real_filename = filename;
|
||||
|
||||
|
||||
if (strncmp(filename, "http://", 7)) {
|
||||
if (strncmp(filename, "http://", 7) && strncmp(filename, "sym://", 6)) {
|
||||
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
@@ -496,6 +501,11 @@ void init_uwsgi_embedded_module() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(up.embedded_dict, "has_threads", PyInt_FromLong(uwsgi.has_threads))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(up.embedded_dict, "cores", PyInt_FromLong(uwsgi.cores))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
@@ -508,39 +518,6 @@ void init_uwsgi_embedded_module() {
|
||||
}
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_NULL", PyInt_FromLong(KIND_NULL))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_WORKER", PyInt_FromLong(KIND_WORKER))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_EVENT", PyInt_FromLong(KIND_EVENT))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_SPOOLER", PyInt_FromLong(KIND_SPOOLER))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_ERLANG", PyInt_FromLong(KIND_ERLANG))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_PROXY", PyInt_FromLong(KIND_PROXY))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (PyDict_SetItemString(up.embedded_dict, "KIND_MASTER", PyInt_FromLong(KIND_MASTER))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject *py_opt_dict = PyDict_New();
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (PyDict_Contains(py_opt_dict, PyString_FromString(uwsgi.exported_opts[i]->key))) {
|
||||
@@ -720,6 +697,12 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
uwsgi_log("you can specify at most %d --pymodule-alias options\n", MAX_PYMODULE_ALIAS);
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_PYIMPORT:
|
||||
uwsgi_string_new_list(&up.import_list, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_POST_PYMODULE_ALIAS:
|
||||
uwsgi_string_new_list(&up.post_pymodule_alias, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_PYTHONPATH:
|
||||
if (glob(optarg, GLOB_MARK, NULL, &g)) {
|
||||
uwsgi_string_new_list(&up.python_path, optarg);
|
||||
@@ -780,18 +763,55 @@ int uwsgi_python_mount_app(char *mountpoint, char *app) {
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_pythonize(char *orig) {
|
||||
|
||||
char *name = uwsgi_concat2(orig, "");
|
||||
size_t i;
|
||||
size_t len = 0;
|
||||
|
||||
if (!strncmp(name, "sym://", 6)) {
|
||||
name+=6;
|
||||
}
|
||||
else if (!strncmp(name, "http://", 7)) {
|
||||
name+=7;
|
||||
}
|
||||
|
||||
len = strlen(name);
|
||||
for(i=0;i<len;i++) {
|
||||
if (name[i] == '/') {
|
||||
name[i] = '.';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((name[len-3] == '.' || name[len-3] == '_') && name[len-2] == 'p' && name[len-1] == 'y') {
|
||||
name[len-3] = 0;
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_init_apps() {
|
||||
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
|
||||
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
|
||||
}
|
||||
|
||||
init_pyargv();
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
init_uwsgi_embedded_module();
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef PYTHREE
|
||||
uwsgi_init_symbol_import();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (up.test_module != NULL) {
|
||||
if (PyImport_ImportModule(up.test_module)) {
|
||||
exit(0);
|
||||
@@ -814,6 +834,56 @@ void uwsgi_python_init_apps() {
|
||||
up.loaders[LOADER_STRING_CALLABLE] = uwsgi_string_callable_loader;
|
||||
|
||||
|
||||
struct uwsgi_string_list *upli = up.import_list;
|
||||
while(upli) {
|
||||
if (strchr(upli->value, '/') || uwsgi_endswith(upli->value, ".py")) {
|
||||
uwsgi_pyimport_by_filename(uwsgi_pythonize(upli->value), upli->value);
|
||||
}
|
||||
else {
|
||||
if (PyImport_ImportModule(upli->value) == NULL) {
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
upli = upli->next;
|
||||
}
|
||||
|
||||
struct uwsgi_string_list *uppa = up.post_pymodule_alias;
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
PyObject *tmp_module;
|
||||
while(uppa) {
|
||||
// split key=value
|
||||
char *value = strchr(uppa->value, '=');
|
||||
if (!value) {
|
||||
uwsgi_log("invalid pymodule-alias syntax\n");
|
||||
continue;
|
||||
}
|
||||
value[0] = 0;
|
||||
if (!strchr(value + 1, '/')) {
|
||||
// this is a standard pymodule
|
||||
tmp_module = PyImport_ImportModule(value + 1);
|
||||
if (!tmp_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(modules, uppa->value, tmp_module);
|
||||
}
|
||||
else {
|
||||
// this is a filepath that need to be mapped
|
||||
tmp_module = uwsgi_pyimport_by_filename(uppa->value, value + 1);
|
||||
if (!tmp_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
uwsgi_log("mapped virtual pymodule \"%s\" to real pymodule \"%s\"\n", uppa->value, value + 1);
|
||||
// reset original value
|
||||
value[0] = '=';
|
||||
|
||||
uppa = uppa->next;
|
||||
}
|
||||
|
||||
|
||||
if (up.wsgi_config != NULL) {
|
||||
init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, up.main_thread);
|
||||
}
|
||||
@@ -1032,9 +1102,12 @@ void uwsgi_python_add_item(char *key, uint16_t keylen, char *val, uint16_t valle
|
||||
PyDict_SetItem(pydict, PyString_FromStringAndSize(key, keylen), PyString_FromStringAndSize(val, vallen));
|
||||
}
|
||||
|
||||
int uwsgi_python_spooler(char *buf, uint16_t len) {
|
||||
int uwsgi_python_spooler(char *filename, char *buf, uint16_t len, char *body, size_t body_len) {
|
||||
|
||||
static int random_seed_reset = 0;
|
||||
|
||||
UWSGI_GET_GIL;
|
||||
|
||||
PyObject *spool_dict = PyDict_New();
|
||||
PyObject *spool_func, *pyargs, *ret;
|
||||
|
||||
@@ -1045,37 +1118,51 @@ int uwsgi_python_spooler(char *buf, uint16_t len) {
|
||||
|
||||
if (!up.embedded_dict) {
|
||||
// ignore
|
||||
UWSGI_RELEASE_GIL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
spool_func = PyDict_GetItemString(up.embedded_dict, "spooler");
|
||||
if (!spool_func) {
|
||||
// ignore
|
||||
UWSGI_RELEASE_GIL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uwsgi_hooked_parse(buf, len, uwsgi_python_add_item, spool_dict)) {
|
||||
// malformed packet, destroy it
|
||||
UWSGI_RELEASE_GIL;
|
||||
return -2;
|
||||
}
|
||||
|
||||
pyargs = PyTuple_New(1);
|
||||
|
||||
PyDict_SetItemString(spool_dict, "spooler_task_name", PyString_FromString(filename));
|
||||
|
||||
if (body && body_len > 0) {
|
||||
PyDict_SetItemString(spool_dict, "body", PyString_FromStringAndSize(body, body_len));
|
||||
}
|
||||
PyTuple_SetItem(pyargs, 0, spool_dict);
|
||||
|
||||
ret = python_call(spool_func, pyargs, 0);
|
||||
if (ret) {
|
||||
if (!PyInt_Check(ret)) {
|
||||
// error, retry
|
||||
UWSGI_RELEASE_GIL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PyInt_AsLong(ret);
|
||||
int retval = (int) PyInt_AsLong(ret);
|
||||
UWSGI_RELEASE_GIL;
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
|
||||
// error, retry
|
||||
UWSGI_RELEASE_GIL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
#include "uwsgi_python.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
|
||||
struct _symimporter {
|
||||
PyObject_HEAD;
|
||||
} uwsgi_symbol_importer_object;
|
||||
|
||||
static char *symbolize(char *name) {
|
||||
|
||||
char *base = uwsgi_concat2(name, "");
|
||||
char *ptr = base;
|
||||
while(*ptr != 0) {
|
||||
if (*ptr == '.') {
|
||||
*ptr = '_';
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
static char *name_to_symbol_module(char *name, char *what) {
|
||||
|
||||
char *symbol = uwsgi_concat4("_binary_", name, "_py_", what);
|
||||
char *sym_ptr_start = dlsym(RTLD_DEFAULT, symbol);
|
||||
free(symbol);
|
||||
return sym_ptr_start;
|
||||
}
|
||||
|
||||
static char *name_to_symbol_pkg(char *name, char *what) {
|
||||
|
||||
char *symbol = uwsgi_concat4("_binary_", name, "___init___py_", what);
|
||||
char *sym_ptr_start = dlsym(RTLD_DEFAULT, symbol);
|
||||
free(symbol);
|
||||
return sym_ptr_start;
|
||||
}
|
||||
|
||||
static PyObject* symimporter_find_module(PyObject *self, PyObject *args) {
|
||||
|
||||
char *fullname;
|
||||
PyObject *path = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|O:find_module", &fullname, &path)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *fullname2 = symbolize(fullname);
|
||||
|
||||
char *code_start = name_to_symbol_module(fullname2, "start");
|
||||
if (code_start) {
|
||||
free(fullname2);
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
}
|
||||
code_start = name_to_symbol_pkg(fullname2, "start");
|
||||
if (code_start) {
|
||||
free(fullname2);
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
free(fullname2);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject* symimporter_load_module(PyObject *self, PyObject *args) {
|
||||
|
||||
char *code_start;
|
||||
char *code_end;
|
||||
char *fullname;
|
||||
char *source;
|
||||
char *modname;
|
||||
PyObject *code;
|
||||
if (!PyArg_ParseTuple(args, "s:load_module", &fullname)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *fullname2 = symbolize(fullname);
|
||||
|
||||
code_start = name_to_symbol_module(fullname2, "start");
|
||||
if (code_start) {
|
||||
code_end = name_to_symbol_module(fullname2, "end");
|
||||
if (code_end) {
|
||||
PyObject *mod = PyImport_AddModule(fullname);
|
||||
if (!mod) goto clear;
|
||||
PyObject *dict = PyModule_GetDict(mod);
|
||||
if (!dict) goto clear;
|
||||
|
||||
PyDict_SetItemString(dict, "__loader__", self);
|
||||
|
||||
source = uwsgi_concat2n(code_start, code_end-code_start, "", 0);
|
||||
modname = uwsgi_concat3("sym://", fullname2, "_py");
|
||||
|
||||
code = Py_CompileString(source, modname, Py_file_input);
|
||||
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
|
||||
|
||||
Py_DECREF(code);
|
||||
free(source);
|
||||
free(modname);
|
||||
free(fullname2);
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
code_start = name_to_symbol_pkg(fullname2, "start");
|
||||
if (code_start) {
|
||||
code_end = name_to_symbol_pkg(fullname2, "end");
|
||||
if (code_end) {
|
||||
PyObject *mod = PyImport_AddModule(fullname);
|
||||
if (!mod) goto clear;
|
||||
PyObject *dict = PyModule_GetDict(mod);
|
||||
if (!dict) goto clear;
|
||||
|
||||
source = uwsgi_concat2n(code_start, code_end-code_start, "", 0);
|
||||
modname = uwsgi_concat3("sym://", symbolize(fullname), "___init___py");
|
||||
|
||||
PyObject *pkgpath = Py_BuildValue("[O]", PyString_FromString(modname));
|
||||
|
||||
PyDict_SetItemString(dict, "__path__", pkgpath);
|
||||
PyDict_SetItemString(dict, "__loader__", self);
|
||||
|
||||
code = Py_CompileString(source, modname, Py_file_input);
|
||||
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
|
||||
|
||||
Py_DECREF(code);
|
||||
free(source);
|
||||
free(modname);
|
||||
free(fullname2);
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
clear:
|
||||
free(fullname2);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyMethodDef symimporter_methods[] = {
|
||||
{"find_module", symimporter_find_module, METH_VARARGS},
|
||||
{"load_module", symimporter_load_module, METH_VARARGS},
|
||||
};
|
||||
|
||||
static void uwsgi_symimporter_free(struct _symimporter *self) {
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
|
||||
static PyTypeObject SymImporter_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"uwsgi.SymbolsImporter",
|
||||
sizeof(struct _symimporter),
|
||||
0, /* tp_itemsize */
|
||||
(destructor) uwsgi_symimporter_free, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT,
|
||||
"uwsgi symbols importer", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
symimporter_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
PyType_GenericAlloc, /* tp_alloc */
|
||||
PyType_GenericNew, /* tp_new */
|
||||
PyObject_GC_Del, /* tp_free */
|
||||
};
|
||||
|
||||
int uwsgi_init_symbol_import() {
|
||||
|
||||
|
||||
if (PyType_Ready(&SymImporter_Type) < 0) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("unable to initialize symbols importer module\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject *uwsgi_em = PyImport_ImportModule("uwsgi");
|
||||
if (!uwsgi_em) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("unable to get uwsgi module\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyModule_AddObject(uwsgi_em, "SymbolsImporter",
|
||||
(PyObject *)&SymImporter_Type) < 0) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("unable to initialize symbols importer object\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
+189
-23
@@ -2,16 +2,74 @@
|
||||
|
||||
#include "uwsgi_python.h"
|
||||
|
||||
char *spool_buffer = NULL;
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
||||
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
int wait_for_specific_signal = 0;
|
||||
uint8_t uwsgi_signal = 0;
|
||||
uint8_t received_signal;
|
||||
int ret;
|
||||
struct pollfd pfd[2];
|
||||
|
||||
wsgi_req->signal_received = -1;
|
||||
|
||||
if (PyTuple_Size(args) > 0) {
|
||||
if (!PyArg_ParseTuple(args, "|B:", &uwsgi_signal)) {
|
||||
return NULL;
|
||||
}
|
||||
wait_for_specific_signal = 1;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi.async > 1) {
|
||||
wsgi_req->sigwait = 1;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
pfd[0].fd = uwsgi.signal_socket;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = uwsgi.my_signal_socket;
|
||||
pfd[1].events = POLLIN;
|
||||
cycle:
|
||||
ret = poll(pfd, 2, -1);
|
||||
if (ret > 0) {
|
||||
if (pfd[0].revents == POLLIN) {
|
||||
if (read(uwsgi.signal_socket, &received_signal, 1) != 1) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
if (uwsgi_signal_handler(received_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on worker %d\n", received_signal, uwsgi.mywid);
|
||||
}
|
||||
wsgi_req->signal_received = received_signal;
|
||||
if (wait_for_specific_signal) {
|
||||
if (received_signal != uwsgi_signal) goto cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pfd[1].revents == POLLIN) {
|
||||
if (read(uwsgi.my_signal_socket, &received_signal, 1) != 1) {
|
||||
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);
|
||||
}
|
||||
wsgi_req->signal_received = received_signal;
|
||||
if (wait_for_specific_signal) {
|
||||
if (received_signal != uwsgi_signal) goto cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
}
|
||||
#endif
|
||||
|
||||
wsgi_req->sigwait = 1;
|
||||
|
||||
return PyString_FromString("");
|
||||
}
|
||||
@@ -460,6 +518,22 @@ PyObject *py_uwsgi_attach_daemon(PyObject * self, PyObject * args) {
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_signal_registered(PyObject * self, PyObject * args) {
|
||||
uint8_t uwsgi_signal;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "B:signal_registered", &uwsgi_signal)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi_signal_registered(uwsgi_signal)) {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
@@ -879,14 +953,13 @@ PyObject *py_uwsgi_log(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
|
||||
|
||||
// the spooler, the master process or single process environment cannot lock resources
|
||||
// the spooler cannot lock resources
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.numproc > 1 && uwsgi.mypid != uwsgi.workers[0].pid && uwsgi.mypid != uwsgi.shared->spooler_pid) {
|
||||
#else
|
||||
if (uwsgi.numproc > 1 && uwsgi.mypid != uwsgi.workers[0].pid) {
|
||||
#endif
|
||||
uwsgi_lock(uwsgi.user_lock);
|
||||
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
|
||||
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
||||
}
|
||||
#endif
|
||||
uwsgi_lock(uwsgi.user_lock);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
@@ -894,12 +967,47 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
|
||||
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
|
||||
}
|
||||
#endif
|
||||
|
||||
uwsgi_unlock(uwsgi.user_lock);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
|
||||
|
||||
char *name;
|
||||
char *symbol;
|
||||
void *sym_ptr_start = NULL;
|
||||
void *sym_ptr_end = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:embedded_data", &name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
symbol = uwsgi_concat3("_binary_", name, "_start");
|
||||
sym_ptr_start = dlsym(RTLD_DEFAULT, symbol);
|
||||
free(symbol);
|
||||
if (!sym_ptr_start)
|
||||
return PyErr_Format(PyExc_ValueError, "unable to find symbol %s", name);
|
||||
|
||||
|
||||
|
||||
symbol = uwsgi_concat3("_binary_", name, "_end");
|
||||
sym_ptr_end = dlsym(RTLD_DEFAULT, symbol);
|
||||
free(symbol);
|
||||
if (!sym_ptr_end)
|
||||
return PyErr_Format(PyExc_ValueError, "unable to find symbol %s", name);
|
||||
|
||||
return PyString_FromStringAndSize(sym_ptr_start, sym_ptr_end - sym_ptr_start);
|
||||
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_sharedarea_inclong(PyObject * self, PyObject * args) {
|
||||
int pos = 0;
|
||||
long value = 0;
|
||||
@@ -1139,6 +1247,11 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
|
||||
int i;
|
||||
char spool_filename[1024];
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
char *priority = NULL;
|
||||
long numprio = 0;
|
||||
time_t at = 0;
|
||||
char *body = NULL;
|
||||
size_t body_len= 0;
|
||||
|
||||
spool_dict = PyTuple_GetItem(args, 0);
|
||||
|
||||
@@ -1159,12 +1272,47 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
|
||||
return PyErr_Format(PyExc_ValueError, "The argument of spooler callable must be a dictionary");
|
||||
}
|
||||
|
||||
PyObject *pyprio = uwsgi_py_dict_get(spool_dict, "priority");
|
||||
if (pyprio) {
|
||||
if (PyInt_Check(pyprio)) {
|
||||
numprio = PyInt_AsLong(pyprio);
|
||||
uwsgi_py_dict_del(spool_dict, "priority");
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *pyat = uwsgi_py_dict_get(spool_dict, "at");
|
||||
if (pyat) {
|
||||
if (PyInt_Check(pyat)) {
|
||||
at = (time_t) PyInt_AsLong(pyat);
|
||||
uwsgi_py_dict_del(spool_dict, "at");
|
||||
}
|
||||
else if (PyLong_Check(pyat)) {
|
||||
at = (time_t) PyLong_AsLong(pyat);
|
||||
uwsgi_py_dict_del(spool_dict, "at");
|
||||
}
|
||||
else if (PyFloat_Check(pyat)) {
|
||||
at = (time_t) PyFloat_AsDouble(pyat);
|
||||
uwsgi_py_dict_del(spool_dict, "at");
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *pybody = uwsgi_py_dict_get(spool_dict, "body");
|
||||
if (pybody) {
|
||||
if (PyString_Check(pybody)) {
|
||||
body = PyString_AsString(pybody);
|
||||
body_len = PyString_Size(pybody);
|
||||
uwsgi_py_dict_del(spool_dict, "body");
|
||||
}
|
||||
}
|
||||
|
||||
spool_vars = PyDict_Items(spool_dict);
|
||||
if (!spool_vars) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
char *spool_buffer = uwsgi_malloc(UMAX16);
|
||||
|
||||
cur_buf = spool_buffer;
|
||||
|
||||
for (i = 0; i < PyList_Size(spool_vars); i++) {
|
||||
@@ -1174,12 +1322,16 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
|
||||
key = PyTuple_GetItem(zero, 0);
|
||||
val = PyTuple_GetItem(zero, 1);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("ob_type %s %s\n", key->ob_type->tp_name, val->ob_type->tp_name);
|
||||
#endif
|
||||
|
||||
if (PyString_Check(key) && PyString_Check(val)) {
|
||||
|
||||
|
||||
keysize = PyString_Size(key);
|
||||
valsize = PyString_Size(val);
|
||||
if (cur_buf + keysize + 2 + valsize + 2 <= spool_buffer + uwsgi.buffer_size) {
|
||||
if (cur_buf + keysize + 2 + valsize + 2 <= spool_buffer + UMAX16) {
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
keysize = uwsgi_swap16(keysize);
|
||||
@@ -1204,36 +1356,54 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
|
||||
}
|
||||
else {
|
||||
Py_DECREF(zero);
|
||||
return PyErr_Format(PyExc_ValueError, "spooler packet cannot be more than %d bytes", uwsgi.buffer_size);
|
||||
free(spool_buffer);
|
||||
return PyErr_Format(PyExc_ValueError, "spooler packet cannot be more than %d bytes", UMAX16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_DECREF(zero);
|
||||
free(spool_buffer);
|
||||
return PyErr_Format(PyExc_ValueError, "spooler callable dictionary must contains only strings");
|
||||
}
|
||||
}
|
||||
else {
|
||||
free(spool_buffer);
|
||||
Py_DECREF(zero);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
else {
|
||||
free(spool_buffer);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, spool_buffer, cur_buf - spool_buffer);
|
||||
if (numprio) {
|
||||
priority = uwsgi_num2str(numprio);
|
||||
}
|
||||
i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, spool_buffer, cur_buf - spool_buffer, priority, at, body, body_len);
|
||||
if (priority) {
|
||||
free(priority);
|
||||
}
|
||||
|
||||
free(spool_buffer);
|
||||
|
||||
Py_DECREF(spool_vars);
|
||||
|
||||
if (i > 0) {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
char *slash = uwsgi_get_last_char(spool_filename, '/');
|
||||
if (slash) {
|
||||
return PyString_FromString(slash+1);
|
||||
}
|
||||
return PyString_FromString(spool_filename);
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
return PyErr_Format(PyExc_ValueError, "unable to spool job");
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_spooler_pid(PyObject * self, PyObject * args) {
|
||||
return PyInt_FromLong(uwsgi.shared->spooler_pid ? uwsgi.shared->spooler_pid : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2246,6 +2416,7 @@ static PyMethodDef uwsgi_spooler_methods[] = {
|
||||
#endif
|
||||
{"set_spooler_frequency", py_uwsgi_spooler_freq, METH_VARARGS, ""},
|
||||
{"spooler_jobs", py_uwsgi_spooler_jobs, METH_VARARGS, ""},
|
||||
{"spooler_pid", py_uwsgi_spooler_pid, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
};
|
||||
#endif
|
||||
@@ -2372,6 +2543,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"register_signal", py_uwsgi_register_signal, METH_VARARGS, ""},
|
||||
{"signal", py_uwsgi_signal, METH_VARARGS, ""},
|
||||
{"signal_wait", py_uwsgi_signal_wait, METH_VARARGS, ""},
|
||||
{"signal_registered", py_uwsgi_signal_registered, METH_VARARGS, ""},
|
||||
{"signal_received", py_uwsgi_signal_received, METH_VARARGS, ""},
|
||||
{"add_file_monitor", py_uwsgi_add_file_monitor, METH_VARARGS, ""},
|
||||
{"add_timer", py_uwsgi_add_timer, METH_VARARGS, ""},
|
||||
@@ -2418,6 +2590,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"fcgi", py_uwsgi_fcgi, METH_VARARGS, ""},
|
||||
|
||||
{"parsefile", py_uwsgi_parse_file, METH_VARARGS, ""},
|
||||
{"embedded_data", py_uwsgi_embedded_data, METH_VARARGS, ""},
|
||||
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
|
||||
|
||||
{NULL, NULL},
|
||||
@@ -2760,13 +2933,6 @@ void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
spool_buffer = malloc(uwsgi.buffer_size);
|
||||
if (!spool_buffer) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
for (uwsgi_function = uwsgi_spooler_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);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#define LONG_ARGS_PYARGV LONG_ARGS_PYTHON_BASE + 3
|
||||
#define LONG_ARGS_PYMODULE_ALIAS LONG_ARGS_PYTHON_BASE + 4
|
||||
#define LONG_ARGS_RELOAD_OS_ENV LONG_ARGS_PYTHON_BASE + 5
|
||||
#define LONG_ARGS_PYIMPORT LONG_ARGS_PYTHON_BASE + 6
|
||||
#define LONG_ARGS_POST_PYMODULE_ALIAS LONG_ARGS_PYTHON_BASE + 7
|
||||
|
||||
#if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2
|
||||
#define Py_ssize_t ssize_t
|
||||
@@ -60,10 +62,14 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
|
||||
#define PyString_Concat PyBytes_Concat
|
||||
#define PyString_AsString (char *) PyBytes_AsString
|
||||
#define PyFile_FromFile(A,B,C,D) PyFile_FromFd(fileno((A)), (B), (C), -1, NULL, NULL, NULL, 0)
|
||||
#define uwsgi_py_dict_get(a, b) PyDict_GetItem(a, PyBytes_FromString(b));
|
||||
#define uwsgi_py_dict_del(a, b) PyDict_DelItem(a, PyBytes_FromString(b));
|
||||
|
||||
#else
|
||||
#define UWSGI_PYFROMSTRING(x) PyString_FromString(x)
|
||||
#define UWSGI_PYFROMSTRINGSIZE(x, y) PyString_FromStringAndSize(x, y)
|
||||
#define uwsgi_py_dict_get(a, b) PyDict_GetItemString(a, b)
|
||||
#define uwsgi_py_dict_del(a, b) PyDict_DelItemString(a, b)
|
||||
#endif
|
||||
|
||||
#define LOADER_DYN 0
|
||||
@@ -99,6 +105,8 @@ struct uwsgi_python {
|
||||
char *test_module;
|
||||
|
||||
struct uwsgi_string_list *python_path;
|
||||
struct uwsgi_string_list *import_list;
|
||||
struct uwsgi_string_list *post_pymodule_alias;
|
||||
|
||||
PyObject *loader_dict;
|
||||
PyObject* (*loaders[LOADER_MAX]) (void *);
|
||||
@@ -223,3 +231,9 @@ void simple_reset_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
int uwsgi_python_profiler_call(PyObject *, PyFrameObject *, int, PyObject *);
|
||||
|
||||
void uwsgi_python_reset_random_seed(void);
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef PYTHREE
|
||||
int uwsgi_init_symbol_import(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@ import os,sys
|
||||
from distutils import sysconfig
|
||||
|
||||
NAME='python'
|
||||
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler']
|
||||
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter']
|
||||
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ]
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -96,6 +96,10 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
|
||||
zero = PyString_FromString(uwsgi.hostname);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", zero);
|
||||
Py_DECREF(zero);
|
||||
|
||||
|
||||
#ifdef UWSGI_ROUTING
|
||||
uwsgi_log("routing %d routes %d\n", uwsgi.routing, uwsgi.nroutes);
|
||||
|
||||
@@ -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'])
|
||||
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
|
||||
|
||||
CFLAGS = os.popen('python2.4-config --cflags').read().rstrip().split()
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
|
||||
@@ -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'])
|
||||
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
|
||||
|
||||
CFLAGS = os.popen('python2.5-config --cflags').read().rstrip().split()
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
|
||||
@@ -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'])
|
||||
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
|
||||
|
||||
CFLAGS = os.popen('python2.6-config --cflags').read().rstrip().split()
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
|
||||
@@ -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'])
|
||||
GCC_LIST = map(lambda x: '../python/' + x, ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'])
|
||||
|
||||
CFLAGS = os.popen('python2.7-config --cflags').read().rstrip().split()
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
|
||||
@@ -134,6 +134,7 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) {
|
||||
|
||||
if (RARRAY_LEN(args) == 0) {
|
||||
chunk = rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, wsgi_req->post_cl-wsgi_req->buf_pos);
|
||||
wsgi_req->buf_pos += (wsgi_req->post_cl-wsgi_req->buf_pos);
|
||||
return chunk;
|
||||
}
|
||||
else if (RARRAY_LEN(args) > 0) {
|
||||
@@ -141,11 +142,12 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) {
|
||||
if (wsgi_req->buf_pos+chunk_size > wsgi_req->post_cl) {
|
||||
chunk_size = wsgi_req->post_cl-wsgi_req->buf_pos;
|
||||
}
|
||||
wsgi_req->buf_pos+=chunk_size;
|
||||
if (RARRAY_LEN(args) > 1) {
|
||||
rb_str_cat(RARRAY_PTR(args)[1], wsgi_req->post_buffering_buf+wsgi_req->buf_pos, chunk_size);
|
||||
wsgi_req->buf_pos+=chunk_size;
|
||||
return RARRAY_PTR(args)[1];
|
||||
}
|
||||
wsgi_req->buf_pos+=chunk_size;
|
||||
return rb_str_new(wsgi_req->post_buffering_buf+wsgi_req->buf_pos, chunk_size);
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -1337,3 +1337,17 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t *len) {
|
||||
|
||||
int i;
|
||||
*len = 0;
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
if (!uwsgi_strncmp(key, strlen(key), wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
|
||||
*len = wsgi_req->hvec[i + 1].iov_len;
|
||||
return wsgi_req->hvec[i + 1].iov_base;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
from threading import Thread
|
||||
import time
|
||||
|
||||
def mess():
|
||||
while True:
|
||||
for i in xrange(0, 100):
|
||||
print(i)
|
||||
time.sleep(0.1)
|
||||
|
||||
t = Thread(target=mess)
|
||||
t.daemon = True
|
||||
t.start()
|
||||
|
||||
print("thread started")
|
||||
@@ -11,10 +11,18 @@ int uwsgi_signal_handler(uint8_t sig) {
|
||||
if (!uwsgi.p[use->modifier1]->signal_handler) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
|
||||
}
|
||||
|
||||
int uwsgi_signal_registered(uint8_t sig) {
|
||||
|
||||
if (uwsgi.shared->signal_table[sig].handler != NULL)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t modifier1) {
|
||||
|
||||
struct uwsgi_signal_entry *use = NULL;
|
||||
@@ -146,6 +154,7 @@ int uwsgi_signal_add_rb_timer(uint8_t sig, int secs, int iterations) {
|
||||
|
||||
void uwsgi_route_signal(uint8_t sig) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_signal_entry *use = &ushared->signal_table[sig];
|
||||
// send to first available worker
|
||||
if (use->receiver[0] == 0 || !strcmp(use->receiver, "worker") || !strcmp(use->receiver, "worker0")) {
|
||||
@@ -156,21 +165,38 @@ void uwsgi_route_signal(uint8_t sig) {
|
||||
}
|
||||
// send to all workers
|
||||
else if (!strcmp(use->receiver, "workers")) {
|
||||
if (write(ushared->worker_signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to workers pool\n", sig);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (write(uwsgi.signal_pipe[i][0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// route to specific worker
|
||||
else if (!strncmp(use->receiver, "worker", 6)) {
|
||||
i = atoi(use->receiver+6);
|
||||
if (i > uwsgi.numproc) {
|
||||
uwsgi_log("invalid signal target: %s\n", use->receiver);
|
||||
}
|
||||
if (write(uwsgi.signal_pipe[i][0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
|
||||
}
|
||||
}
|
||||
// route to subscribed
|
||||
else if (!strcmp(use->receiver, "subscribed")) {
|
||||
}
|
||||
// route to spooler
|
||||
else if (!strcmp(use->receiver, "spooler")) {
|
||||
if (ushared->worker_signal_pipe[0] != -1) {
|
||||
if (write(ushared->spooler_signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to the spooler\n", sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// unregistered signal, sending it to all the workers
|
||||
uwsgi_log("^^^ ROUTING UNREGISTERED SIGNAL ^^^\n");
|
||||
if (write(ushared->worker_signal_pipe[0], &sig, 1) != 1) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_log("could not deliver signal %d to workers pool\n", sig);
|
||||
}
|
||||
|
||||
uwsgi_log("^^^ UNSUPPORTED SIGNAL TARGET: %s ^^^\n", use->receiver);
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import uwsgi
|
||||
from uwsgidecorators import *
|
||||
|
||||
@signal(17, target='workers')
|
||||
def hello(signum):
|
||||
print("I AM THE WORKER %d" % uwsgi.worker_id())
|
||||
|
||||
@signal(30, target='worker2')
|
||||
def hello2(signum):
|
||||
print("I AM THE WORKER 2")
|
||||
|
||||
@postfork
|
||||
def wait_for_signal():
|
||||
if uwsgi.worker_id() != 2:
|
||||
print("waiting for a signal...")
|
||||
uwsgi.signal_wait()
|
||||
print("signal %d received" % uwsgi.signal_received())
|
||||
|
||||
|
||||
def application(e, s):
|
||||
s('200 OK', [('Content-Type', 'text/html')])
|
||||
if e['PATH_INFO'] == '/30':
|
||||
uwsgi.signal(30)
|
||||
uwsgi.signal(100)
|
||||
else:
|
||||
uwsgi.signal(17)
|
||||
return "Signal raised"
|
||||
|
||||
@@ -736,6 +736,8 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) {
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
|
||||
uwsgi_sock->name = name;
|
||||
|
||||
if (!name) return uwsgi_sock;
|
||||
|
||||
char *tcp_port = strchr(name, ':');
|
||||
if (tcp_port) {
|
||||
// INET socket, check for 0 port
|
||||
@@ -769,6 +771,10 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
|
||||
union uwsgi_sockaddr usa;
|
||||
int abstract = 0;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("creating socket from fd %d\n", fd);
|
||||
#endif
|
||||
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = &usa.sa;
|
||||
if (!getsockname(fd, gsa.sa, &socket_type_len)) {
|
||||
|
||||
@@ -3,7 +3,26 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
static void spooler_readdir(char *);
|
||||
#ifdef __linux__
|
||||
static void spooler_scandir(char *);
|
||||
#endif
|
||||
void spooler_manage_task(char *, char *);
|
||||
|
||||
pid_t spooler_start() {
|
||||
|
||||
int i;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
|
||||
if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
|
||||
// setup internal signalling system
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.shared->spooler_signal_pipe)) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
@@ -11,23 +30,31 @@ pid_t spooler_start() {
|
||||
exit(1);
|
||||
}
|
||||
else if (pid == 0) {
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
close(uwsgi_sock->fd);
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
uwsgi_close_all_sockets();
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.shared->spooler_signal_pipe[0]);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.signal_pipe[i][0] != -1) {
|
||||
close(uwsgi.signal_pipe[i][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1];
|
||||
spooler();
|
||||
}
|
||||
else if (pid > 0) {
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.shared->spooler_signal_pipe[1]);
|
||||
}
|
||||
uwsgi_log("spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
void destroy_spool(char *file) {
|
||||
void destroy_spool(char *dir, char *file) {
|
||||
|
||||
if (chdir(uwsgi.spool_dir)) {
|
||||
if (chdir(dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
uwsgi_log("something horrible happened to the spooler. Better to kill it.\n");
|
||||
exit(1);
|
||||
@@ -42,7 +69,7 @@ void destroy_spool(char *file) {
|
||||
}
|
||||
|
||||
|
||||
int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
|
||||
int spool_request(char *filename, int rn, int core_id, char *buffer, int size, char *priority, time_t at, char *body, size_t body_len) {
|
||||
|
||||
struct timeval tv;
|
||||
int fd;
|
||||
@@ -52,9 +79,24 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (snprintf(filename, 1024, "%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uwsgi.spool_dir, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) {
|
||||
uwsgi_unlock(uwsgi.spooler_lock);
|
||||
return 0;
|
||||
if (priority) {
|
||||
if (snprintf(filename, 1024, "%s/%s", uwsgi.spool_dir, priority) <= 0) {
|
||||
uwsgi_unlock(uwsgi.spooler_lock);
|
||||
return 0;
|
||||
}
|
||||
// no need to check for errors...
|
||||
(void) mkdir(filename, 0777);
|
||||
|
||||
if (snprintf(filename, 1024, "%s/%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uwsgi.spool_dir, priority, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) {
|
||||
uwsgi_unlock(uwsgi.spooler_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (snprintf(filename, 1024, "%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uwsgi.spool_dir, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) {
|
||||
uwsgi_unlock(uwsgi.spooler_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
@@ -91,9 +133,30 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
|
||||
goto clear;
|
||||
}
|
||||
|
||||
if (body && body_len > 0) {
|
||||
if ((size_t)write(fd, body, body_len) != body_len) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
|
||||
if (at > 0) {
|
||||
struct timeval tv[2];
|
||||
tv[0].tv_sec = at;
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = at;
|
||||
tv[1].tv_usec = 0;
|
||||
#ifdef __sun__
|
||||
if (futimesat(fd, NULL, tv)) {
|
||||
#else
|
||||
if (futimes(fd, tv)) {
|
||||
#endif
|
||||
uwsgi_error("futimes()");
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
uwsgi_log("written %d bytes to spool file %s\n", size + 4, filename);
|
||||
uwsgi_log("written %d bytes to spool file %s\n", size + body_len + 4, filename);
|
||||
|
||||
uwsgi_unlock(uwsgi.spooler_lock);
|
||||
|
||||
@@ -111,21 +174,10 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
|
||||
|
||||
|
||||
void spooler() {
|
||||
DIR *sdir;
|
||||
struct dirent *dp;
|
||||
int i, ret;
|
||||
|
||||
|
||||
int spool_fd;
|
||||
|
||||
// prevent process blindly reading stdin to make mess
|
||||
int nullfd;
|
||||
|
||||
struct uwsgi_header uh;
|
||||
|
||||
char spool_buf[0xffff];
|
||||
|
||||
|
||||
// asked by Marco Beri
|
||||
#ifdef __HAIKU__
|
||||
#ifdef UWSGI_DEBUG
|
||||
@@ -150,6 +202,13 @@ void spooler() {
|
||||
close(nullfd);
|
||||
}
|
||||
|
||||
int spooler_event_queue = event_queue_init();
|
||||
int interesting_fd = -1;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
event_queue_add_fd_read(spooler_event_queue, uwsgi.shared->spooler_signal_pipe[1]);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
||||
|
||||
@@ -158,86 +217,193 @@ void spooler() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sdir = opendir(uwsgi.spool_dir);
|
||||
if (sdir) {
|
||||
while ((dp = readdir(sdir)) != NULL) {
|
||||
if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) {
|
||||
struct stat sf_lstat;
|
||||
if (lstat(dp->d_name, &sf_lstat)) {
|
||||
continue;
|
||||
}
|
||||
if (!S_ISREG(sf_lstat.st_mode)) {
|
||||
continue;
|
||||
}
|
||||
if (!access(dp->d_name, R_OK | W_OK)) {
|
||||
uwsgi_log("managing spool request %s ...\n", dp->d_name);
|
||||
|
||||
spool_fd = open(dp->d_name, O_RDONLY);
|
||||
if (spool_fd < 0) {
|
||||
uwsgi_error_open(dp->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef __sun__
|
||||
if (lockf(spool_fd, F_LOCK, 0)) {
|
||||
uwsgi_error("lockf()");
|
||||
#else
|
||||
if (flock(spool_fd, LOCK_EX)) {
|
||||
uwsgi_error("flock()");
|
||||
if (uwsgi.spooler_ordered) {
|
||||
#ifdef __linux__
|
||||
spooler_scandir(uwsgi.spool_dir);
|
||||
#endif
|
||||
close(spool_fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read(spool_fd, &uh, 4) != 4) {
|
||||
uwsgi_error("read()");
|
||||
close(spool_fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh.pktsize = uwsgi_swap16(uh.pktsize);
|
||||
#endif
|
||||
|
||||
|
||||
if (read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
|
||||
uwsgi_error("read()");
|
||||
destroy_spool(dp->d_name);
|
||||
close(spool_fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
close(spool_fd);
|
||||
|
||||
for(i=0;i<0xff;i++) {
|
||||
if (uwsgi.p[i]->spooler) {
|
||||
ret = uwsgi.p[i]->spooler(spool_buf, uh.pktsize);
|
||||
if (ret == 0) continue;
|
||||
if (ret == -2) {
|
||||
|
||||
uwsgi_log("done with task/spool %s\n", dp->d_name);
|
||||
destroy_spool(dp->d_name);
|
||||
}
|
||||
// re-spool it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(sdir);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("opendir()");
|
||||
spooler_readdir(uwsgi.spool_dir);
|
||||
}
|
||||
|
||||
sleep(uwsgi.shared->spooler_frequency);
|
||||
if (event_queue_wait(spooler_event_queue, uwsgi.shared->spooler_frequency, &interesting_fd) > 0) {
|
||||
if (uwsgi.master_process) {
|
||||
if (interesting_fd == uwsgi.shared->spooler_signal_pipe[1]) {
|
||||
uint8_t uwsgi_signal;
|
||||
if (read(interesting_fd, &uwsgi_signal, 1) <= 0) {
|
||||
if (uwsgi.no_orphans) {
|
||||
uwsgi_log_verbose("uWSGI spooler screams: UAAAAAAH my master died, i will follow him...\n");
|
||||
end_me(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to the spooler\n", uwsgi_signal);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on the spooler\n", uwsgi_signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static void spooler_scandir(char *dir) {
|
||||
|
||||
struct dirent **tasklist;
|
||||
int n;
|
||||
|
||||
n = scandir(dir, &tasklist, 0, versionsort);
|
||||
if (n < 0) {
|
||||
uwsgi_error("scandir()");
|
||||
return;
|
||||
}
|
||||
|
||||
while(n--) {
|
||||
spooler_manage_task(dir, tasklist[n]->d_name);
|
||||
free(tasklist[n]);
|
||||
}
|
||||
|
||||
free(tasklist);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void spooler_readdir(char *dir) {
|
||||
|
||||
DIR *sdir;
|
||||
struct dirent *dp;
|
||||
|
||||
sdir = opendir(dir);
|
||||
if (sdir) {
|
||||
while ((dp = readdir(sdir)) != NULL) {
|
||||
spooler_manage_task(dir, dp->d_name);
|
||||
}
|
||||
closedir(sdir);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("opendir()");
|
||||
}
|
||||
}
|
||||
|
||||
void spooler_manage_task(char *dir, char *task) {
|
||||
|
||||
int i, ret;
|
||||
|
||||
char spool_buf[0xffff];
|
||||
struct uwsgi_header uh;
|
||||
char *body = NULL;
|
||||
size_t body_len = 0;
|
||||
|
||||
int spool_fd;
|
||||
|
||||
if (!strncmp("uwsgi_spoolfile_on_", task, 19) || (uwsgi.spooler_ordered && is_a_number(task))) {
|
||||
struct stat sf_lstat;
|
||||
if (lstat(task, &sf_lstat)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// a spool request for the future
|
||||
if (sf_lstat.st_mtime > time(NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (S_ISDIR(sf_lstat.st_mode) && uwsgi.spooler_ordered) {
|
||||
if (chdir(task)) {
|
||||
uwsgi_error("chdir()");
|
||||
return;
|
||||
}
|
||||
char *prio_path = realpath(".", NULL);
|
||||
spooler_scandir(prio_path);
|
||||
free(prio_path);
|
||||
if (chdir(dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!S_ISREG(sf_lstat.st_mode)) {
|
||||
return;
|
||||
}
|
||||
if (!access(task, R_OK | W_OK)) {
|
||||
uwsgi_log("managing spool request %s ...\n", task);
|
||||
|
||||
spool_fd = open(task, O_RDONLY);
|
||||
if (spool_fd < 0) {
|
||||
uwsgi_error_open(task);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __sun__
|
||||
if (lockf(spool_fd, F_LOCK, 0)) {
|
||||
uwsgi_error("lockf()");
|
||||
#else
|
||||
if (flock(spool_fd, LOCK_EX)) {
|
||||
uwsgi_error("flock()");
|
||||
#endif
|
||||
close(spool_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (read(spool_fd, &uh, 4) != 4) {
|
||||
uwsgi_error("read()");
|
||||
close(spool_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh.pktsize = uwsgi_swap16(uh.pktsize);
|
||||
#endif
|
||||
|
||||
if (read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
|
||||
uwsgi_error("read()");
|
||||
destroy_spool(dir, task);
|
||||
close(spool_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
// body available ?
|
||||
if (sf_lstat.st_size > (uh.pktsize+4)) {
|
||||
body_len = sf_lstat.st_size - (uh.pktsize+4);
|
||||
body = uwsgi_malloc(body_len);
|
||||
if ((size_t)read(spool_fd, body, body_len) != body_len) {
|
||||
uwsgi_error("read()");
|
||||
destroy_spool(dir, task);
|
||||
close(spool_fd);
|
||||
free(body);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
close(spool_fd);
|
||||
|
||||
for(i=0;i<0xff;i++) {
|
||||
if (uwsgi.p[i]->spooler) {
|
||||
time_t now = time(NULL);
|
||||
ret = uwsgi.p[i]->spooler(task, spool_buf, uh.pktsize, body, body_len);
|
||||
if (body) {
|
||||
free(body);
|
||||
}
|
||||
if (ret == 0) continue;
|
||||
if (ret == -2) {
|
||||
|
||||
uwsgi_log("done with task/spool %s after %d seconds\n", task, time(NULL)-now);
|
||||
destroy_spool(dir, task);
|
||||
}
|
||||
// re-spool it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
|
||||
|
||||
@@ -251,7 +417,7 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
uwsgi_log("managing spool request...\n");
|
||||
i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize);
|
||||
i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize, NULL, 0, NULL, 0);
|
||||
wsgi_req->uh.modifier1 = 255;
|
||||
wsgi_req->uh.pktsize = 0;
|
||||
if (i > 0) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import Queue
|
||||
from threading import Thread
|
||||
import uwsgi
|
||||
|
||||
CONSUMERS = 4
|
||||
|
||||
def consumer(q):
|
||||
while True:
|
||||
item = q.get()
|
||||
print(item)
|
||||
#... DO A HEAVY TASK HERE ...
|
||||
q.task_done()
|
||||
|
||||
def spawn_consumers():
|
||||
global q
|
||||
q = Queue.Queue()
|
||||
for i in range(CONSUMERS):
|
||||
t = Thread(target=consumer,args=(q,))
|
||||
t.daemon = True
|
||||
t.start()
|
||||
print("consumer %d on worker %d started" % (i, uwsgi.worker_id()))
|
||||
|
||||
|
||||
uwsgi.post_fork_hook = spawn_consumers
|
||||
|
||||
|
||||
def application(env, start_response):
|
||||
global q
|
||||
|
||||
# we pass a copy of the env dictionary as it gets cleared after yield/return
|
||||
q.put(env.copy())
|
||||
|
||||
start_response('200 OK', [('Content-Type', 'text/html')])
|
||||
|
||||
yield "Task enqueued"
|
||||
|
||||
@@ -419,37 +419,45 @@ void internal_server_error(struct wsgi_request *wsgi_req, char *message) {
|
||||
void uwsgi_set_cgroup() {
|
||||
|
||||
char *cgroup_taskfile;
|
||||
int i;
|
||||
FILE *cgroup;
|
||||
char *cgroup_opt;
|
||||
struct uwsgi_string_list *usl, *uslo;
|
||||
|
||||
if (!uwsgi.cgroup) return;
|
||||
|
||||
if (mkdir(uwsgi.cgroup, 0700)) {
|
||||
uwsgi_log("using Linux cgroup %s\n", uwsgi.cgroup);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("created Linux cgroup %s\n", uwsgi.cgroup);
|
||||
}
|
||||
uwsgi_error("mkdir()");
|
||||
cgroup_taskfile = uwsgi_concat2(uwsgi.cgroup, "/tasks");
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(cgroup, "%d", (int) getpid()) <= 0) {
|
||||
uwsgi_log("could not set cgroup\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("moved process %d to cgroup %s\n", (int) getpid(), cgroup_taskfile);
|
||||
fclose(cgroup);
|
||||
free(cgroup_taskfile);
|
||||
usl = uwsgi.cgroup;
|
||||
|
||||
for (i = 0; i < uwsgi.cgroup_opt_cnt; i++) {
|
||||
cgroup_opt = strchr(uwsgi.cgroup_opt[i], '=');
|
||||
while(usl) {
|
||||
if (mkdir(usl->value, 0700)) {
|
||||
uwsgi_log("using Linux cgroup %s\n", usl->value);
|
||||
if (errno != EEXIST) {
|
||||
uwsgi_error("mkdir()");
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("created Linux cgroup %s\n", usl->value);
|
||||
}
|
||||
|
||||
cgroup_taskfile = uwsgi_concat2(usl->value, "/tasks");
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(cgroup, "%d", (int) getpid()) <= 0) {
|
||||
uwsgi_log("could not set cgroup\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("assigned process %d to cgroup %s\n", (int) getpid(), cgroup_taskfile);
|
||||
fclose(cgroup);
|
||||
free(cgroup_taskfile);
|
||||
|
||||
|
||||
uslo = uwsgi.cgroup_opt;
|
||||
while(uslo) {
|
||||
cgroup_opt = strchr(uslo->value, '=');
|
||||
if (!cgroup_opt) {
|
||||
cgroup_opt = strchr(uwsgi.cgroup_opt[i], ':');
|
||||
cgroup_opt = strchr(uslo->value, ':');
|
||||
if (!cgroup_opt) {
|
||||
uwsgi_log("invalid cgroup-opt syntax\n");
|
||||
exit(1);
|
||||
@@ -459,20 +467,26 @@ void uwsgi_set_cgroup() {
|
||||
cgroup_opt[0] = 0;
|
||||
cgroup_opt++;
|
||||
|
||||
cgroup_taskfile = uwsgi_concat3(uwsgi.cgroup, "/", uwsgi.cgroup_opt[i]);
|
||||
cgroup_taskfile = uwsgi_concat3(usl->value, "/", uslo->value);
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
if (cgroup) {
|
||||
if (fprintf(cgroup, "%s\n", cgroup_opt) < 0) {
|
||||
uwsgi_log("could not set cgroup option %s to %s\n", uslo->value, cgroup_opt);
|
||||
exit(1);
|
||||
}
|
||||
fclose(cgroup);
|
||||
uwsgi_log("set %s to %s\n", cgroup_opt, cgroup_taskfile);
|
||||
}
|
||||
if (fprintf(cgroup, "%s\n", cgroup_opt) < 0) {
|
||||
uwsgi_log("could not set cgroup option %s to %s\n", uwsgi.cgroup_opt[i], cgroup_opt);
|
||||
exit(1);
|
||||
}
|
||||
fclose(cgroup);
|
||||
free(cgroup_taskfile);
|
||||
|
||||
cgroup_opt[-1] = '=';
|
||||
|
||||
uslo = uslo->next;
|
||||
}
|
||||
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -754,8 +768,10 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
|
||||
char uwsgi_signal;
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
|
||||
thunder_lock;
|
||||
ret = event_queue_wait(queue, uwsgi.edge_triggered - 1, &interesting_fd);
|
||||
if (ret < 0) {
|
||||
thunder_unlock;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -764,7 +780,10 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
|
||||
if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &ret);
|
||||
#endif
|
||||
|
||||
if (uwsgi.signal_socket > -1 && interesting_fd == uwsgi.signal_socket) {
|
||||
if (uwsgi.signal_socket > -1 && (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket)) {
|
||||
|
||||
thunder_unlock;
|
||||
|
||||
if (read(interesting_fd, &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);
|
||||
@@ -794,6 +813,7 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
|
||||
if (interesting_fd == uwsgi_sock->fd || (uwsgi.edge_triggered && uwsgi_sock->edge_trigger)) {
|
||||
wsgi_req->socket = uwsgi_sock;
|
||||
wsgi_req->poll.fd = wsgi_req->socket->proto_accept(wsgi_req, interesting_fd);
|
||||
thunder_unlock;
|
||||
if (wsgi_req->poll.fd < 0) {
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret);
|
||||
@@ -828,6 +848,7 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
thunder_unlock;
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret);
|
||||
#endif
|
||||
@@ -958,13 +979,26 @@ void uwsgi_log_verbose(const char *fmt, ...) {
|
||||
int rlen = 0;
|
||||
|
||||
struct timeval tv;
|
||||
char sftime[64];
|
||||
time_t now;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
if (uwsgi.log_strftime) {
|
||||
now = time(NULL);
|
||||
rlen = strftime(sftime, 64, uwsgi.log_strftime, localtime(&now));
|
||||
memcpy(logpkt, sftime, rlen);
|
||||
memcpy(logpkt + rlen, " - ", 3);
|
||||
rlen += 3;
|
||||
}
|
||||
else {
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
memcpy(logpkt, ctime((const time_t *) &tv.tv_sec), 24);
|
||||
memcpy(logpkt + 24, " - ", 3);
|
||||
memcpy(logpkt, ctime((const time_t *) &tv.tv_sec), 24);
|
||||
memcpy(logpkt + 24, " - ", 3);
|
||||
|
||||
rlen = 24 + 3;
|
||||
}
|
||||
|
||||
|
||||
rlen = 24 + 3;
|
||||
|
||||
va_start(ap, fmt);
|
||||
rlen += vsnprintf(logpkt + rlen, 4096 - rlen, fmt, ap);
|
||||
@@ -1746,6 +1780,42 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
buffer[*size - 1] = 0;
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_EMBED_CONFIG
|
||||
else if (url[0] == 0) {
|
||||
*size = &UWSGI_EMBED_CONFIG_END-&UWSGI_EMBED_CONFIG;
|
||||
if (add_zero) {
|
||||
*size+=1;
|
||||
}
|
||||
buffer = uwsgi_malloc(*size);
|
||||
memset(buffer, 0, *size);
|
||||
memcpy(buffer, &UWSGI_EMBED_CONFIG, &UWSGI_EMBED_CONFIG_END-&UWSGI_EMBED_CONFIG);
|
||||
}
|
||||
#endif
|
||||
else if (!strncmp("sym://", url, 6)) {
|
||||
char *symbol = uwsgi_concat3("_binary_", url+6, "_start") ;
|
||||
void *sym_start_ptr = dlsym(RTLD_DEFAULT, symbol);
|
||||
if (!sym_start_ptr) {
|
||||
uwsgi_log("unable to find symbol %s\n", symbol);
|
||||
exit(1);
|
||||
}
|
||||
free(symbol);
|
||||
symbol = uwsgi_concat3("_binary_", url+6, "_end");
|
||||
void *sym_end_ptr = dlsym(RTLD_DEFAULT, symbol);
|
||||
if (!sym_end_ptr) {
|
||||
uwsgi_log("unable to find symbol %s\n", symbol);
|
||||
exit(1);
|
||||
}
|
||||
free(symbol);
|
||||
|
||||
*size = sym_end_ptr - sym_start_ptr;
|
||||
if (add_zero) {
|
||||
*size+=1;
|
||||
}
|
||||
buffer = uwsgi_malloc(*size);
|
||||
memset(buffer, 0, *size);
|
||||
memcpy(buffer, sym_start_ptr, sym_end_ptr - sym_start_ptr);
|
||||
|
||||
}
|
||||
// fallback to file
|
||||
else {
|
||||
fd = open(url, O_RDONLY);
|
||||
@@ -2284,10 +2354,9 @@ void uwsgi_sig_pause() {
|
||||
sigsuspend(&mask);
|
||||
}
|
||||
|
||||
int uwsgi_run_command_and_wait(char *command, ...) {
|
||||
|
||||
va_list ap;
|
||||
int uwsgi_run_command_and_wait(char *command, char *arg) {
|
||||
|
||||
char *argv[3];
|
||||
int waitpid_status = 0;
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
@@ -2303,11 +2372,13 @@ int uwsgi_run_command_and_wait(char *command, ...) {
|
||||
return WEXITSTATUS(waitpid_status);
|
||||
}
|
||||
|
||||
va_start(ap, command);
|
||||
execlp(command, command, ap, (char *) NULL);
|
||||
va_end(ap);
|
||||
argv[0] = command;
|
||||
argv[1] = arg;
|
||||
argv[2] = NULL;
|
||||
|
||||
uwsgi_error("execlp()");
|
||||
execvp(command, argv);
|
||||
|
||||
uwsgi_error("execvp()");
|
||||
//never here
|
||||
exit(1);
|
||||
}
|
||||
@@ -2401,16 +2472,16 @@ int *uwsgi_attach_fd(int fd, int count, char *code, size_t code_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size_t) (cmsg->cmsg_len - ((char *)CMSG_DATA(cmsg)- (char *)cmsg)) > (size_t) (sizeof(int) * (count + 1))) {
|
||||
uwsgi_log("not enough space for sockets data, consider increasing it\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = uwsgi_malloc(sizeof(int) * (count + 1));
|
||||
for(i=0;i<count+1;i++) {
|
||||
ret[i] = -1;
|
||||
}
|
||||
|
||||
if ((size_t) (cmsg->cmsg_len - ((char *)CMSG_DATA(cmsg)- (char *)cmsg)) > (size_t) (sizeof(int) * (count + 1))) {
|
||||
uwsgi_log("not enough space for sockets data, consider increasing it\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(ret, CMSG_DATA(cmsg), cmsg->cmsg_len - ((char *)CMSG_DATA(cmsg)- (char *)cmsg));
|
||||
|
||||
free(msg_control);
|
||||
@@ -2420,3 +2491,69 @@ int *uwsgi_attach_fd(int fd, int count, char *code, size_t code_len) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int uwsgi_endswith(char *str1, char *str2) {
|
||||
|
||||
size_t i;
|
||||
size_t str1len = strlen(str1);
|
||||
size_t str2len = strlen(str2);
|
||||
char *ptr;
|
||||
|
||||
if (str2len > str1len) return 0;
|
||||
|
||||
ptr = (str1 + str1len) - str2len;
|
||||
|
||||
for(i=0;i<str2len;i++) {
|
||||
if (*ptr != str2[i]) return 0;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uwsgi_chown(char *filename, char *owner) {
|
||||
|
||||
uid_t new_uid = -1;
|
||||
uid_t new_gid = -1;
|
||||
struct group *new_group = NULL;
|
||||
struct passwd *new_user = NULL;
|
||||
|
||||
char *colon = strchr(owner, ':');
|
||||
if (colon) {
|
||||
colon[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (is_a_number(owner)) {
|
||||
new_uid = atoi(owner);
|
||||
}
|
||||
else {
|
||||
new_user = getpwnam(owner);
|
||||
if (!new_user) {
|
||||
uwsgi_log("unable to find user %s\n", owner);
|
||||
exit(1);
|
||||
}
|
||||
new_uid = new_user->pw_uid;
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
colon[0] = ':';
|
||||
if (is_a_number(colon+1)) {
|
||||
new_gid = atoi(colon+1);
|
||||
}
|
||||
else {
|
||||
new_group = getgrnam(colon+1);
|
||||
if (!new_group) {
|
||||
uwsgi_log("unable to find group %s\n", colon+1);
|
||||
exit(1);
|
||||
}
|
||||
new_gid = new_group->gr_gid;
|
||||
}
|
||||
}
|
||||
|
||||
if (chown(filename, new_uid, new_gid)) {
|
||||
uwsgi_error("chown()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ static struct option long_base_options[] = {
|
||||
{"cgi-mode", no_argument, 0, 'c'},
|
||||
{"abstract-socket", no_argument, 0, 'a'},
|
||||
{"chmod-socket", optional_argument, 0, 'C'},
|
||||
{"chown-socket", required_argument, 0, LONG_ARGS_CHOWN_SOCKET},
|
||||
{"map-socket", required_argument, 0, LONG_ARGS_MAP_SOCKET},
|
||||
{"chmod", optional_argument, 0, 'C'},
|
||||
#ifdef UWSGI_THREADING
|
||||
@@ -65,12 +66,14 @@ static struct option long_base_options[] = {
|
||||
{"master", no_argument, 0, 'M'},
|
||||
{"emperor", required_argument, 0, LONG_ARGS_EMPEROR},
|
||||
{"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},
|
||||
{"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},
|
||||
{"vassal-sos-backlog", required_argument, 0, LONG_ARGS_VASSAL_SOS_BACKLOG},
|
||||
{"auto-snapshot", optional_argument, 0, LONG_ARGS_AUTO_SNAPSHOT},
|
||||
{"reload-mercy", required_argument, 0, LONG_ARGS_RELOAD_MERCY},
|
||||
{"exit-on-reload", no_argument, &uwsgi.exit_on_reload, 1},
|
||||
@@ -86,12 +89,15 @@ static struct option long_base_options[] = {
|
||||
{"cache-blocksize", required_argument, 0, LONG_ARGS_CACHE_BLOCKSIZE},
|
||||
{"cache-store", required_argument, 0, LONG_ARGS_CACHE_STORE},
|
||||
{"cache-store-sync", required_argument, 0, LONG_ARGS_CACHE_STORE_SYNC},
|
||||
{"cache-server", required_argument, 0, LONG_ARGS_CACHE_SERVER},
|
||||
{"cache-server-threads", required_argument, 0, LONG_ARGS_CACHE_SERVER_THREADS},
|
||||
{"queue", required_argument, 0, LONG_ARGS_QUEUE},
|
||||
{"queue-blocksize", required_argument, 0, LONG_ARGS_QUEUE_BLOCKSIZE},
|
||||
{"queue-store", required_argument, 0, LONG_ARGS_QUEUE_STORE},
|
||||
{"queue-store-sync", required_argument, 0, LONG_ARGS_QUEUE_STORE_SYNC},
|
||||
#ifdef UWSGI_SPOOLER
|
||||
{"spooler", required_argument, 0, 'Q'},
|
||||
{"spooler-ordered", no_argument, &uwsgi.spooler_ordered, 1},
|
||||
#endif
|
||||
{"disable-logging", no_argument, 0, 'L'},
|
||||
|
||||
@@ -185,6 +191,7 @@ static struct option long_base_options[] = {
|
||||
{"lazy", no_argument, &uwsgi.lazy, 1},
|
||||
{"cheap", no_argument, &uwsgi.cheap, 1},
|
||||
{"idle", required_argument, 0, LONG_ARGS_IDLE},
|
||||
{"die-on-idle", no_argument, &uwsgi.die_on_idle, 1},
|
||||
{"mount", required_argument, 0, LONG_ARGS_MOUNT},
|
||||
{"grunt", no_argument, &uwsgi.grunt, 1},
|
||||
{"threads", required_argument, 0, LONG_ARGS_THREADS},
|
||||
@@ -333,7 +340,9 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
magic_table['d'] = uwsgi_concat2n(magic_table['p'], magic_table['s'] - magic_table['p'], "", 0);
|
||||
if (magic_table['d'][strlen(magic_table['d'])-1] == '/') {
|
||||
tmp = magic_table['d'] + (strlen(magic_table['d']) -1) ;
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("tmp = %c\n", *tmp);
|
||||
#endif
|
||||
*tmp = 0;
|
||||
}
|
||||
if (uwsgi_get_last_char(magic_table['d'], '/'))
|
||||
@@ -806,6 +815,8 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi.master_queue = -1;
|
||||
|
||||
uwsgi.signal_socket = -1;
|
||||
uwsgi.my_signal_socket = -1;
|
||||
uwsgi.cache_server_fd = -1;
|
||||
|
||||
uwsgi.emperor_fd_config = -1;
|
||||
uwsgi.emperor_pid = -1;
|
||||
@@ -828,6 +839,11 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 4;
|
||||
uwsgi.shared->options[UWSGI_OPTION_LOGGING] = 1;
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
uwsgi.shared->spooler_signal_pipe[0] = -1;
|
||||
uwsgi.shared->spooler_signal_pipe[1] = -1;
|
||||
#endif
|
||||
|
||||
|
||||
gettimeofday(&uwsgi.start_tv, NULL);
|
||||
|
||||
@@ -898,6 +914,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
plugins_requested = getenv("UWSGI_PLUGINS");
|
||||
if (plugins_requested) {
|
||||
plugins_requested = uwsgi_concat2(plugins_requested, "");
|
||||
char *p = strtok(plugins_requested, ",");
|
||||
while (p != NULL) {
|
||||
uwsgi_load_plugin(-1, p, NULL, 0);
|
||||
@@ -906,6 +923,19 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
build_options();
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
uwsgi_error("gethostname()");
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
magic_table['v'] = uwsgi.cwd;
|
||||
magic_table['h'] = uwsgi.hostname;
|
||||
|
||||
#ifdef UWSGI_EMBED_CONFIG
|
||||
uwsgi_ini_config("", magic_table);
|
||||
#endif
|
||||
|
||||
uwsgi.option_index = -1;
|
||||
while ((i = getopt_long(argc, argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
|
||||
|
||||
@@ -993,15 +1023,6 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
uwsgi_error("gethostname()");
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
magic_table['v'] = uwsgi.cwd;
|
||||
magic_table['h'] = uwsgi.hostname;
|
||||
|
||||
#ifdef UWSGI_XML
|
||||
if (uwsgi.xml_config != NULL) {
|
||||
config_magic_table_fill(uwsgi.xml_config, magic_table);
|
||||
@@ -1349,7 +1370,7 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!uwsgi.master_as_root) {
|
||||
if (!uwsgi.master_as_root && !uwsgi.chown_socket) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
|
||||
@@ -1526,6 +1547,10 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("cores allocated...\n");
|
||||
#endif
|
||||
|
||||
|
||||
//by default set wsgi_req to the first slot
|
||||
uwsgi.wsgi_req = uwsgi.wsgi_requests[0];
|
||||
@@ -1539,6 +1564,11 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
|
||||
// event queue lock (mitigate same event on multiple queues)
|
||||
if (uwsgi.threads > 1) {
|
||||
pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
|
||||
}
|
||||
|
||||
// application generic lock
|
||||
uwsgi.user_lock = uwsgi_mmap_shared_lock();
|
||||
uwsgi_lock_init(uwsgi.user_lock);
|
||||
@@ -1610,6 +1640,10 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_log("!!! unable to attach daemon %s !!!\n", uwsgi.startup_daemons[i]);
|
||||
}
|
||||
}
|
||||
// create the cache server
|
||||
if (uwsgi.cache_server) {
|
||||
uwsgi.cache_server_fd = uwsgi_cache_server(uwsgi.cache_server, uwsgi.cache_server_threads);
|
||||
}
|
||||
}
|
||||
|
||||
/* plugin initialization */
|
||||
@@ -1626,6 +1660,9 @@ int uwsgi_start(void *v_argv) {
|
||||
if (uwsgi.is_a_reload || uwsgi.zerg) {
|
||||
|
||||
if (uwsgi.zerg) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("attaching zerg sockets...\n");
|
||||
#endif
|
||||
int zerg_fd;
|
||||
i = 0;
|
||||
for(;;) {
|
||||
@@ -1637,6 +1674,8 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_add_socket_from_fd(uwsgi_sock, zerg_fd);
|
||||
i++;
|
||||
}
|
||||
|
||||
uwsgi_log("zerg sockets attached\n");
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
@@ -1661,6 +1700,12 @@ int uwsgi_start(void *v_argv) {
|
||||
if (j == uwsgi.emperor_fd)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uwsgi.cache_server && uwsgi.cache_server_fd != -1) {
|
||||
if (j == uwsgi.cache_server_fd)
|
||||
continue;
|
||||
}
|
||||
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = (struct sockaddr *) &usa;
|
||||
if (!getsockname(j, gsa.sa, &socket_type_len)) {
|
||||
@@ -1685,6 +1730,9 @@ int uwsgi_start(void *v_argv) {
|
||||
if (tcp_port == NULL) {
|
||||
uwsgi_sock->fd = bind_to_unix(uwsgi_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
if (uwsgi.chown_socket) {
|
||||
uwsgi_chown(uwsgi_sock->name, uwsgi.chown_socket);
|
||||
}
|
||||
uwsgi_log("uwsgi socket %d bound to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
else {
|
||||
@@ -1702,6 +1750,12 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
if (uwsgi.chown_socket) {
|
||||
if (!uwsgi.master_as_root) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
}
|
||||
|
||||
int zero_used = 0;
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
@@ -1721,7 +1775,7 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_log("uwsgi socket %d inherited UNIX address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
else {
|
||||
uwsgi_sock = uwsgi_new_socket(":0");
|
||||
uwsgi_sock = uwsgi_new_socket(uwsgi_concat2(":0", ""));
|
||||
uwsgi_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
}
|
||||
@@ -1736,6 +1790,7 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1915,6 +1970,13 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
memset(uwsgi.workers, 0, sizeof(struct uwsgi_worker) * uwsgi.numproc + 1);
|
||||
|
||||
uwsgi.signal_pipe = uwsgi_malloc( sizeof(int *) * (uwsgi.numproc + 1));
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
uwsgi.signal_pipe[i] = uwsgi_malloc(sizeof(int) * 2);
|
||||
uwsgi.signal_pipe[i][0] = - 1;
|
||||
uwsgi.signal_pipe[i][1] = - 1;
|
||||
}
|
||||
|
||||
uwsgi.mypid = getpid();
|
||||
masterpid = uwsgi.mypid;
|
||||
|
||||
@@ -2017,6 +2079,14 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// master fixup
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir != NULL && uwsgi.sockets) {
|
||||
@@ -2028,13 +2098,7 @@ int uwsgi_start(void *v_argv) {
|
||||
routing_setup();
|
||||
#endif
|
||||
|
||||
// master fixup
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!uwsgi.master_process) {
|
||||
@@ -2059,6 +2123,7 @@ int uwsgi_start(void *v_argv) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.signal_socket = uwsgi.shared->worker_signal_pipe[1];
|
||||
}
|
||||
|
||||
// uWSGI is ready
|
||||
@@ -2165,6 +2230,7 @@ int uwsgi_start(void *v_argv) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.worker_exec) {
|
||||
char *w_argv[2];
|
||||
w_argv[0] = uwsgi.worker_exec;
|
||||
@@ -2298,6 +2364,8 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
uwsgi.async_queue_unused_ptr = uwsgi.async - 1;
|
||||
|
||||
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.signal_socket);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2377,16 +2445,6 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
uwsgi.signal_socket = uwsgi.shared->worker_signal_pipe[1];
|
||||
#ifdef UWSGI_ASYNC
|
||||
// add uwsgi signal fd to async queue
|
||||
if (uwsgi.async > 1) {
|
||||
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.signal_socket);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.cores > 1) {
|
||||
uwsgi.core[0]->thread_id = pthread_self();
|
||||
@@ -2518,7 +2576,7 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi.allowed_modifiers = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PLUGINS:
|
||||
p = strtok(optarg, ",");
|
||||
p = strtok(uwsgi_concat2(optarg, ""), ",");
|
||||
while (p != NULL) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("loading plugin %s\n", p);
|
||||
@@ -2576,6 +2634,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_LOGTO2:
|
||||
uwsgi.logto2 = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_EMPEROR_BROODLORD:
|
||||
uwsgi.emperor_broodlord = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_EMPEROR:
|
||||
uwsgi.emperor_dir = optarg;
|
||||
return 1;
|
||||
@@ -2697,6 +2758,10 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
return 1;
|
||||
case LONG_ARGS_CHECK_STATIC:
|
||||
uwsgi.check_static = realpath(optarg, NULL);
|
||||
if (!uwsgi.check_static) {
|
||||
uwsgi_error("check-static realpath()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.check_static_len = strlen(uwsgi.check_static);
|
||||
return 1;
|
||||
case LONG_ARGS_FILE_SERVE_MODE:
|
||||
@@ -2739,6 +2804,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uct->filename = optarg;
|
||||
uct->next = NULL;
|
||||
|
||||
return 1;
|
||||
case LONG_ARGS_VASSAL_SOS_BACKLOG:
|
||||
uwsgi.vassal_sos_backlog = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_VASSALS_START_HOOK:
|
||||
uwsgi.vassals_start_hook = optarg;
|
||||
@@ -2820,6 +2888,10 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
usm->mountpoint_len = docroot - usm->mountpoint;
|
||||
|
||||
usm->document_root = realpath(docroot + 1, NULL);
|
||||
if (!usm->document_root) {
|
||||
uwsgi_error("static-map realpath()");
|
||||
exit(1);
|
||||
}
|
||||
usm->document_root_len = strlen(usm->document_root);
|
||||
|
||||
usm->orig_document_root = usm->document_root;
|
||||
@@ -2849,16 +2921,10 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
return 1;
|
||||
#ifdef __linux__
|
||||
case LONG_ARGS_CGROUP:
|
||||
uwsgi.cgroup = optarg;
|
||||
uwsgi_string_new_list(&uwsgi.cgroup, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CGROUP_OPT:
|
||||
if (uwsgi.cgroup_opt_cnt < 63) {
|
||||
uwsgi.cgroup_opt[uwsgi.cgroup_opt_cnt] = optarg;
|
||||
uwsgi.cgroup_opt_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can specify at most 64 --cgroup_opt options\n");
|
||||
}
|
||||
uwsgi_string_new_list(&uwsgi.cgroup_opt, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_LINUX_NS:
|
||||
uwsgi.ns = optarg;
|
||||
@@ -2928,6 +2994,12 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_CHECK_INTERVAL:
|
||||
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_SERVER:
|
||||
uwsgi.cache_server = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_SERVER_THREADS:
|
||||
uwsgi.cache_server_threads = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE:
|
||||
uwsgi.cache_max_items = atoi(optarg);
|
||||
return 1;
|
||||
@@ -3103,6 +3175,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi.log_strftime = optarg;
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_CHOWN_SOCKET:
|
||||
uwsgi.chown_socket = optarg;
|
||||
return 1;
|
||||
case 'C':
|
||||
uwsgi.chmod_socket = 1;
|
||||
if (optarg) {
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ unlock()
|
||||
send()
|
||||
cl()
|
||||
req_fd()
|
||||
signal(num,[payload])
|
||||
signal(num)
|
||||
sendfile()
|
||||
set_warning_message()
|
||||
mem()
|
||||
@@ -50,6 +50,6 @@ sharedarea_writebyte
|
||||
sharedarea_readlong
|
||||
sharedarea_writelong
|
||||
sharedarea_inclong
|
||||
register_signal(num, handler)
|
||||
register_signal(num, targer, handler)
|
||||
register_rpc(name, func[,args])
|
||||
rpc(node, name[,args,...])
|
||||
|
||||
@@ -204,6 +204,13 @@ $(document).ready(function() {
|
||||
<b>cores:</b> {{ uwsgi.cores }}<br/>
|
||||
<b>masterpid:</b> {{uwsgi.masterpid()}}<br/>
|
||||
<b>cluster:</b> {{uwsgi.cluster()}}<br/>
|
||||
{% if uwsgi.opt['spooler'] %}
|
||||
<b>spooler pid:</b> {{uwsgi.spooler_pid()}}<br/>
|
||||
{% endif %}
|
||||
|
||||
{% if uwsgi.has_threads == 1 %}
|
||||
<b>--- threads enabled ---</b><br/>
|
||||
{% endif %}
|
||||
|
||||
<div class="anchor">
|
||||
<a href="#top">back to top</a>
|
||||
|
||||
+66
-12
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '0.9.8.1'
|
||||
uwsgi_version = '0.9.8.2'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -25,8 +25,10 @@ GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
|
||||
if not GCC:
|
||||
GCC = 'gcc'
|
||||
|
||||
binary_list = []
|
||||
|
||||
|
||||
def binarize(name):
|
||||
return name.replace('/', '_').replace('.','_').replace('-','_')
|
||||
|
||||
def spcall(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=open('/dev/null','w'))
|
||||
@@ -164,6 +166,11 @@ def build_uwsgi(uc):
|
||||
|
||||
bin_name = uc.get('bin_name')
|
||||
|
||||
if uc.get('embed_config'):
|
||||
gcc_list.append(uc.get('embed_config'))
|
||||
for ef in binary_list:
|
||||
gcc_list.append("build/%s" % ef)
|
||||
|
||||
print("*** uWSGI linking ***")
|
||||
ldline = "%s -o %s %s %s %s" % (GCC, bin_name, ' '.join(ldflags),
|
||||
' '.join(map(add_o, gcc_list)), ' '.join(libs))
|
||||
@@ -225,12 +232,13 @@ class uConf(object):
|
||||
iconfig = ConfigParser.ConfigParser()
|
||||
iconfig.read(inherit)
|
||||
for opt in iconfig.options('uwsgi'):
|
||||
if not self.get(opt):
|
||||
if not self.config.has_option('uwsgi', opt):
|
||||
self.set(opt, iconfig.get('uwsgi', opt))
|
||||
elif self.get(opt).startswith('+'):
|
||||
self.set(opt, iconfig.get('uwsgi', opt) + self.get(opt)[1:])
|
||||
elif self.get(opt) == 'null':
|
||||
self.config.remove_option('uwsgi', opt)
|
||||
elif self.get(opt):
|
||||
if self.get(opt).startswith('+'):
|
||||
self.set(opt, iconfig.get('uwsgi', opt) + self.get(opt)[1:])
|
||||
elif self.get(opt) == 'null':
|
||||
self.config.remove_option('uwsgi', opt)
|
||||
|
||||
|
||||
def set(self, key, value):
|
||||
@@ -433,6 +441,48 @@ class uConf(object):
|
||||
uwsgi_version += '-'
|
||||
uwsgi_version += self.get('append_version')
|
||||
|
||||
|
||||
|
||||
if uwsgi_os == 'Linux':
|
||||
if self.get('embed_config'):
|
||||
binary_link_cmd = "ld -r -b binary -o %s.o %s" % (self.get('embed_config'), self.get('embed_config'))
|
||||
print(binary_link_cmd)
|
||||
os.system(binary_link_cmd)
|
||||
self.cflags.append("-DUWSGI_EMBED_CONFIG=_binary_%s_start" % self.get('embed_config').replace('.','_'))
|
||||
self.cflags.append("-DUWSGI_EMBED_CONFIG_END=_binary_%s_end" % self.get('embed_config').replace('.','_'))
|
||||
if self.get('embed_files'):
|
||||
for ef in self.get('embed_files').split(','):
|
||||
ef_parts = ef.split('=')
|
||||
symbase = None
|
||||
if len(ef_parts) > 1:
|
||||
ef = ef_parts[1]
|
||||
symbase = ef_parts[0]
|
||||
if os.path.isdir(ef):
|
||||
for directory, directories, files in os.walk(ef):
|
||||
for f in files:
|
||||
fname = "%s/%s" % (directory, f)
|
||||
binary_link_cmd = "ld -r -b binary -o build/%s.o %s" % (binarize(fname), fname)
|
||||
print(binary_link_cmd)
|
||||
os.system(binary_link_cmd)
|
||||
if symbase:
|
||||
for kind in ('start','end'):
|
||||
objcopy_cmd = "objcopy --redefine-sym _binary_%s_%s=_binary_%s%s_%s build/%s.o" % (binarize(fname), kind, binarize(symbase), binarize(fname[len(ef):]), kind, binarize(fname))
|
||||
print(objcopy_cmd)
|
||||
os.system(objcopy_cmd)
|
||||
binary_list.append(binarize(fname))
|
||||
else:
|
||||
binary_link_cmd = "ld -r -b binary -o build/%s.o %s" % (binarize(ef), ef)
|
||||
print(binary_link_cmd)
|
||||
os.system(binary_link_cmd)
|
||||
binary_list.append(binarize(ef))
|
||||
if symbase:
|
||||
for kind in ('start','end'):
|
||||
objcopy_cmd = "objcopy --redefine-sym _binary_%s_%s=_binary_%s_%s build/%s.o" % (binarize(ef), kind, binarize(symbase), kind, binarize(ef))
|
||||
print(objcopy_cmd)
|
||||
os.system(objcopy_cmd)
|
||||
|
||||
|
||||
|
||||
self.cflags.append('-DUWSGI_VERSION="\\"' + uwsgi_version + '\\""')
|
||||
|
||||
uver_whole = uwsgi_version.split('-', 1)
|
||||
@@ -628,7 +678,10 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
shared_flag = '-dynamiclib -undefined dynamic_lookup'
|
||||
|
||||
for cfile in up.GCC_LIST:
|
||||
gcc_list.append(path + '/' + cfile + '.c')
|
||||
if not cfile.endswith('.c') and not cfile.endswith('.cc'):
|
||||
gcc_list.append(path + '/' + cfile + '.c')
|
||||
else:
|
||||
gcc_list.append(path + '/' + cfile)
|
||||
|
||||
|
||||
gccline = "%s -fPIC %s -o %s.so %s %s %s %s" % (GCC, shared_flag, plugin_dest, ' '.join(p_cflags), ' '.join(p_ldflags), ' '.join(gcc_list), ' '.join(p_libs) )
|
||||
@@ -685,10 +738,11 @@ if __name__ == "__main__":
|
||||
name = None
|
||||
build_plugin(sys.argv[2], uc, cflags, ldflags, libs, name)
|
||||
elif cmd == '--clean':
|
||||
os.system("rm *.o")
|
||||
os.system("rm proto/*.o")
|
||||
os.system("rm lib/*.o")
|
||||
os.system("rm plugins/*/*.o")
|
||||
os.system("rm -f *.o")
|
||||
os.system("rm -f proto/*.o")
|
||||
os.system("rm -f lib/*.o")
|
||||
os.system("rm -f plugins/*/*.o")
|
||||
os.system("rm -f build/*.o")
|
||||
|
||||
else:
|
||||
print("unknown uwsgiconfig command")
|
||||
|
||||
+128
-13
@@ -1,4 +1,5 @@
|
||||
import uwsgi
|
||||
from threading import Thread
|
||||
|
||||
if uwsgi.masterpid() == 0:
|
||||
raise Exception("you have to enable the uWSGI master process to use this module")
|
||||
@@ -6,6 +7,74 @@ if uwsgi.masterpid() == 0:
|
||||
if uwsgi.opt.get('lazy'):
|
||||
raise Exception("uWSGI lazy mode is not supporte by this module")
|
||||
|
||||
spooler_functions = {}
|
||||
postfork_chain = []
|
||||
|
||||
def get_free_signal():
|
||||
for signum in xrange(0, 256):
|
||||
if not uwsgi.signal_registered(signum):
|
||||
return signum
|
||||
|
||||
raise Exception("No free uwsgi signal available")
|
||||
|
||||
def manage_spool_request(vars):
|
||||
ret = spooler_functions[vars['ud_spool_func']](vars)
|
||||
if not vars.has_key('ud_spool_ret'):
|
||||
return ret
|
||||
return int(vars['ud_spool_ret'])
|
||||
|
||||
def postfork_chain_hook():
|
||||
for f in postfork_chain:
|
||||
f()
|
||||
|
||||
uwsgi.spooler = manage_spool_request
|
||||
uwsgi.post_fork_hook = postfork_chain_hook
|
||||
|
||||
class postfork(object):
|
||||
def __init__(self, f):
|
||||
postfork_chain.append(f)
|
||||
|
||||
class spool(object):
|
||||
|
||||
def spool(self, *args, **kwargs):
|
||||
arguments = self.base_dict
|
||||
arguments['ud_spool_ret'] = str(uwsgi.SPOOL_OK)
|
||||
if len(args) > 0:
|
||||
arguments.update(args[0])
|
||||
if kwargs:
|
||||
arguments.update(kwargs)
|
||||
return uwsgi.spool(arguments)
|
||||
|
||||
def __init__(self, f):
|
||||
if not uwsgi.opt.has_key('spooler'):
|
||||
raise Exception("you have to enable the uWSGI spooler to use the @spool decorator")
|
||||
self.f = f
|
||||
spooler_functions[f.__name__] = self.f
|
||||
self.f.spool = self.spool
|
||||
self.base_dict = {'ud_spool_func':self.f.__name__}
|
||||
|
||||
class spoolforever(spool):
|
||||
|
||||
def spool(self, *args, **kwargs):
|
||||
arguments = self.base_dict
|
||||
arguments['ud_spool_ret'] = str(uwsgi.SPOOL_RETRY)
|
||||
if len(args) > 0:
|
||||
arguments.update(args[0])
|
||||
if kwargs:
|
||||
arguments.update(kwargs)
|
||||
return uwsgi.spool(arguments)
|
||||
|
||||
class spoolraw(spool):
|
||||
|
||||
def spool(self, *args, **kwargs):
|
||||
arguments = self.base_dict
|
||||
if len(args) > 0:
|
||||
arguments.update(args[0])
|
||||
if kwargs:
|
||||
arguments.update(kwargs)
|
||||
return uwsgi.spool(arguments)
|
||||
|
||||
|
||||
class rpc(object):
|
||||
|
||||
def __init__(self, name):
|
||||
@@ -17,42 +86,88 @@ class rpc(object):
|
||||
|
||||
class signal(object):
|
||||
|
||||
def __init__(self, num):
|
||||
def __init__(self, num, **kwargs):
|
||||
self.num = num
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
return f
|
||||
|
||||
class timer(object):
|
||||
|
||||
def __init__(self, num, secs):
|
||||
self.num = num
|
||||
def __init__(self, secs, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.secs = secs
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_timer(self.num, self.secs)
|
||||
return f
|
||||
|
||||
class rbtimer(object):
|
||||
class cron(object):
|
||||
|
||||
def __init__(self, num, secs):
|
||||
self.num = num
|
||||
self.secs = secs
|
||||
def __init__(self, minute, hour, day, month, dayweek, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.minute = minute
|
||||
self.hour = hour
|
||||
self.day = day
|
||||
self.month = month
|
||||
self.dayweek = dayweek
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_cron(self.num, self.minute, self.hour, self.day, self.month, self.dayweek)
|
||||
return f
|
||||
|
||||
|
||||
|
||||
class rbtimer(object):
|
||||
|
||||
def __init__(self, secs, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.secs = secs
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_rb_timer(self.num, self.secs)
|
||||
return f
|
||||
|
||||
class filemon(object):
|
||||
|
||||
def __init__(self, num, fsobj):
|
||||
self.num = num
|
||||
def __init__(self, fsobj, **kwargs):
|
||||
self.num = kwargs.get('signum', get_free_signal())
|
||||
self.fsobj = fsobj
|
||||
self.target = kwargs.get('target', '')
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.register_signal(self.num, self.target, f)
|
||||
uwsgi.add_file_monitor(self.num, self.fsobj)
|
||||
return f
|
||||
|
||||
class lock(object):
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
uwsgi.lock()
|
||||
try:
|
||||
return self.f(*args, **kwargs)
|
||||
finally:
|
||||
uwsgi.unlock()
|
||||
|
||||
class thread(object):
|
||||
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
|
||||
def __call__(self, *args):
|
||||
t = Thread(target=self.f, args=args)
|
||||
t.daemon = True
|
||||
t.start()
|
||||
return self.f
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
[uwsgi]
|
||||
|
||||
socket = :3031
|
||||
master = true
|
||||
vassal-sos-backlog = 10
|
||||
module = werkzeug.testapp:test_app
|
||||
processes = 1
|
||||
zerg-server = /tmp/broodlord.sock
|
||||
disable-logging = true
|
||||
|
||||
|
||||
[zerg]
|
||||
zerg = /tmp/broodlord.sock
|
||||
master = true
|
||||
module = werkzeug.testapp:test_app
|
||||
processes = 1
|
||||
disable-logging = true
|
||||
idle = 30
|
||||
die-on-idle = true
|
||||
@@ -3,6 +3,7 @@
|
||||
trac = trac.web.main
|
||||
id = myapp
|
||||
socket = /tmp/%(id).sock
|
||||
socket = :0
|
||||
env = TRAC_ENV=/opt/projects/%(id)
|
||||
module = %(trac):dispatch_request
|
||||
processes = 8
|
||||
|
||||
Reference in New Issue
Block a user