Compare commits

..
23 Commits
Author SHA1 Message Date
roberto@precise64 6692276472 uWSGI 1.2 2012-04-30 11:05:08 +02:00
roberto@mrspurr 81c09a9c9c report signum in worker's death 2012-04-29 05:04:19 +02:00
roberto@precise64 6a0a367ec3 added a test for gevent + threads 2012-04-26 15:11:52 +02:00
roberto@precise64 bdf533d62b fixed auto-reloading 2012-04-26 14:51:39 +02:00
roberto@precise64 1aba0bc26c completed --if-reload//--if-not-reload 2012-04-26 09:40:20 +02:00
roberto@precise64 aac6e9a365 fixed ruby -bash 2012-04-26 09:26:33 +02:00
roberto@precise64 9da732d96c added --if-reload/--if-not-reload and --unenv 2012-04-26 09:17:45 +02:00
roberto@precise64 328ba43ed2 fix uninitialzied structure 2012-04-25 17:55:47 +02:00
roberto@freebsd9 62d3253b02 fix kqueue() usage 2012-04-25 15:02:19 +02:00
roberto@mrspurr e5ba01e707 fixed socket in non-blocking mode 2012-04-25 14:18:40 +02:00
roberto@openbsd51 82c25f7f8c better execinfo detection 2012-04-25 11:00:25 +02:00
roberto@precise64 8791866ea0 added ebug infos for touch checks 2012-04-25 08:37:23 +02:00
roberto@opensuse12 8f10b8fece fix python version printing on freeky systems 2012-04-25 08:11:12 +02:00
roberto@opensuse12 0d28d210d4 another opensuse-related fix, build mimedict only if needed 2012-04-25 08:02:24 +02:00
roberto@precise 2368a5a050 fixed bug 121 2012-04-25 07:21:28 +02:00
roberto@precise64 74a9b1b41d added uwsgi.ready() 2012-04-24 21:50:00 +02:00
roberto@precise64 672c49e8eb refactored signal handling 2012-04-24 21:27:43 +02:00
roberto@precise64 225db32636 threading support for gevent 2012-04-24 19:23:14 +02:00
roberto@opensuse12 01541e4a50 fixed bug #120 2012-04-24 18:53:38 +02:00
roberto@precise64 357e260b45 some minor cleanup spotted by marcin deranek 2012-04-20 16:27:00 +02:00
roberto@centos32 a2513b1851 put a \0 at the end of process name 2012-04-20 16:11:16 +02:00
roberto@precise64 bbe8604054 added hack for ruby -bash 2012-04-20 14:11:08 +02:00
roberto@precise64 58a33de7f7 Added tag 1.2-rc2 for changeset 29de0fb320bc 2012-04-20 10:11:59 +02:00
23 changed files with 282 additions and 121 deletions
+1
View File
@@ -50,3 +50,4 @@ ede5c664978bb40e476e8d4a5789562928f28507 1.1-rc3
ef99144291f06822d026e981d5d856cbec14d867 1.1-rc4
e1568fd16b7b586cc72deb4dfccbbe64ae0b84df 1.1
24c8fe5a26e557db41cf1cee45b8964d5885e484 1.2-rc1
29de0fb320bc0a1ce84972f9f249360e315d3c10 1.2-rc2
+20
View File
@@ -1,3 +1,23 @@
*** april 2012 ***
* 1.2 [20120430]
- PyPy support
- Improved gevent support with threads
- Python auto-reload subsystem
- added --spooler-max-tasks
- pthread robust mutexes support in Linux and Solaris
- posix semaphores support in FreeBSD9
- thread-safe ctime() reporting
- interval support in cron subsystem
- improved syslog support
- better management of disconnected clients
- static files serving improvements
- another set of multithreading optimizations
- minor fixes in the Rack plugin
- Upstart socket-activation support
*** march 2012 ***
* 1.1 [20120317]
+1 -1
View File
@@ -40,7 +40,7 @@ void cluster_setup() {
// receive the packet
char clusterbuf[4096];
if (!uwsgi_hooked_parse_dict_dgram(uwsgi.cluster_fd, clusterbuf, 4096, 99, 1, cluster_manage_opt, NULL)) {
uwsgi_configure(-1);
uwsgi_configure();
goto options_parsed;
}
else {
+2 -1
View File
@@ -421,7 +421,8 @@ int event_queue_interesting_fd(void *events, int id) {
int event_queue_interesting_fd_has_error(void *events, int id) {
struct kevent *ev = (struct kevent *) events;
if ( ( (ev[id].flags == EV_ERROR) || (ev[id].flags == EV_EOF) || (ev[id].flags == (EV_EOF|EV_ERROR))) ) {
// DO NOT CHECK FOR EOF !!!
if ( ev[id].flags & EV_ERROR ) {
return 1;
}
return 0;
+1 -1
View File
@@ -14,7 +14,7 @@ def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
yield "foobar<br/>"
if uwsgi.loop == 'gevent':
gevent.sleep(10)
gevent.sleep(3)
yield str(env['wsgi.input'].fileno())
yield "<h1>Hello World</h1>"
try:
+2 -29
View File
@@ -120,7 +120,6 @@ 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[3];
char uwsgi_signal;
if (uwsgi.threads > 1) {
@@ -188,38 +187,12 @@ void *zeromq_loop(void *arg1) {
}
if (zmq_poll_items[1].revents & ZMQ_POLLIN) {
if (read(uwsgi.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);
}
}
uwsgi_receive_signal(uwsgi.signal_socket, "worker", uwsgi.mywid);
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);
}
}
uwsgi_receive_signal(uwsgi.my_signal_socket, "worker", uwsgi.mywid);
continue;
}
+6 -1
View File
@@ -1601,7 +1601,12 @@ nextlock:
// noop
}
else if (uwsgi.workers[uwsgi.mywid].manage_next_request) {
uwsgi_log("DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int) diedpid);
if (WIFSIGNALED(waitpid_status)) {
uwsgi_log("DAMN ! worker %d (pid: %d) died, killed by signal %d :( trying respawn ...\n", uwsgi.mywid, (int) diedpid, (int) WTERMSIG(waitpid_status));
}
else {
uwsgi_log("DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int) diedpid);
}
}
if (uwsgi.workers[uwsgi.mywid].cheaped == 1) {
+4
View File
@@ -582,6 +582,10 @@ void fastrouter_loop(int id) {
break;
}
#ifndef __linux__
uwsgi_socket_b(new_connection);
#endif
ufr.fr_table[new_connection] = alloc_fr_session();
ufr.fr_table[new_connection]->fd = new_connection;
ufr.fr_table[new_connection]->instance_fd = -1;
+15 -18
View File
@@ -34,34 +34,20 @@ struct wsgi_request *uwsgi_gevent_current_wsgi_req(void) {
PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) {
uint8_t uwsgi_signal;
int signal_socket;
if (!PyArg_ParseTuple(args, "i:uwsgi_gevent_signal_handler", &signal_socket)) {
return NULL;
}
if (read(signal_socket, &uwsgi_signal, 1) <= 0) {
if (uwsgi.no_orphans) {
uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid);
end_me(0);
}
// close the socket to end the mess...from now on the worker is alone (no master)
else close(signal_socket);
}
else {
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid);
}
}
uwsgi_receive_signal(signal_socket, "worker", uwsgi.mywid);
Py_INCREF(Py_None);
return Py_None;
}
// the following twi functions are called whenever an event is available in the signal queue
// they both trigger the same function
PyObject *py_uwsgi_gevent_signal(PyObject * self, PyObject * args) {
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.signal_socket));
@@ -180,7 +166,6 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
goto clear_and_stop;
}
else if (ret == watcher) {
status = wsgi_req->socket->proto(wsgi_req);
if (status < 0) {
goto clear_and_stop;
@@ -203,6 +188,7 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
if (wsgi_req->async_status <= UWSGI_OK) {
goto clear;
}
wsgi_req->switches++;
// switch after each yield
GEVENT_SWITCH;
}
@@ -239,6 +225,17 @@ PyMethodDef uwsgi_gevent_signal_handler_def[] = { {"uwsgi_gevent_signal_handler"
void gevent_loop() {
if (!uwsgi.has_threads && uwsgi.mywid == 1) {
uwsgi_log("!!! Running gevent without threads IS NOT recommended, enable them with --enable-threads !!!\n");
}
// get the GIL
UWSGI_GET_GIL
// ..then reset GIL subsystem as noop (gevent IO will take care of it...)
up.gil_get = gil_fake_get;
up.gil_release = gil_fake_release;
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
if (uwsgi.async < 2) {
+6 -5
View File
@@ -592,6 +592,9 @@ void http_loop(int id) {
taken = 1;
break;
}
#ifndef __linux__
uwsgi_socket_b(new_connection);
#endif
uhttp_table[new_connection] = alloc_uhttp_session();
uhttp_table[new_connection]->fd = new_connection;
@@ -892,10 +895,9 @@ void http_loop(int id) {
break;
}
len = send(uhttp_session->fd, bbuf, len, 0);
if (len <= 0) {
if (len < 0)
ssize_t s_len = send(uhttp_session->fd, bbuf, len, 0);
if (s_len <= 0) {
if (s_len < 0)
uwsgi_error("send()");
close(uhttp_session->fd);
close(uhttp_session->instance_fd);
@@ -910,7 +912,6 @@ void http_loop(int id) {
// body from client
else if (interesting_fd == uhttp_session->fd) {
//uwsgi_log("receiving body...\n");
len = recv(uhttp_session->fd, bbuf, UMAX16, 0);
#ifdef UWSGI_EVENT_USE_PORT
event_queue_add_fd_read(uhttp_queue, uhttp_session->fd);
+15 -15
View File
@@ -150,7 +150,12 @@ int uwsgi_python_init() {
#ifndef UWSGI_PYPY
char *pyversion = strchr(Py_GetVersion(), '\n');
uwsgi_log_initial("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1);
if (!pyversion) {
uwsgi_log_initial("Python version: %s\n", Py_GetVersion());
}
else {
uwsgi_log_initial("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1);
}
#else
uwsgi_log_initial("PyPy version: %s\n", PYPY_VERSION);
#endif
@@ -189,6 +194,10 @@ int uwsgi_python_init() {
Py_Initialize();
if (!uwsgi.has_threads) {
uwsgi_log("*** Python threads support is disabled. You can enable it with --enable-threads ***\n");
}
up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL);
up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL);
@@ -1187,22 +1196,15 @@ void uwsgi_python_init_thread(int core_id) {
}
#ifdef UWSGI_THREADING
int uwsgi_check_python_mtime(PyObject *times_dict, uint64_t cycles, char *filename) {
int uwsgi_check_python_mtime(PyObject *times_dict, char *filename) {
struct stat st;
PyObject *py_mtime = PyDict_GetItemString(times_dict, filename);
if (!py_mtime) {
if (cycles == 0) {
if (stat(filename, &st)) {
return 0;
}
PyDict_SetItemString(times_dict, filename, PyLong_FromLong(st.st_mtime));
}
else {
uwsgi_log("[uwsgi-python-reloader] found new module/file: %s\n", filename);
kill(uwsgi.workers[0].pid, SIGHUP);
return 1;
if (stat(filename, &st)) {
return 0;
}
PyDict_SetItemString(times_dict, filename, PyLong_FromLong(st.st_mtime));
}
// the record is already tracked;
else {
@@ -1268,7 +1270,6 @@ cycle:
}
PyObject *times_dict = PyDict_New();
char *filename;
uint64_t cycles = 0;
for(;;) {
UWSGI_RELEASE_GIL;
sleep(up.auto_reload);
@@ -1314,7 +1315,7 @@ cycle:
else {
filename = uwsgi_concat2(mod_filename, "");
}
if (uwsgi_check_python_mtime(times_dict, cycles, filename)) {
if (uwsgi_check_python_mtime(times_dict, filename)) {
UWSGI_RELEASE_GIL;
return NULL;
}
@@ -1323,7 +1324,6 @@ cycle:
Py_DECREF(zero);
#endif
}
cycles++;
}
return NULL;
+13
View File
@@ -1025,6 +1025,17 @@ PyObject *py_uwsgi_setprocname(PyObject * self, PyObject * args) {
return Py_None;
}
PyObject *py_uwsgi_ready(PyObject * self, PyObject * args) {
if (ushared->ready) {
Py_INCREF(Py_True);
return Py_True;
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_in_farm(PyObject * self, PyObject * args) {
char *farm_name = NULL;
@@ -3103,6 +3114,8 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"mule_get_msg", (PyCFunction) py_uwsgi_mule_get_msg, METH_VARARGS|METH_KEYWORDS, ""},
{"farm_get_msg", py_uwsgi_farm_get_msg, METH_VARARGS, ""},
{"in_farm", py_uwsgi_in_farm, METH_VARARGS, ""},
{"ready", py_uwsgi_ready, METH_VARARGS, ""},
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
{NULL, NULL},
+9
View File
@@ -325,6 +325,11 @@ void uwsgi_ruby_gemset(char *gemset) {
}
static void rack_hack_dollar_zero(VALUE name, ID id) {
ur.dollar_zero = rb_obj_as_string(name);
rb_obj_taint(ur.dollar_zero);
}
int uwsgi_rack_init(){
struct http_status_codes *http_sc;
@@ -357,6 +362,10 @@ int uwsgi_rack_init(){
ruby_script("uwsgi");
ur.dollar_zero = rb_str_new2("uwsgi");
rb_define_hooked_variable("$0", &ur.dollar_zero, 0, rack_hack_dollar_zero);
rb_define_hooked_variable("$PROGRAM_NAME", &ur.dollar_zero, 0, rack_hack_dollar_zero);
ur.signals_protector = rb_ary_new();
ur.rpc_protector = rb_ary_new();
rb_gc_register_address(&ur.signals_protector);
+2
View File
@@ -52,6 +52,8 @@ struct uwsgi_rack {
VALUE signals_protector;
VALUE rpc_protector;
VALUE dollar_zero;
VALUE dispatcher;
VALUE rb_uwsgi_io_class;
ID call;
+3
View File
@@ -1,9 +1,12 @@
from threading import Thread
import time
import uwsgi
def mess():
while True:
for i in xrange(0, 100):
if uwsgi.ready():
uwsgi.signal(17)
print(i)
time.sleep(0.1)
+30
View File
@@ -559,3 +559,33 @@ cycle:
return received_signal;
}
void uwsgi_receive_signal(int fd, char *name, int id) {
uint8_t uwsgi_signal;
ssize_t ret = read(fd, &uwsgi_signal, 1);
if (ret == 0) {
goto destroy;
}
else if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
uwsgi_error("[uwsgi-signal] read()");
goto destroy;
}
else if (ret > 0) {
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to %s %d\n", uwsgi_signal, name, id);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on %s %d\n", uwsgi_signal, name, id);
}
}
return;
destroy:
// better to kill the whole worker...
uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: i will kill myself !!!\n", name, id);
end_me(0);
}
+19 -4
View File
@@ -758,6 +758,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
return serverfd;
}
// set non-blocking socket
void uwsgi_socket_nb(int fd) {
int arg;
@@ -774,6 +775,24 @@ void uwsgi_socket_nb(int fd) {
}
// set blocking socket
void uwsgi_socket_b(int fd) {
int arg;
arg = fcntl(fd, F_GETFL, NULL);
if (arg < 0) {
uwsgi_error("fcntl()");
return;
}
arg &= (~O_NONBLOCK);
if (fcntl(fd, F_SETFL, arg) < 0) {
uwsgi_error("fcntl()");
return;
}
}
int timed_connect(struct pollfd *fdpoll, const struct sockaddr *addr, int addr_size, int timeout, int async) {
int arg, ret;
@@ -1013,10 +1032,6 @@ 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)) {
+1 -13
View File
@@ -340,19 +340,7 @@ void spooler(struct uwsgi_spooler *uspool) {
if (event_queue_wait(spooler_event_queue, timeout, &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) {
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);
}
}
uwsgi_receive_signal(interesting_fd, "spooler", (int) getpid());
}
}
}
+39
View File
@@ -0,0 +1,39 @@
# uwsgi -s :3031 -M -p 4 --plugin gevent --loop gevent --async 1000 --enable-threads -w tests.testgevent
from threading import Thread
import gevent
import uwsgi
import time
def microtask(wid):
print "i am a gevent task"
gevent.sleep(10)
print "10 seconds elapsed in worker id %d" % wid
def athread():
while True:
time.sleep(1)
print "i am the thread 1"
def athread2():
while True:
time.sleep(1)
print "i am the thread 2"
t1 = Thread(target=athread)
t1.daemon = True
t1.start()
t2 = Thread(target=athread2)
t2.daemon = True
t2.start()
def application(environ, start_response):
gevent.sleep()
start_response('200 OK', [('Content-Type','text/html')])
yield "sleeping for 3 seconds...<br/>"
gevent.sleep(3)
yield "done<br/>"
gevent.spawn(microtask, uwsgi.worker_id())
yield "microtask started<br/>"
+32 -19
View File
@@ -1018,7 +1018,6 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
int ret;
int interesting_fd;
char uwsgi_signal;
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
thunder_lock;
@@ -1037,23 +1036,7 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
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);
end_me(0);
}
else {
close(interesting_fd);
}
}
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);
}
}
uwsgi_receive_signal(interesting_fd, "worker", uwsgi.mywid);
#ifdef UWSGI_THREADING
if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret);
@@ -1135,6 +1118,11 @@ void sanitize_args() {
uwsgi.ignore_sigpipe = 1;
uwsgi.ignore_write_errors = 1;
}
if (uwsgi.cheaper_count > 0 && uwsgi.cheaper_count >= uwsgi.numproc) {
uwsgi_log("invalid cheaper value: must be lower than processes\n");
exit(1);
}
}
void env_to_arg(char *src, char *dst) {
@@ -1925,6 +1913,22 @@ int uwsgi_logic_opt_if_not_env(char *key, char *value) {
return 0;
}
int uwsgi_logic_opt_if_reload(char *key, char *value) {
if (uwsgi.is_a_reload) {
add_exported_option(key, value, 0);
return 1;
}
return 0;
}
int uwsgi_logic_opt_if_not_reload(char *key, char *value) {
if (!uwsgi.is_a_reload) {
add_exported_option(key, value, 0);
return 1;
}
return 0;
}
int uwsgi_logic_opt_if_file(char *key, char *value) {
if (uwsgi_is_file(uwsgi.logic_opt_data)) {
@@ -3190,6 +3194,7 @@ struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list,
uwsgi_string->len = strlen(value);
}
uwsgi_string->next = NULL;
uwsgi_string->custom = 0;
return uwsgi_string;
}
@@ -3920,7 +3925,11 @@ void uwsgi_set_processname(char *name) {
strncat(uwsgi.orig_argv[0], uwsgi.procname_append, uwsgi.max_procname-(amount+1));
}
memset(uwsgi.orig_argv[0]+amount+1, ' ', uwsgi.max_procname-(amount-1));
// fill with spaces...
memset(uwsgi.orig_argv[0]+amount+1, ' ', uwsgi.max_procname-(amount));
// end with \0
memset(uwsgi.orig_argv[0]+amount+1+(uwsgi.max_procname-(amount)), '\0', 1);
#elif defined(__FreeBSD__)
if (uwsgi.procname_prefix) {
if (!uwsgi.procname_append) {
@@ -4088,6 +4097,10 @@ char *uwsgi_check_touches(struct uwsgi_string_list *touch_list) {
else {
if (!touch->custom) touch->custom = (uint64_t) tr_st.st_mtime;
if ((uint64_t) tr_st.st_mtime > touch->custom) {
#ifdef UWSGI_DEBUG
uwsgi_log("[uwsgi-check-touches] modification detected on %s: %llu -> %llu\n", touch->value, (unsigned long long) touch->custom,
(unsigned long long) tr_st.st_mtime);
#endif
touch->custom = (uint64_t) tr_st.st_mtime;
return touch->value;
}
+49 -12
View File
@@ -71,6 +71,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"if-not-env", required_argument, 0, "(opt logic) check for environment variable", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_not_env, UWSGI_OPT_IMMEDIATE},
{"ifenv", required_argument, 0, "(opt logic) check for environment variable", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_env, UWSGI_OPT_IMMEDIATE},
{"if-reload", no_argument, 0, "(opt logic) check for reload", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_reload, UWSGI_OPT_IMMEDIATE},
{"if-not-reload", no_argument, 0, "(opt logic) check for reload", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_not_reload, UWSGI_OPT_IMMEDIATE},
{"if-exists", required_argument, 0, "(opt logic) check for file/directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_exists, UWSGI_OPT_IMMEDIATE},
{"if-not-exists", required_argument, 0, "(opt logic) check for file/directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_not_exists, UWSGI_OPT_IMMEDIATE},
{"ifexists", required_argument, 0, "(opt logic) check for file/directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_exists, UWSGI_OPT_IMMEDIATE},
@@ -263,7 +266,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"propagate-touch", no_argument, 0, "over-engineering option for system with flaky signal mamagement", uwsgi_opt_true, &uwsgi.propagate_touch, 0},
{"limit-post", required_argument, 0, "limit request body", uwsgi_opt_set_64bit, &uwsgi.limit_post, 0},
{"no-orphans", no_argument, 0, "automatically kill workers if master dies (can be dangerous for availability)", uwsgi_opt_true, &uwsgi.no_orphans, 0},
{"prio", required_argument, 0, "set processes/threads priority", uwsgi_opt_set_int, &uwsgi.prio, 0},
{"prio", required_argument, 0, "set processes/threads priority", uwsgi_opt_set_rawint, &uwsgi.prio, 0},
{"cpu-affinity", required_argument, 0, "set cpu affinity", uwsgi_opt_set_int, &uwsgi.cpu_affinity, 0},
{"post-buffering", required_argument, 0, "enable post buffering", uwsgi_opt_set_64bit, &uwsgi.post_buffering, 0},
{"post-buffering-bufsize", required_argument, 0, "set buffer size for read() in post buffering mode", uwsgi_opt_set_64bit, &uwsgi.post_buffering_bufsize,0},
@@ -394,6 +397,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"close-on-exec", no_argument, 0, "set close-on-exec on sockets (could be required for spawning processes in requests)", uwsgi_opt_true, &uwsgi.close_on_exec, 0},
{"mode", required_argument, 0, "set uWSGI custom mode", uwsgi_opt_set_str, &uwsgi.mode,0},
{"env", required_argument, 0, "set environment variable", uwsgi_opt_set_env, NULL, 0},
{"unenv", required_argument, 0, "unset environment variable", uwsgi_opt_unset_env, NULL, 0},
{"vacuum", no_argument, 0, "try to remove all of the generated file/sockets", uwsgi_opt_true, &uwsgi.vacuum,0},
#ifdef __linux__
{"cgroup", required_argument, 0, "put the processes in the specified cgroup", uwsgi_opt_add_string_list, &uwsgi.cgroup,0},
@@ -562,8 +566,8 @@ void gracefully_kill(int signum) {
uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
#ifdef UWSGI_THREADING
struct wsgi_request *wsgi_req = current_wsgi_req();
if (uwsgi.threads > 1) {
struct wsgi_request *wsgi_req = current_wsgi_req();
wait_for_threads();
if (!uwsgi.core[wsgi_req->async_id]->in_request) {
exit(UWSGI_RELOAD_CODE);
@@ -1654,6 +1658,12 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_log_initial("*** big endian arch detected ***\n");
#endif
#if defined(_SC_NPROCESSORS_ONLN)
uwsgi_log_initial("detected number of CPU cores: %d\n", sysconf(_SC_NPROCESSORS_ONLN));
#elif defined(_SC_NPROCESSORS_CONF)
uwsgi_log_initial("detected number of CPU cores: %d\n", sysconf(_SC_NPROCESSORS_CONF));
#endif
uwsgi_log_initial("current working directory: %s\n", uwsgi.cwd);
@@ -1863,17 +1873,21 @@ int uwsgi_start(void *v_argv) {
sanitize_args();
// initialize workers
if (!uwsgi.mime_file) uwsgi_string_new_list(&uwsgi.mime_file, "/etc/mime.types");
struct uwsgi_string_list *umd = uwsgi.mime_file;
while(umd) {
if (!access(umd->value, R_OK)) {
uwsgi_build_mime_dict(umd->value);
if (uwsgi.build_mime_dict) {
if (!uwsgi.mime_file) uwsgi_string_new_list(&uwsgi.mime_file, "/etc/mime.types");
struct uwsgi_string_list *umd = uwsgi.mime_file;
while(umd) {
if (!access(umd->value, R_OK)) {
uwsgi_build_mime_dict(umd->value);
}
else {
uwsgi_log("!!! no %s file found !!!\n", umd->value);
}
umd = umd->next;
}
else {
uwsgi_log("!!! no %s file found !!!\n", umd->value);
}
umd = umd->next;
}
}
if (uwsgi.static_offload_to_thread) {
pthread_attr_init(&uwsgi.static_offload_thread_attr);
@@ -2276,6 +2290,7 @@ int uwsgi_start(void *v_argv) {
uwsgi_sock = uwsgi_sock->next;
}
if (uwsgi.chown_socket) {
if (!uwsgi.master_as_root) {
uwsgi_as_root();
@@ -3525,8 +3540,24 @@ void uwsgi_opt_set_int(char *opt, char *value, void *key) {
else {
*ptr = 1;
}
if (*ptr < 0) {
uwsgi_log("invalid value for option \"%s\": must be > 0\n", opt);
exit(1);
}
}
void uwsgi_opt_set_rawint(char *opt, char *value, void *key) {
int *ptr = (int *) key;
if (value) {
*ptr = atoi((char *)value);
}
else {
*ptr = 1;
}
}
void uwsgi_opt_set_64bit(char *opt, char *value, void *key) {
uint64_t *ptr = (uint64_t *) key;
@@ -3681,6 +3712,12 @@ void uwsgi_opt_set_env(char *opt, char *value, void *none) {
}
}
void uwsgi_opt_unset_env(char *opt, char *value, void *none) {
if (unsetenv(value)) {
uwsgi_error("unsetenv()");
}
}
void uwsgi_opt_pidfile_signal(char *opt, char *pidfile, void *sig) {
long *signum_fake_ptr = (long *) sig;
+10 -1
View File
@@ -24,7 +24,7 @@ extern "C" {
#define uwsgi_str(x) uwsgi_concat2(x, "")
#define uwsgi_notify(x) if (uwsgi.notify) uwsgi.notify(x)
#define uwsgi_notify_ready() if (uwsgi.notify_ready) uwsgi.notify_ready()
#define uwsgi_notify_ready() uwsgi.shared->ready = 1 ; if (uwsgi.notify_ready) uwsgi.notify_ready()
#define uwsgi_apps uwsgi.workers[uwsgi.mywid].apps
#define uwsgi_apps_cnt uwsgi.workers[uwsgi.mywid].apps_cnt
@@ -1811,6 +1811,8 @@ struct uwsgi_shared {
struct uwsgi_gateway gateways[MAX_GATEWAYS];
int gateways_cnt;
time_t gateways_harakiri[MAX_GATEWAYS];
int ready;
};
struct uwsgi_core {
@@ -2463,6 +2465,7 @@ void uwsgi_string_del_list(struct uwsgi_string_list **, struct uwsgi_string_list
void uwsgi_init_all_apps(void);
void uwsgi_socket_nb(int);
void uwsgi_socket_b(int);
void uwsgi_destroy_request(struct wsgi_request *);
@@ -2675,6 +2678,7 @@ void uwsgi_opt_add_dyn_dict(char *, char *, void *);
void uwsgi_opt_add_regexp_dyn_dict(char *, char *, void *);
#endif
void uwsgi_opt_set_int(char *, char *, void *);
void uwsgi_opt_set_rawint(char *, char *, void *);
void uwsgi_opt_set_64bit(char *, char *, void *);
void uwsgi_opt_set_megabytes(char *, char *, void *);
void uwsgi_opt_set_dyn(char *, char *, void *);
@@ -2716,6 +2720,7 @@ void uwsgi_opt_add_daemon(char *, char *, void *);
void uwsgi_opt_set_uid(char *, char *, void *);
void uwsgi_opt_set_gid(char *, char *, void *);
void uwsgi_opt_set_env(char *, char *, void *);
void uwsgi_opt_unset_env(char *, char *, void *);
void uwsgi_opt_pidfile_signal(char *, char *, void *);
void uwsgi_opt_add_app(char *, char *, void *);
@@ -2752,6 +2757,8 @@ int uwsgi_logic_opt_if_file(char *, char *);
int uwsgi_logic_opt_if_not_file(char *, char *);
int uwsgi_logic_opt_if_dir(char *, char *);
int uwsgi_logic_opt_if_not_dir(char *, char *);
int uwsgi_logic_opt_if_reload(char *, char *);
int uwsgi_logic_opt_if_not_reload(char *, char *);
#ifdef UWSGI_CAP
@@ -2818,6 +2825,8 @@ int uwsgi_try_autoload(char *);
uint64_t uwsgi_micros(void);
int uwsgi_is_file(char *);
void uwsgi_receive_signal(int, char *, int);
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);
#endif
+2 -1
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '1.2-rc2'
uwsgi_version = '1.2'
import os
import re
@@ -392,6 +392,7 @@ class uConf(object):
if self.has_include('execinfo.h') or os.path.exists('/usr/local/include/execinfo.h'):
if os.path.exists('/usr/local/include/execinfo.h'):
self.cflags.append('-I/usr/local/include')
self.ldflags.append('-L/usr/local/lib')
self.cflags.append('-DUWSGI_HAS_EXECINFO')
self.libs.append('-lexecinfo')