mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7525475d8 | ||
|
|
f35a36ac02 | ||
|
|
3b53f89a24 | ||
|
|
764d94e41b | ||
|
|
0292e15497 | ||
|
|
bde4ac7b2f | ||
|
|
c71fa3abd1 | ||
|
|
d2abdb5d3a | ||
|
|
1392791837 | ||
|
|
6f7d9634d5 | ||
|
|
82b95114a8 | ||
|
|
d90e701acd | ||
|
|
42993022bb | ||
|
|
29b1e46252 | ||
|
|
260cea639f | ||
|
|
208aea8aca | ||
|
|
f164d401d3 | ||
|
|
5e1c34a08b | ||
|
|
9c7b596a0d | ||
|
|
5ff34ac6d0 | ||
|
|
e304e34929 | ||
|
|
6d7848248d | ||
|
|
dbc0da0586 | ||
|
|
fecdcf9d10 | ||
|
|
bfd0ab2301 | ||
|
|
8002777e75 | ||
|
|
d57d5acb30 | ||
|
|
43e6664dd9 | ||
|
|
d0c6dff83e | ||
|
|
54b40f5978 | ||
|
|
1c59c03261 | ||
|
|
ce23fd38ab | ||
|
|
4818efa7de | ||
|
|
ea19e74229 | ||
|
|
fe353de5a8 | ||
|
|
1d89266f2e | ||
|
|
61d79394ca | ||
|
|
491f2828b5 | ||
|
|
431e05d4f4 | ||
|
|
ae6780a487 | ||
|
|
5707a70141 | ||
|
|
e9a7bd7da1 | ||
|
|
91e45daf6c | ||
|
|
9f69998075 | ||
|
|
4f6270976b | ||
|
|
328caa43f2 | ||
|
|
368408374a | ||
|
|
c3a90db493 | ||
|
|
5bc0320877 | ||
|
|
622ed620b9 | ||
|
|
1b859413de | ||
|
|
95432fd8e3 | ||
|
|
b3f3c5d7b3 | ||
|
|
02cef20462 | ||
|
|
3edebe34ae | ||
|
|
28c9b75fb5 | ||
|
|
a2735e10b7 | ||
|
|
e03d26fd63 | ||
|
|
7c4c346e64 | ||
|
|
67b3c0c4a8 | ||
|
|
dadca785e4 | ||
|
|
accebe5597 | ||
|
|
792965bedd | ||
|
|
1bb1bafe0c |
@@ -20,3 +20,7 @@ d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
|
||||
0000000000000000000000000000000000000000 0.9.7.1
|
||||
486e7760bcbc2191ddb9b4aee6c98dbd5fc4c754 0.9.7.1
|
||||
a5f13497b39269621f8f1e56e14d2cc141452e79 0.9.7.2
|
||||
d1e57707f6317f134fea7d12f6588d8690f74f3f 0.9.8-rc1
|
||||
e91bc724325e14c13b8f548c0b6a315c48a1c32a 0.9.8-rc2
|
||||
4fb424d52f226a0a087fea89709f5eb540e03f25 0.9.8-rc3
|
||||
0f1f3924ee5309a9990d9af1ffc68846e3dfb31b 0.9.8-rc4
|
||||
|
||||
@@ -1,3 +1,77 @@
|
||||
*** may 2011 ***
|
||||
|
||||
* 0.9.8-rc4 [20110602]
|
||||
|
||||
- fixed REMOTE_ADDR when --protocol=http
|
||||
- official support for OpenIndiana
|
||||
- added a welcome.py test script
|
||||
- new api attribute uwsgi.version_info
|
||||
- improved the admin plugin
|
||||
- two new management flag for backlog queue monitoring
|
||||
- fixed uwsgi_log for bigger loglines
|
||||
- new option --early-emperor to allows out-of-jail emperors
|
||||
- emperor can now spawn other emperors (sub-emperors)
|
||||
- fixed idle mode in single-process
|
||||
- fixed solaris iovec
|
||||
|
||||
* 0.9.8-rc3 [20110530]
|
||||
|
||||
- snapshotting support
|
||||
- fixed python 3.x spooler
|
||||
- improvements for grunt processes
|
||||
- better abstract unix socket
|
||||
- --log-socket allows logging to generic DGRAM sockets
|
||||
- a bunch of solaris fixes
|
||||
- new option --no-fd-passing for fastrouter
|
||||
- --fastrouter-subscription-slot to set the number of slot in subscription server
|
||||
- unlimited shared sockets
|
||||
- fixed netlink compilation
|
||||
- auto-reconnect on emperor+amqp server disconnection
|
||||
- various emperor fixes
|
||||
- unlimited fastrouter sockets
|
||||
- better cgroup support
|
||||
- --add-header option allow adding of custom HTTP response headers
|
||||
- cheap and idle operational modes
|
||||
|
||||
|
||||
* 0.9.8-rc2 [20110521]
|
||||
|
||||
- new option --die-on-term
|
||||
- fixed touch reload
|
||||
- a couple of optimizations for wsgi.input
|
||||
- systemd integration
|
||||
|
||||
* 0.9.8-rc1 [20110514]
|
||||
|
||||
- massive code cleanup and refactoring
|
||||
- added vassals loyalty concept
|
||||
- fixed virtualhosting with dynamic virtualenv
|
||||
- fixed reloading on grand-central-dispatch-enabled OSX
|
||||
- improved PSGI support with uGreen and async support
|
||||
- improved Rack support with complete fiber+async in ruby 1.9
|
||||
- support for JSON config files
|
||||
- native multi-protocol support (added fastcgi and http)
|
||||
- Mongrel2 support
|
||||
- support for templates in vassals
|
||||
- various threading fixes
|
||||
- gcc-4.6 support
|
||||
- support for logging via zeromq
|
||||
- support for configuration passed via pipe/stdin
|
||||
- pythonpath entries are now unlimited
|
||||
- socket entries are unlimited
|
||||
- pythonpath can be a glob
|
||||
- lazy mode added
|
||||
- new language-independent profiling subsystem
|
||||
- support for configuration stored in a sqlite3 db
|
||||
- allow workers to survive to syslogd death (when --log-syslog is used)
|
||||
- fix traceback in Python 3.x
|
||||
- support for uwsgi signals in threads
|
||||
- plugin autoloading
|
||||
- graceful reloading for threads
|
||||
- new wsgi.input object
|
||||
- support for alternative allocators (tcmalloc and jemalloc)
|
||||
|
||||
|
||||
*** april 2011 ***
|
||||
|
||||
* 0.9.7.2 [20110406]
|
||||
|
||||
@@ -318,7 +318,9 @@ void *async_loop(void *arg1) {
|
||||
// parsing complete
|
||||
if (!proto_parser_status) {
|
||||
// remove fd from event poll and fd proto table
|
||||
#ifndef UWSGI_EVENT_USE_PORT
|
||||
event_queue_del_fd(uwsgi.async_queue, interesting_fd, event_queue_read());
|
||||
#endif
|
||||
uwsgi.async_proto_fd_table[interesting_fd] = NULL;
|
||||
// put request in the runqueue
|
||||
runqueue_push(uwsgi.wsgi_req);
|
||||
|
||||
@@ -25,6 +25,7 @@ yaml_implementation = auto
|
||||
malloc_implementation = libc
|
||||
plugins =
|
||||
bin_name = uwsgi
|
||||
append_version =
|
||||
plugin_dir = .
|
||||
embedded_plugins = python, ping, cache, nagios, rpc, fastrouter, http, ugreen
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@ extern char **environ;
|
||||
|
||||
int emperor_queue;
|
||||
|
||||
static void royal_death(int signum) {
|
||||
uwsgi_notify("The Emperor is buried.");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
struct uwsgi_instance {
|
||||
struct uwsgi_instance *ui_prev;
|
||||
struct uwsgi_instance *ui_next;
|
||||
@@ -194,6 +199,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
else {
|
||||
|
||||
unsetenv("UWSGI_RELOADS");
|
||||
unsetenv("NOTIFY_SOCKET");
|
||||
|
||||
uef = uwsgi_num2str(n_ui->pipe[1]);
|
||||
if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
|
||||
@@ -309,8 +315,11 @@ void emperor_loop() {
|
||||
void *events;
|
||||
int nevents;
|
||||
int interesting_fd;
|
||||
char notification_message[64];
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
uwsgi_unix_signal(SIGINT, royal_death);
|
||||
uwsgi_unix_signal(SIGTERM, royal_death);
|
||||
|
||||
memset(&ui_base, 0, sizeof(struct uwsgi_instance));
|
||||
|
||||
@@ -319,7 +328,12 @@ void emperor_loop() {
|
||||
|
||||
events = event_queue_alloc(64);
|
||||
|
||||
uwsgi_log("*** starting uWSGI Emperor ***\n");
|
||||
if (uwsgi.has_emperor) {
|
||||
uwsgi_log("*** starting uWSGI sub-Emperor ***\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("*** starting uWSGI Emperor ***\n");
|
||||
}
|
||||
|
||||
amqp_port = strchr(uwsgi.emperor_dir, ':');
|
||||
|
||||
@@ -347,7 +361,7 @@ reconnect:
|
||||
event_queue_add_fd_read(emperor_queue, amqp_fd);
|
||||
}
|
||||
else {
|
||||
if (!glob(uwsgi.emperor_dir, GLOB_MARK, NULL, &g)) {
|
||||
if (!glob(uwsgi.emperor_dir, GLOB_MARK|GLOB_NOCHECK, NULL, &g)) {
|
||||
if (g.gl_pathc == 1 && g.gl_pathv[0][strlen(g.gl_pathv[0]) - 1] == '/') {
|
||||
simple_mode = 1;
|
||||
if (chdir(uwsgi.emperor_dir)) {
|
||||
@@ -388,6 +402,7 @@ reconnect:
|
||||
|
||||
if (!config) {
|
||||
uwsgi_log("problem with RabbitMQ server, trying reconnection...\n");
|
||||
event_queue_del_fd(emperor_queue, amqp_fd, event_queue_read());
|
||||
close(amqp_fd);
|
||||
amqp_fd = -1;
|
||||
goto reconnect;
|
||||
@@ -478,6 +493,7 @@ reconnect:
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unrecognized event on fd %d\n", interesting_fd);
|
||||
event_queue_del_fd(emperor_queue, interesting_fd, event_queue_read());
|
||||
close(interesting_fd);
|
||||
}
|
||||
}
|
||||
@@ -520,7 +536,7 @@ reconnect:
|
||||
closedir(dir);
|
||||
}
|
||||
else {
|
||||
if (glob(uwsgi.emperor_dir, GLOB_MARK, NULL, &g)) {
|
||||
if (glob(uwsgi.emperor_dir, GLOB_MARK|GLOB_NOCHECK, NULL, &g)) {
|
||||
uwsgi_error("glob()");
|
||||
continue;
|
||||
}
|
||||
@@ -569,6 +585,12 @@ reconnect:
|
||||
has_children++;
|
||||
}
|
||||
|
||||
if (uwsgi.notify) {
|
||||
if (snprintf(notification_message, 64, "The Emperor is governing %d vassals", has_children) >= 34) {
|
||||
uwsgi_notify(notification_message);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_children) {
|
||||
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
|
||||
}
|
||||
@@ -620,6 +642,7 @@ reconnect:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef IFLA_NET_NS_PID
|
||||
#ifdef CLONE_NEWNET
|
||||
|
||||
#define NLMSG_TAIL(nmsg) \
|
||||
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
|
||||
|
||||
@@ -68,11 +68,7 @@ void *simple_loop(void *arg1) {
|
||||
// initialize the main event queue to monitor sockets
|
||||
uwsgi.main_queue = event_queue_init();
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
event_queue_add_fd_read(uwsgi.main_queue, uwsgi_sock->fd);
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
uwsgi_add_sockets_to_queue(uwsgi.main_queue);
|
||||
|
||||
if (uwsgi.signal_socket > -1) {
|
||||
event_queue_add_fd_read(uwsgi.main_queue, uwsgi.signal_socket);
|
||||
@@ -94,9 +90,7 @@ void *simple_loop(void *arg1) {
|
||||
uwsgi_close_request(wsgi_req);
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
//never here
|
||||
// end of the loop
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -202,8 +196,7 @@ void *zeromq_loop(void *arg1) {
|
||||
}
|
||||
|
||||
|
||||
pthread_exit(NULL);
|
||||
//never here
|
||||
// end of the loop
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void uwsgi_restore_auto_snapshot(int signum) {
|
||||
|
||||
if (uwsgi.workers[1].snapshot > 0) {
|
||||
uwsgi.restore_snapshot = 1;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("[WARNING] no snapshot available\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void expire_rb_timeouts(struct rb_root *root) {
|
||||
|
||||
time_t current = time(NULL);
|
||||
@@ -85,8 +96,11 @@ void get_linux_tcp_info(int fd) {
|
||||
if (!uwsgi.shared->ti.tcpi_sacked) {
|
||||
return;
|
||||
}
|
||||
|
||||
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS] = 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]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,16 +135,14 @@ void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t val
|
||||
|
||||
void master_loop(char **argv, char **environ) {
|
||||
|
||||
uint64_t master_cycles = 0;
|
||||
uint64_t tmp_counter;
|
||||
|
||||
char log_buf[4096];
|
||||
|
||||
time_t current_time = time(NULL);
|
||||
|
||||
struct timeval last_respawn;
|
||||
int last_respawn_rate = 0;
|
||||
|
||||
pid_t pid;
|
||||
int pid_found = 0;
|
||||
|
||||
pid_t diedpid;
|
||||
@@ -143,6 +155,9 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
|
||||
time_t last_request_timecheck = 0;
|
||||
uint64_t last_request_count = 0;
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
struct sockaddr_in udp_client;
|
||||
socklen_t udp_len;
|
||||
@@ -174,12 +189,22 @@ void master_loop(char **argv, char **environ) {
|
||||
struct rb_root *rb_timers = uwsgi_init_rb_timer();
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
uwsgi.current_time = time(NULL);
|
||||
|
||||
uwsgi_unix_signal(SIGHUP, grace_them_all);
|
||||
uwsgi_unix_signal(SIGTERM, reap_them_all);
|
||||
if (uwsgi.die_on_term) {
|
||||
uwsgi_unix_signal(SIGTERM, kill_them_all);
|
||||
uwsgi_unix_signal(SIGQUIT, reap_them_all);
|
||||
}
|
||||
else {
|
||||
uwsgi_unix_signal(SIGTERM, reap_them_all);
|
||||
uwsgi_unix_signal(SIGQUIT, kill_them_all);
|
||||
}
|
||||
uwsgi_unix_signal(SIGINT, kill_them_all);
|
||||
uwsgi_unix_signal(SIGQUIT, kill_them_all);
|
||||
uwsgi_unix_signal(SIGUSR1, stats);
|
||||
if (uwsgi.auto_snapshot) {
|
||||
uwsgi_unix_signal(SIGURG, uwsgi_restore_auto_snapshot);
|
||||
}
|
||||
|
||||
|
||||
uwsgi.master_queue = event_queue_init();
|
||||
@@ -214,6 +239,12 @@ void master_loop(char **argv, char **environ) {
|
||||
event_queue_add_fd_read(uwsgi.master_queue, udp_fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.cheap) {
|
||||
uwsgi_add_sockets_to_queue(uwsgi.master_queue);
|
||||
uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MULTICAST
|
||||
if (uwsgi.cluster) {
|
||||
|
||||
@@ -376,29 +407,46 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ready_to_die >= uwsgi.numproc && uwsgi.to_hell) {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
kill(uwsgi.shared->spooler_pid, SIGKILL);
|
||||
uwsgi_log( "killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
|
||||
if (uwsgi.respawn_workers) {
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi_respawn_worker(i)) return;
|
||||
}
|
||||
|
||||
#endif
|
||||
uwsgi.respawn_workers = 0;
|
||||
}
|
||||
if (uwsgi.restore_snapshot) {
|
||||
uwsgi_log("[snapshot] restoring workers...\n");
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].pid == 0) continue;
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
}
|
||||
if (uwsgi.auto_snapshot > 0 && i > uwsgi.auto_snapshot) {
|
||||
uwsgi.workers[i].pid = 0;
|
||||
uwsgi.workers[i].snapshot = 0;
|
||||
}
|
||||
else {
|
||||
uwsgi.workers[i].pid = uwsgi.workers[i].snapshot;
|
||||
uwsgi.workers[i].snapshot = 0;
|
||||
kill(uwsgi.workers[i].pid, SIGURG);
|
||||
uwsgi_log( "Restored uWSGI worker %d (pid: %d)\n", i, (int) uwsgi.workers[i].pid);
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.restore_snapshot = 0;
|
||||
continue;
|
||||
}
|
||||
if ((uwsgi.cheap || ready_to_die >= uwsgi.numproc) && uwsgi.to_hell) {
|
||||
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
|
||||
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
|
||||
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
|
||||
}
|
||||
|
||||
// TODO kill all the gateways
|
||||
uwsgi_log( "goodbye to uWSGI.\n");
|
||||
exit(0);
|
||||
}
|
||||
if (ready_to_reload >= uwsgi.numproc && uwsgi.to_heaven) {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
kill(uwsgi.shared->spooler_pid, SIGKILL);
|
||||
uwsgi_log( "wait4() the spooler with pid %d...", uwsgi.shared->spooler_pid);
|
||||
diedpid = waitpid(uwsgi.shared->spooler_pid, &waitpid_status, 0);
|
||||
uwsgi_log( "done.");
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( (uwsgi.cheap || ready_to_reload >= uwsgi.numproc) && uwsgi.to_heaven) {
|
||||
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
|
||||
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
|
||||
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
|
||||
@@ -454,14 +502,17 @@ void master_loop(char **argv, char **environ) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.numproc > 0 || uwsgi.gateways_cnt > 0 || ushared->daemons_cnt > 0) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
if (!uwsgi.cheap) {
|
||||
|
||||
if (uwsgi.numproc > 0 || uwsgi.gateways_cnt > 0 || ushared->daemons_cnt > 0) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!master_has_children) {
|
||||
diedpid = 0;
|
||||
@@ -549,8 +600,8 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
// check uwsgi-cron table
|
||||
if (ushared->cron_cnt) {
|
||||
current_time = time(NULL);
|
||||
uwsgi_cron_delta = localtime( ¤t_time );
|
||||
uwsgi.current_time = time(NULL);
|
||||
uwsgi_cron_delta = localtime( &uwsgi.current_time );
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
@@ -601,9 +652,9 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
|
||||
// date match, signal it ?
|
||||
if (current_time - ucron->last_job > 60) {
|
||||
if (uwsgi.current_time - ucron->last_job > 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = current_time;
|
||||
ucron->last_job = uwsgi.current_time;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,6 +685,9 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (uwsgi.log_socket) {
|
||||
sendto(uwsgi.log_socket_fd, log_buf, rlen, 0, &uwsgi.log_socket_addr->sa, uwsgi.log_socket_size);
|
||||
}
|
||||
// TODO allow uwsgi.logger = func
|
||||
}
|
||||
}
|
||||
@@ -664,6 +718,25 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.cheap) {
|
||||
int found = 0 ;
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
if (interesting_fd == uwsgi_sock->fd) {
|
||||
found = 1;
|
||||
uwsgi.cheap = 0;
|
||||
uwsgi_del_sockets_from_queue(uwsgi.master_queue);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi_respawn_worker(i)) return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
if (found) continue;
|
||||
}
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp_addr && interesting_fd == snmp_fd) {
|
||||
udp_len = sizeof(udp_client);
|
||||
@@ -826,7 +899,7 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
current_time = time(NULL);
|
||||
uwsgi.current_time = time(NULL);
|
||||
// checking logsize
|
||||
if (uwsgi.logfile) {
|
||||
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
|
||||
@@ -844,25 +917,49 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
|
||||
|
||||
master_cycles++;
|
||||
uwsgi.master_cycles++;
|
||||
|
||||
// recalculate requests counter on race conditions risky configurations
|
||||
// a bit of inaccuracy is better than locking;)
|
||||
|
||||
if (uwsgi.numproc > 1) {
|
||||
tmp_counter = 0;
|
||||
for(i=1;i<uwsgi.numproc+1;i++) {
|
||||
for(i=1;i<uwsgi.numproc+1;i++)
|
||||
tmp_counter += uwsgi.workers[i].requests;
|
||||
}
|
||||
uwsgi.workers[0].requests = tmp_counter;
|
||||
}
|
||||
|
||||
if (uwsgi.idle > 0 && !uwsgi.cheap) {
|
||||
uwsgi.current_time = time(NULL);
|
||||
if (!last_request_timecheck) last_request_timecheck = uwsgi.current_time;
|
||||
if (last_request_count != uwsgi.workers[0].requests) {
|
||||
last_request_timecheck = uwsgi.current_time;
|
||||
last_request_count = uwsgi.workers[0].requests;
|
||||
}
|
||||
else if (uwsgi.current_time - last_request_timecheck > uwsgi.idle) {
|
||||
uwsgi_log("workers have been inactive for more than %d seconds\n", uwsgi.idle);
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (uwsgi.workers[i].pid == 0) continue;
|
||||
kill(uwsgi.workers[i].pid, SIGKILL);
|
||||
if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// remove expired cache items TODO use rb_tree timeouts
|
||||
if (uwsgi.cache_max_items > 0) {
|
||||
for(i=0;i< (int)uwsgi.cache_max_items;i++) {
|
||||
uwsgi_wlock(uwsgi.cache_lock);
|
||||
if (uwsgi.cache_items[i].expires) {
|
||||
if (uwsgi.cache_items[i].expires < (uint64_t) current_time) {
|
||||
if (uwsgi.cache_items[i].expires < (uint64_t) uwsgi.current_time) {
|
||||
uwsgi_cache_del(uwsgi.cache_items[i].key, uwsgi.cache_items[i].keysize);
|
||||
}
|
||||
}
|
||||
@@ -888,7 +985,7 @@ void master_loop(char **argv, char **environ) {
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
/* first check for harakiri */
|
||||
if (uwsgi.workers[i].harakiri > 0) {
|
||||
if (uwsgi.workers[i].harakiri < (time_t) current_time) {
|
||||
if (uwsgi.workers[i].harakiri < (time_t) uwsgi.current_time) {
|
||||
/* first try to invoke the harakiri() custom handler */
|
||||
/* TODO */
|
||||
/* then brutally kill the worker */
|
||||
@@ -942,37 +1039,15 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
// check for cluster nodes
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
struct uwsgi_cluster_node *ucn = &uwsgi.shared->nodes[i];
|
||||
|
||||
if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_STATIC && ucn->status == UWSGI_NODE_FAILED) {
|
||||
// should i retry ?
|
||||
if (master_cycles % ucn->errors == 0) {
|
||||
if (!uwsgi_ping_node(i, uwsgi.wsgi_req)) {
|
||||
ucn->status = UWSGI_NODE_OK;
|
||||
uwsgi_log( "re-enabled cluster node %d/%s\n", i, ucn->name);
|
||||
}
|
||||
else {
|
||||
ucn->errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_DYNAMIC) {
|
||||
// if the last_seen attr is higher than 30 secs ago, mark the node as dead
|
||||
if ( (current_time - ucn->last_seen) > 30) {
|
||||
uwsgi_log_verbose("no presence announce in the last 30 seconds by node %s, i assume it is dead.\n", ucn->name);
|
||||
ucn->name[0] = 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
master_check_cluster_nodes();
|
||||
|
||||
// reannounce myself every 10 cycles
|
||||
if (uwsgi.cluster && uwsgi.cluster_fd >= 0 && !uwsgi.cluster_nodes && (master_cycles % 10) == 0) {
|
||||
if (uwsgi.cluster && uwsgi.cluster_fd >= 0 && !uwsgi.cluster_nodes && (uwsgi.master_cycles % 10) == 0) {
|
||||
uwsgi_cluster_add_me();
|
||||
}
|
||||
|
||||
// resubscribe every 10 cycles
|
||||
if (uwsgi.subscriptions_cnt > 0 && ((master_cycles % 10) == 0 || master_cycles == 1)) {
|
||||
if (uwsgi.subscriptions_cnt > 0 && ((uwsgi.master_cycles % 10) == 0 || uwsgi.master_cycles == 1)) {
|
||||
for(i=0;i<uwsgi.subscriptions_cnt;i++) {
|
||||
uwsgi_subscribe(uwsgi.subscriptions[i]);
|
||||
}
|
||||
@@ -980,13 +1055,13 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
#endif
|
||||
|
||||
if (uwsgi.cache_store && uwsgi.cache_filesize && uwsgi.cache_store_sync && ((master_cycles % uwsgi.cache_store_sync) == 0)) {
|
||||
if (uwsgi.cache_store && uwsgi.cache_filesize && uwsgi.cache_store_sync && ((uwsgi.master_cycles % uwsgi.cache_store_sync) == 0)) {
|
||||
if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((master_cycles % uwsgi.queue_store_sync) == 0)) {
|
||||
if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((uwsgi.master_cycles % uwsgi.queue_store_sync) == 0)) {
|
||||
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
@@ -1002,7 +1077,7 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
else {
|
||||
if (tr_st.st_mtime > uwsgi.last_touch_reload_mtime) {
|
||||
uwsgi_log("*** %s has been touched... grace them all !!! ***\n");
|
||||
uwsgi_log("*** %s has been touched... grace them all !!! ***\n", uwsgi.touch_reload);
|
||||
grace_them_all(0);
|
||||
}
|
||||
}
|
||||
@@ -1015,6 +1090,9 @@ void master_loop(char **argv, char **environ) {
|
||||
continue;
|
||||
|
||||
}
|
||||
// reload gateways and daemons only on normal workflow
|
||||
if (!uwsgi.to_heaven && !uwsgi.to_hell) {
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
/* reload the spooler */
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
@@ -1026,8 +1104,6 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// reload gateways and daemons only on normal workflow
|
||||
if (!uwsgi.to_heaven && !uwsgi.to_hell) {
|
||||
/* reload the gateways */
|
||||
// TODO reload_gateway(diedpid);
|
||||
pid_found = 0;
|
||||
@@ -1053,6 +1129,7 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
|
||||
if (pid_found) continue;
|
||||
|
||||
}
|
||||
|
||||
/* What happens here ?
|
||||
@@ -1101,9 +1178,16 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
gettimeofday(&last_respawn, NULL);
|
||||
if (last_respawn.tv_sec == uwsgi.respawn_delta) {
|
||||
uwsgi_log( "worker respawning too fast !!! i have to sleep a bit...\n");
|
||||
/* TODO, user configurable fork throttler */
|
||||
sleep(2);
|
||||
last_respawn_rate++;
|
||||
if (last_respawn_rate > uwsgi.numproc) {
|
||||
uwsgi_log( "worker respawning too fast !!! i have to sleep a bit...\n");
|
||||
/* TODO, user configurable fork throttler */
|
||||
sleep(2);
|
||||
last_respawn_rate = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
last_respawn_rate = 0;
|
||||
}
|
||||
gettimeofday(&last_respawn, NULL);
|
||||
uwsgi.respawn_delta = last_respawn.tv_sec;
|
||||
@@ -1115,27 +1199,9 @@ void master_loop(char **argv, char **environ) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
// 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].harakiri = 0;
|
||||
uwsgi.workers[uwsgi.mywid].requests = 0;
|
||||
uwsgi.workers[uwsgi.mywid].failed_requests = 0;
|
||||
uwsgi.workers[uwsgi.mywid].respawn_count++;
|
||||
uwsgi.workers[uwsgi.mywid].last_spawn = current_time;
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
|
||||
break;
|
||||
}
|
||||
else if (pid < 1) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "Respawned uWSGI worker %d (new pid: %d)\n", uwsgi.mywid, (int) pid);
|
||||
}
|
||||
if (uwsgi_respawn_worker(uwsgi.mywid)) return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void master_check_cluster_nodes() {
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
struct uwsgi_cluster_node *ucn = &uwsgi.shared->nodes[i];
|
||||
|
||||
if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_STATIC && ucn->status == UWSGI_NODE_FAILED) {
|
||||
// should i retry ?
|
||||
if (uwsgi.master_cycles % ucn->errors == 0) {
|
||||
if (!uwsgi_ping_node(i, uwsgi.wsgi_req)) {
|
||||
ucn->status = UWSGI_NODE_OK;
|
||||
uwsgi_log( "re-enabled cluster node %d/%s\n", i, ucn->name);
|
||||
}
|
||||
else {
|
||||
ucn->errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_DYNAMIC) {
|
||||
// if the last_seen attr is higher than 30 secs ago, mark the node as dead
|
||||
if ( (uwsgi.current_time - ucn->last_seen) > 30) {
|
||||
uwsgi_log_verbose("no presence announce in the last 30 seconds by node %s, i assume it is dead.\n", ucn->name);
|
||||
ucn->name[0] = 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_respawn_worker(int wid) {
|
||||
|
||||
int respawns = uwsgi.workers[wid].respawn_count;
|
||||
|
||||
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;
|
||||
uwsgi.workers[uwsgi.mywid].harakiri = 0;
|
||||
uwsgi.workers[uwsgi.mywid].requests = 0;
|
||||
uwsgi.workers[uwsgi.mywid].failed_requests = 0;
|
||||
uwsgi.workers[uwsgi.mywid].respawn_count++;
|
||||
uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
|
||||
return 1;
|
||||
}
|
||||
else if (pid < 1) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
if (respawns > 0) {
|
||||
uwsgi_log( "Respawned uWSGI worker %d (new pid: %d)\n", uwsgi.mywid, (int) pid);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("spawned uWSGI worker %d (pid: %d, cores: %d)\n", wid, pid, uwsgi.cores);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+11
-1
@@ -2,6 +2,16 @@ import uwsgi
|
||||
import struct
|
||||
import sys
|
||||
|
||||
print sys.argv
|
||||
if len(sys.argv) == 3:
|
||||
chunks = uwsgi.send_message(sys.argv[1], 10, int(sys.argv[2]), '')
|
||||
|
||||
print uwsgi.send_uwsgi_message(sys.argv[1], int(sys.argv[2]), 10, int(sys.argv[3]), struct.pack("i", int(sys.argv[4])))
|
||||
pkt = ''
|
||||
|
||||
for chunk in chunks:
|
||||
pkt += chunk
|
||||
|
||||
print "%d = %d" % (int(sys.argv[2]), struct.unpack("I", pkt)[0])
|
||||
elif len(sys.argv) == 4:
|
||||
uwsgi.send_message(sys.argv[1], 10, int(sys.argv[2]), struct.pack("I", int(sys.argv[3])))
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
|
||||
|
||||
void uwsgi_systemd_notify(char *message) {
|
||||
|
||||
struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object;
|
||||
struct iovec *iovec = msghdr->msg_iov;
|
||||
|
||||
iovec[0].iov_base = "STATUS=";
|
||||
iovec[0].iov_len = 7;
|
||||
|
||||
iovec[1].iov_base = message;
|
||||
iovec[1].iov_len = strlen(message);
|
||||
|
||||
iovec[2].iov_base = "\n";
|
||||
iovec[2].iov_len = 1;
|
||||
|
||||
msghdr->msg_iovlen = 3;
|
||||
|
||||
sendmsg(uwsgi.notification_fd, msghdr, 0);
|
||||
}
|
||||
|
||||
void uwsgi_systemd_notify_ready(void) {
|
||||
|
||||
struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object;
|
||||
struct iovec *iovec = msghdr->msg_iov;
|
||||
|
||||
iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n";
|
||||
iovec[0].iov_len = 30;
|
||||
|
||||
msghdr->msg_iovlen = 1;
|
||||
|
||||
sendmsg(uwsgi.notification_fd, msghdr, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_systemd_init(char *systemd_socket) {
|
||||
|
||||
struct sockaddr_un *sd_sun;
|
||||
struct msghdr *msghdr;
|
||||
|
||||
uwsgi.notification_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
if (uwsgi.notification_fd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
return;
|
||||
}
|
||||
|
||||
sd_sun = uwsgi_malloc(sizeof(struct sockaddr_un));
|
||||
memset(sd_sun, 0, sizeof(struct sockaddr_un));
|
||||
sd_sun->sun_family = AF_UNIX;
|
||||
strncpy(sd_sun->sun_path, systemd_socket, sizeof(sd_sun->sun_path));
|
||||
if (sd_sun->sun_path[0] == '@') sd_sun->sun_path[0] = 0;
|
||||
|
||||
msghdr = uwsgi_malloc(sizeof(struct msghdr));
|
||||
memset(msghdr, 0, sizeof(struct msghdr));
|
||||
|
||||
msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec)*3);
|
||||
memset(msghdr->msg_iov, 0, sizeof(struct iovec)*3);
|
||||
|
||||
msghdr->msg_name = sd_sun;
|
||||
msghdr->msg_namelen = sizeof(struct sockaddr_un);
|
||||
|
||||
uwsgi.notification_object = msghdr;
|
||||
|
||||
uwsgi.notify = uwsgi_systemd_notify;
|
||||
uwsgi.notify_ready = uwsgi_systemd_notify_ready;
|
||||
|
||||
}
|
||||
@@ -1,28 +1,58 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
/* uwsgi ADMIN|10 */
|
||||
int uwsgi_request_admin(struct wsgi_request *wsgi_req) {
|
||||
|
||||
uint32_t opt_value = 0;
|
||||
int i;
|
||||
ssize_t len;
|
||||
|
||||
if (wsgi_req->uh.pktsize >= 4) {
|
||||
if (wsgi_req->uh.pktsize != 0 && wsgi_req->uh.pktsize != 4)
|
||||
return UWSGI_OK;
|
||||
|
||||
// write request
|
||||
if (wsgi_req->uh.pktsize == 4) {
|
||||
memcpy(&opt_value, wsgi_req->buffer, 4);
|
||||
// TODO: check endianess ?
|
||||
}
|
||||
|
||||
uwsgi_log( "setting internal option %d to %d\n", wsgi_req->uh.modifier2, opt_value);
|
||||
uwsgi.shared->options[wsgi_req->uh.modifier2] = opt_value;
|
||||
|
||||
// ACK
|
||||
wsgi_req->uh.modifier1 = 255;
|
||||
wsgi_req->uh.pktsize = 0;
|
||||
wsgi_req->uh.modifier2 = 1;
|
||||
|
||||
i = write(wsgi_req->poll.fd, wsgi_req, 4);
|
||||
if (i != 4) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
uwsgi_log( "setting internal option %d to %d\n", wsgi_req->uh.modifier2, opt_value);
|
||||
uwsgi.shared->options[wsgi_req->uh.modifier2] = opt_value;
|
||||
|
||||
// ACK
|
||||
wsgi_req->uh.modifier1 = 255;
|
||||
wsgi_req->uh.pktsize = 0;
|
||||
wsgi_req->uh.modifier2 = 1;
|
||||
len = write(wsgi_req->poll.fd, wsgi_req, 4);
|
||||
if (len != 4) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
}
|
||||
// get request
|
||||
else {
|
||||
uwsgi_log( "internal option %d = %d\n", wsgi_req->uh.modifier2, uwsgi.shared->options[wsgi_req->uh.modifier2]);
|
||||
|
||||
wsgi_req->uh.modifier1 = 10;
|
||||
wsgi_req->uh.pktsize = 4;
|
||||
len = write(wsgi_req->poll.fd, wsgi_req, 4);
|
||||
if (len != 4) {
|
||||
uwsgi_error("write()");
|
||||
return UWSGI_OK;
|
||||
}
|
||||
len = write(wsgi_req->poll.fd, (char *) &uwsgi.shared->options[wsgi_req->uh.modifier2], 4);
|
||||
if (len != 4) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_plugin admin_plugin = {
|
||||
|
||||
.name = "admin",
|
||||
.modifier1 = 10,
|
||||
.request = uwsgi_request_admin,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
NAME='admin'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['admin_plugin']
|
||||
+108
-49
@@ -18,6 +18,7 @@
|
||||
#define LONG_ARGS_FASTROUTER_USE_BASE 150004
|
||||
#define LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER 150005
|
||||
#define LONG_ARGS_FASTROUTER_TIMEOUT 150006
|
||||
#define LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT 150007
|
||||
|
||||
#define FASTROUTER_STATUS_FREE 0
|
||||
#define FASTROUTER_STATUS_CONNECTING 1
|
||||
@@ -28,25 +29,62 @@
|
||||
#define add_timeout(x) uwsgi_add_rb_timer(ufr.timeouts, time(NULL)+ufr.socket_timeout, x)
|
||||
#define del_timeout(x) rb_erase(&x->timeout->rbt, ufr.timeouts); free(x->timeout);
|
||||
|
||||
struct uwsgi_fastrouter_socket {
|
||||
char *name;
|
||||
int fd;
|
||||
struct uwsgi_fastrouter_socket *next;
|
||||
};
|
||||
|
||||
struct uwsgi_fastrouter {
|
||||
char *socket_name;
|
||||
int use_cache;
|
||||
int nevents;
|
||||
|
||||
char *pattern;
|
||||
int pattern_len;
|
||||
struct uwsgi_fastrouter_socket *sockets;
|
||||
|
||||
char *base;
|
||||
int base_len;
|
||||
int use_cache;
|
||||
int nevents;
|
||||
|
||||
char *subscription_server;
|
||||
struct uwsgi_dict *subscription_dict;
|
||||
int subscription_slot;
|
||||
|
||||
int socket_timeout;
|
||||
char *pattern;
|
||||
int pattern_len;
|
||||
|
||||
struct rb_root *timeouts;
|
||||
char *base;
|
||||
int base_len;
|
||||
|
||||
char *subscription_server;
|
||||
struct uwsgi_dict *subscription_dict;
|
||||
|
||||
int socket_timeout;
|
||||
|
||||
struct rb_root *timeouts;
|
||||
} ufr;
|
||||
|
||||
|
||||
static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) {
|
||||
|
||||
struct uwsgi_fastrouter_socket *uwsgi_sock = ufr.sockets, *old_uwsgi_sock;
|
||||
|
||||
if (!uwsgi_sock) {
|
||||
ufr.sockets = uwsgi_malloc(sizeof(struct uwsgi_fastrouter_socket));
|
||||
uwsgi_sock = ufr.sockets;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_sock) {
|
||||
old_uwsgi_sock = uwsgi_sock;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_fastrouter_socket));
|
||||
old_uwsgi_sock->next = uwsgi_sock;
|
||||
}
|
||||
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_fastrouter_socket));
|
||||
uwsgi_sock->name = name;
|
||||
|
||||
return uwsgi_sock;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct option fastrouter_options[] = {
|
||||
{"fastrouter", required_argument, 0, LONG_ARGS_FASTROUTER},
|
||||
{"fastrouter-use-cache", no_argument, &ufr.use_cache, 1},
|
||||
@@ -54,6 +92,7 @@ struct option fastrouter_options[] = {
|
||||
{"fastrouter-use-base", required_argument, 0, LONG_ARGS_FASTROUTER_USE_BASE},
|
||||
{"fastrouter-events", required_argument, 0, LONG_ARGS_FASTROUTER_EVENTS},
|
||||
{"fastrouter-subscription-server", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER},
|
||||
{"fastrouter-subscription-slot", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT},
|
||||
{"fastrouter-timeout", required_argument, 0, LONG_ARGS_FASTROUTER_TIMEOUT},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
@@ -163,7 +202,6 @@ struct fastrouter_session *alloc_fr_session() {
|
||||
void fastrouter_loop() {
|
||||
|
||||
int fr_queue;
|
||||
int fr_server = -1;
|
||||
int nevents;
|
||||
int interesting_fd;
|
||||
int new_connection;
|
||||
@@ -210,37 +248,43 @@ void fastrouter_loop() {
|
||||
fr_table[i] = NULL;
|
||||
}
|
||||
|
||||
if (ufr.socket_name[0] == '=') {
|
||||
int shared_socket = atoi(ufr.socket_name+1);
|
||||
if (shared_socket >= 0 && shared_socket < uwsgi.shared_sockets_cnt) {
|
||||
if (uwsgi.shared_sockets[shared_socket].name) {
|
||||
fr_server = uwsgi.shared_sockets[shared_socket].fd;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unable to use shared socket %d\n", shared_socket);
|
||||
fr_queue = event_queue_init();
|
||||
|
||||
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
|
||||
|
||||
while(ufr_sock) {
|
||||
if (ufr_sock->name[0] == '=') {
|
||||
int shared_socket = atoi(ufr_sock->name+1);
|
||||
if (shared_socket >= 0) {
|
||||
ufr_sock->fd = uwsgi_get_shared_socket_fd_by_num(shared_socket);
|
||||
if (ufr_sock->fd == -1) {
|
||||
uwsgi_log("unable to use shared socket %d\n", shared_socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tcp_port = strchr(ufr.socket_name, ':');
|
||||
if (tcp_port) {
|
||||
fr_server = bind_to_tcp(ufr.socket_name, uwsgi.listen_queue, tcp_port);
|
||||
}
|
||||
else {
|
||||
fr_server = bind_to_unix(ufr.socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
tcp_port = strchr(ufr_sock->name, ':');
|
||||
if (tcp_port) {
|
||||
ufr_sock->fd = bind_to_tcp(ufr_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
}
|
||||
else {
|
||||
ufr_sock->fd = bind_to_unix(ufr_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
}
|
||||
|
||||
event_queue_add_fd_read(fr_queue, ufr_sock->fd);
|
||||
ufr_sock = ufr_sock->next;
|
||||
}
|
||||
|
||||
fr_queue = event_queue_init();
|
||||
|
||||
events = event_queue_alloc(ufr.nevents);
|
||||
|
||||
event_queue_add_fd_read(fr_queue, fr_server);
|
||||
|
||||
if (ufr.subscription_server) {
|
||||
ufr_subserver = bind_to_udp(ufr.subscription_server, 0, 0);
|
||||
event_queue_add_fd_read(fr_queue, ufr_subserver);
|
||||
ufr.subscription_dict = uwsgi_dict_create(30, 0);
|
||||
if (!ufr.subscription_slot) ufr.subscription_slot = 30;
|
||||
ufr.subscription_dict = uwsgi_dict_create(ufr.subscription_slot, 0);
|
||||
}
|
||||
|
||||
if (ufr.pattern) {
|
||||
@@ -276,27 +320,39 @@ void fastrouter_loop() {
|
||||
interesting_fd = event_queue_interesting_fd(events, i);
|
||||
|
||||
|
||||
if (interesting_fd == fr_server) {
|
||||
new_connection = accept(fr_server, (struct sockaddr *) &fr_addr, &fr_addr_len);
|
||||
if (new_connection < 0) {
|
||||
continue;
|
||||
}
|
||||
int taken = 0;
|
||||
struct uwsgi_fastrouter_socket *uwsgi_sock = ufr.sockets;
|
||||
while(uwsgi_sock) {
|
||||
if (interesting_fd == uwsgi_sock->fd) {
|
||||
new_connection = accept(interesting_fd, (struct sockaddr *) &fr_addr, &fr_addr_len);
|
||||
if (new_connection < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fr_table[new_connection] = alloc_fr_session();
|
||||
fr_table[new_connection]->fd = new_connection;
|
||||
fr_table[new_connection]->instance_fd = -1;
|
||||
fr_table[new_connection]->status = FASTROUTER_STATUS_RECV_HDR;
|
||||
fr_table[new_connection]->h_pos = 0;
|
||||
fr_table[new_connection]->pos = 0;
|
||||
fr_table[new_connection]->instance_failed = 0;
|
||||
fr_table[new_connection]->instance_address_len = 0;
|
||||
fr_table[new_connection] = alloc_fr_session();
|
||||
fr_table[new_connection]->fd = new_connection;
|
||||
fr_table[new_connection]->instance_fd = -1;
|
||||
fr_table[new_connection]->status = FASTROUTER_STATUS_RECV_HDR;
|
||||
fr_table[new_connection]->h_pos = 0;
|
||||
fr_table[new_connection]->pos = 0;
|
||||
fr_table[new_connection]->instance_failed = 0;
|
||||
fr_table[new_connection]->instance_address_len = 0;
|
||||
|
||||
fr_table[new_connection]->timeout = add_timeout(fr_table[new_connection]);
|
||||
fr_table[new_connection]->timeout = add_timeout(fr_table[new_connection]);
|
||||
|
||||
event_queue_add_fd_read(fr_queue, new_connection);
|
||||
event_queue_add_fd_read(fr_queue, new_connection);
|
||||
taken = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
else if (interesting_fd == ufr_subserver) {
|
||||
|
||||
if (taken) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (interesting_fd == ufr_subserver) {
|
||||
len = recv(ufr_subserver, bbuf, 4096, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(fr_queue, ufr_subserver);
|
||||
@@ -437,7 +493,7 @@ void fastrouter_loop() {
|
||||
iov[1].iov_len = fr_session->uh.pktsize;
|
||||
|
||||
// fd passing: PERFORMANCE EXTREME BOOST !!!
|
||||
if (fr_session->pass_fd) {
|
||||
if (fr_session->pass_fd && !uwsgi.no_fd_passing) {
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = iov;
|
||||
@@ -532,7 +588,7 @@ void fastrouter_loop() {
|
||||
|
||||
int fastrouter_init() {
|
||||
|
||||
if (ufr.socket_name) {
|
||||
if (ufr.sockets) {
|
||||
|
||||
if (ufr.use_cache && !uwsgi.cache_max_items) {
|
||||
uwsgi_log("you need to create a uwsgi cache to use the fastrouter (add --cache <n>)\n");
|
||||
@@ -554,7 +610,7 @@ int fastrouter_opt(int i, char *optarg) {
|
||||
|
||||
switch(i) {
|
||||
case LONG_ARGS_FASTROUTER:
|
||||
ufr.socket_name = optarg;
|
||||
uwsgi_fastrouter_new_socket(generate_socket_name(optarg));
|
||||
return 1;
|
||||
case LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER:
|
||||
ufr.subscription_server = optarg;
|
||||
@@ -575,6 +631,9 @@ int fastrouter_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_FASTROUTER_TIMEOUT:
|
||||
ufr.socket_timeout = atoi(optarg);
|
||||
return -1;
|
||||
case LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT:
|
||||
ufr.subscription_slot = atoi(optarg);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -710,7 +710,7 @@ void http_loop() {
|
||||
|
||||
#ifndef __sun__
|
||||
// fd passing: PERFORMANCE EXTREME BOOST !!!
|
||||
if (uhttp_session->pass_fd && !uhttp_session->remains) {
|
||||
if (uhttp_session->pass_fd && !uhttp_session->remains && !uwsgi.no_fd_passing) {
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = uhttp_session->iov;
|
||||
|
||||
@@ -114,7 +114,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
uwsgi_log("%s = %s\n", PyString_AsString(k), PyString_AsString(env_value));
|
||||
|
||||
if (PyObject_SetItem(py_environ, k, env_value)) {
|
||||
uwsgi_log("cazzo\n");
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
@@ -521,6 +520,9 @@ PyObject *uwsgi_file_loader(void *arg1) {
|
||||
PyObject *wsgi_file_module, *wsgi_file_dict;
|
||||
PyObject *wsgi_file_callable;
|
||||
|
||||
char *callable = up.callable;
|
||||
if (!callable) callable = "application";
|
||||
|
||||
wsgi_file_module = uwsgi_pyimport_by_filename("uwsgi_wsgi_file", filename);
|
||||
// no need to check here for module import as it is already done by uwsgi_pyimport_by_file
|
||||
|
||||
@@ -530,7 +532,7 @@ PyObject *uwsgi_file_loader(void *arg1) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wsgi_file_callable = PyDict_GetItemString(wsgi_file_dict, "application");
|
||||
wsgi_file_callable = PyDict_GetItemString(wsgi_file_dict, callable);
|
||||
if (!wsgi_file_callable) {
|
||||
PyErr_Print();
|
||||
uwsgi_log( "unable to find \"application\" callable in file %s\n", filename);
|
||||
|
||||
@@ -428,6 +428,20 @@ void init_uwsgi_embedded_module() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject *uwsgi_py_version_info = PyTuple_New(5);
|
||||
|
||||
PyTuple_SetItem(uwsgi_py_version_info, 0, PyInt_FromLong(UWSGI_VERSION_BASE));
|
||||
PyTuple_SetItem(uwsgi_py_version_info, 1, PyInt_FromLong(UWSGI_VERSION_MAJOR));
|
||||
PyTuple_SetItem(uwsgi_py_version_info, 2, PyInt_FromLong(UWSGI_VERSION_MINOR));
|
||||
PyTuple_SetItem(uwsgi_py_version_info, 3, PyInt_FromLong(UWSGI_VERSION_REVISION));
|
||||
PyTuple_SetItem(uwsgi_py_version_info, 4, PyString_FromString(UWSGI_VERSION_CUSTOM));
|
||||
|
||||
if (PyDict_SetItemString(up.embedded_dict, "version_info", uwsgi_py_version_info)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (PyDict_SetItemString(up.embedded_dict, "hostname", PyString_FromStringAndSize(uwsgi.hostname, uwsgi.hostname_len))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
@@ -719,6 +733,7 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
return 1;
|
||||
|
||||
|
||||
#ifdef UWSGI_INI
|
||||
case LONG_ARGS_INI_PASTE:
|
||||
uwsgi.ini = optarg;
|
||||
if (uwsgi.ini[0] != '/') {
|
||||
@@ -728,6 +743,7 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
up.paste = uwsgi_concat2("config:", uwsgi.ini);
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_PASTE:
|
||||
up.paste = optarg;
|
||||
return 1;
|
||||
|
||||
@@ -1192,8 +1192,7 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
|
||||
}
|
||||
else {
|
||||
Py_DECREF(zero);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
return PyErr_Format(PyExc_ValueError, "spooler packet cannot be more than %d bytes", uwsgi.buffer_size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1555,7 +1554,6 @@ PyObject *uwsgi_Iter_next(PyObject * self) {
|
||||
ui->has_cl = 1;
|
||||
ui->size = uh.pktsize;
|
||||
ui->sent = 0;
|
||||
uwsgi_log("NEED TO READ %d\n", uh.pktsize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2209,8 +2207,10 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
// close connection on the worker
|
||||
fclose(wsgi_req->async_post);
|
||||
wsgi_req->fd_closed = 1;
|
||||
if (PyTuple_Size(args) == 0) {
|
||||
fclose(wsgi_req->async_post);
|
||||
wsgi_req->fd_closed = 1;
|
||||
}
|
||||
|
||||
clear:
|
||||
Py_INCREF(Py_None);
|
||||
@@ -2219,8 +2219,13 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
static PyMethodDef uwsgi_spooler_methods[] = {
|
||||
#ifdef PYTHREE
|
||||
{"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""},
|
||||
{"spool", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""},
|
||||
#else
|
||||
{"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_KEYWORDS, ""},
|
||||
{"spool", (PyCFunction) py_uwsgi_send_spool, METH_KEYWORDS, ""},
|
||||
#endif
|
||||
{"set_spooler_frequency", py_uwsgi_spooler_freq, METH_VARARGS, ""},
|
||||
{"spooler_jobs", py_uwsgi_spooler_jobs, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
@@ -2338,7 +2343,6 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"load_plugin", py_uwsgi_load_plugin, METH_VARARGS, ""},
|
||||
{"lock", py_uwsgi_lock, METH_VARARGS, ""},
|
||||
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
|
||||
{"send", py_uwsgi_send, METH_VARARGS, ""},
|
||||
{"cl", py_uwsgi_cl, METH_VARARGS, ""},
|
||||
|
||||
{"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""},
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#define HAS_NOT_PyFrame_GetLineNumber
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 2
|
||||
#define HAS_NOT_PyFrame_GetLineNumber
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION > 2
|
||||
#define PYTHREE
|
||||
#endif
|
||||
|
||||
@@ -103,7 +103,7 @@ static void uwsgi_Input_free(uwsgi_Input *self) {
|
||||
static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
long len = 0;
|
||||
size_t remains;
|
||||
size_t remains, tmp_pos = 0;
|
||||
ssize_t rlen;
|
||||
char *tmp_buf;
|
||||
PyObject *res;
|
||||
@@ -113,10 +113,24 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
}
|
||||
|
||||
// return empty string if no post_cl or pos >= post_cl
|
||||
if (!self->wsgi_req->post_cl || (size_t) self->pos >= self->wsgi_req->post_cl) {
|
||||
if ((!self->wsgi_req->post_cl || (size_t) self->pos >= self->wsgi_req->post_cl ) && !self->readline_pos) {
|
||||
return PyString_FromString("");
|
||||
}
|
||||
|
||||
// some residual data ?
|
||||
if (self->readline_pos && self->readline_size) {
|
||||
if (len > 0) {
|
||||
if ((size_t) len < (self->readline_size - self->readline_pos)) {
|
||||
res = PyString_FromStringAndSize(self->readline + self->readline_pos, len);
|
||||
self->readline_pos+=len;
|
||||
if (self->readline_pos >= self->readline_size) self->readline_pos = 0;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
self->readline_pos = 0;
|
||||
return PyString_FromStringAndSize(self->readline + self->readline_pos, self->readline_size - self->readline_pos);
|
||||
}
|
||||
|
||||
// return the whole input
|
||||
if (len <= 0) {
|
||||
remains = self->wsgi_req->post_cl;
|
||||
@@ -125,7 +139,7 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
remains = len ;
|
||||
}
|
||||
|
||||
if (remains + self->pos > self->wsgi_req->post_cl) {
|
||||
if (remains + self->pos > self->wsgi_req->post_cl) {
|
||||
remains = self->wsgi_req->post_cl - self->pos;
|
||||
}
|
||||
|
||||
@@ -134,7 +148,7 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
}
|
||||
|
||||
if (uwsgi.post_buffering > 0) {
|
||||
res = PyString_FromStringAndSize( self->wsgi_req->post_buffering_buf, remains);
|
||||
res = PyString_FromStringAndSize( self->wsgi_req->post_buffering_buf+self->pos, remains);
|
||||
self->pos += remains;
|
||||
return res;
|
||||
}
|
||||
@@ -143,23 +157,26 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
tmp_buf = uwsgi_malloc(remains);
|
||||
|
||||
if (uwsgi_waitfd(self->wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data");
|
||||
while(remains) {
|
||||
if (uwsgi_waitfd(self->wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data");
|
||||
}
|
||||
|
||||
rlen = read(self->wsgi_req->poll.fd, tmp_buf+tmp_pos, remains);
|
||||
if (rlen < 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data");
|
||||
}
|
||||
tmp_pos += rlen;
|
||||
remains -= rlen;
|
||||
}
|
||||
|
||||
rlen = read(self->wsgi_req->poll.fd, tmp_buf, remains);
|
||||
if (rlen < 0) {
|
||||
free(tmp_buf);
|
||||
UWSGI_GET_GIL
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data");
|
||||
}
|
||||
|
||||
self->pos += rlen;
|
||||
UWSGI_GET_GIL
|
||||
res = PyString_FromStringAndSize(tmp_buf, rlen);
|
||||
|
||||
self->pos += tmp_pos;
|
||||
res = PyString_FromStringAndSize(tmp_buf, tmp_pos);
|
||||
free(tmp_buf);
|
||||
return res;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
PyObject *headers, *head;
|
||||
PyObject *h_key, *h_value;
|
||||
int i, j;
|
||||
struct uwsgi_header uh;
|
||||
PyObject *exc_info = NULL;
|
||||
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
@@ -70,10 +69,8 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
wsgi_req->hvec[0].iov_len = wsgi_req->protocol_len;
|
||||
uh.pktsize = wsgi_req->hvec[0].iov_len;
|
||||
wsgi_req->hvec[1].iov_base = " ";
|
||||
wsgi_req->hvec[1].iov_len = 1;
|
||||
uh.pktsize += wsgi_req->hvec[1].iov_len;
|
||||
#ifdef PYTHREE
|
||||
wsgi_req->hvec[2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head));
|
||||
wsgi_req->hvec[2].iov_len = strlen(wsgi_req->hvec[2].iov_base);
|
||||
@@ -81,18 +78,15 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[2].iov_base = PyString_AsString(head);
|
||||
wsgi_req->hvec[2].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[2].iov_len;
|
||||
wsgi_req->status = uwsgi_str3_num(wsgi_req->hvec[2].iov_base);
|
||||
wsgi_req->hvec[3].iov_base = nl;
|
||||
wsgi_req->hvec[3].iov_len = NL_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[3].iov_len;
|
||||
}
|
||||
else {
|
||||
// drop http status on cgi mode
|
||||
base = 3;
|
||||
wsgi_req->hvec[0].iov_base = "Status: ";
|
||||
wsgi_req->hvec[0].iov_len = 8;
|
||||
uh.pktsize = wsgi_req->hvec[0].iov_len;
|
||||
#ifdef PYTHREE
|
||||
wsgi_req->hvec[1].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head));
|
||||
wsgi_req->hvec[1].iov_len = strlen(wsgi_req->hvec[1].iov_base);
|
||||
@@ -100,11 +94,9 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[1].iov_base = PyString_AsString(head);
|
||||
wsgi_req->hvec[1].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[1].iov_len;
|
||||
wsgi_req->status = uwsgi_str3_num(wsgi_req->hvec[1].iov_base);
|
||||
wsgi_req->hvec[2].iov_base = nl;
|
||||
wsgi_req->hvec[2].iov_len = NL_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[2].iov_len;
|
||||
}
|
||||
|
||||
headers = PyTuple_GetItem(args, 1);
|
||||
@@ -146,10 +138,8 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[j].iov_base = PyString_AsString(h_key);
|
||||
wsgi_req->hvec[j].iov_len = PyString_Size(h_key);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[j].iov_len;
|
||||
wsgi_req->hvec[j + 1].iov_base = h_sep;
|
||||
wsgi_req->hvec[j + 1].iov_len = H_SEP_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[j+1].iov_len;
|
||||
#ifdef PYTHREE
|
||||
wsgi_req->hvec[j + 2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_value));
|
||||
wsgi_req->hvec[j + 2].iov_len = strlen(wsgi_req->hvec[j + 2].iov_base);
|
||||
@@ -158,29 +148,63 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[j + 2].iov_len = PyString_Size(h_value);
|
||||
#endif
|
||||
|
||||
uh.pktsize += wsgi_req->hvec[j+2].iov_len;
|
||||
|
||||
wsgi_req->hvec[j + 3].iov_base = nl;
|
||||
wsgi_req->hvec[j + 3].iov_len = NL_SIZE;
|
||||
|
||||
uh.pktsize += wsgi_req->hvec[j+3].iov_len;
|
||||
//uwsgi_log( "%.*s: %.*s\n", wsgi_req->hvec[j].iov_len, (char *)wsgi_req->hvec[j].iov_base, wsgi_req->hvec[j+2].iov_len, (char *) wsgi_req->hvec[j+2].iov_base);
|
||||
}
|
||||
|
||||
j = (i * 4) + base;
|
||||
|
||||
struct uwsgi_string_list *ah = uwsgi.additional_headers;
|
||||
while(ah) {
|
||||
if (wsgi_req->header_cnt+1 <= uwsgi.max_vars) {
|
||||
wsgi_req->header_cnt++;
|
||||
wsgi_req->hvec[j].iov_base = ah->value;
|
||||
wsgi_req->hvec[j].iov_len = ah->len;
|
||||
j++;
|
||||
wsgi_req->hvec[j].iov_base = nl;
|
||||
wsgi_req->hvec[j].iov_len = NL_SIZE;
|
||||
j++;
|
||||
ah = ah->next;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("no more space in iovec. consider increasing max-vars...\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// \r\n
|
||||
j = (i * 4) + base;
|
||||
wsgi_req->hvec[j].iov_base = nl;
|
||||
wsgi_req->hvec[j].iov_len = NL_SIZE;
|
||||
|
||||
uh.pktsize += wsgi_req->hvec[j].iov_len;
|
||||
|
||||
#ifdef __sun__
|
||||
int remains = j + 1;
|
||||
int iov_size;
|
||||
struct iovec* iov_ptr = wsgi_req->hvec;
|
||||
ssize_t iov_ret;
|
||||
while(remains) {
|
||||
iov_size = UMIN(remains, IOV_MAX);
|
||||
UWSGI_RELEASE_GIL
|
||||
iov_ret = wsgi_req->socket->proto_writev_header(wsgi_req, iov_ptr, iov_size);
|
||||
UWSGI_GET_GIL
|
||||
if (iov_ret < 0) {
|
||||
uwsgi_error("writev()");
|
||||
}
|
||||
wsgi_req->headers_size += iov_ret;
|
||||
iov_ptr += iov_size;
|
||||
remains -= iov_size;
|
||||
}
|
||||
#else
|
||||
UWSGI_RELEASE_GIL
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, j + 1);
|
||||
UWSGI_GET_GIL
|
||||
if (wsgi_req->headers_size < 0) {
|
||||
uwsgi_error("writev()");
|
||||
}
|
||||
#endif
|
||||
|
||||
//uwsgi_log("%d %p\n", wsgi_req->poll.fd, up.wsgi_writeout);
|
||||
Py_INCREF(up.wsgi_writeout);
|
||||
|
||||
+2
-1
@@ -17,7 +17,7 @@ uint16_t proto_base_add_uwsgi_header(struct wsgi_request *wsgi_req, char *key, u
|
||||
key[i] = '_';
|
||||
}
|
||||
else {
|
||||
key[i] = toupper(key[i]);
|
||||
key[i] = toupper((int)key[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ uint16_t proto_base_add_uwsgi_var(struct wsgi_request * wsgi_req, char *key, uin
|
||||
|
||||
int uwsgi_proto_base_accept(struct wsgi_request *wsgi_req, int fd) {
|
||||
|
||||
wsgi_req->c_len = sizeof(struct sockaddr_un);
|
||||
return accept(fd, (struct sockaddr *) &wsgi_req->c_addr, (socklen_t *) & wsgi_req->c_len);
|
||||
}
|
||||
|
||||
|
||||
+10
-9
@@ -89,6 +89,8 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
|
||||
char *ptr = wsgi_req->proto_parser_buf;
|
||||
char *base = ptr;
|
||||
char *query_string = NULL;
|
||||
char ip[INET_ADDRSTRLEN+1];
|
||||
struct sockaddr_in *http_sin = (struct sockaddr_in *) &wsgi_req->c_addr;
|
||||
|
||||
// REQUEST_METHOD
|
||||
while (ptr < watermark) {
|
||||
@@ -146,15 +148,14 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
|
||||
// SERVER_PORT
|
||||
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, "3031", 4);
|
||||
|
||||
/*
|
||||
// REMOTE_ADDR
|
||||
if (inet_ntop(AF_INET, &h_session->ip_addr, h_session->ip, INET_ADDRSTRLEN)) {
|
||||
h_session->uh.pktsize += proto_base_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "REMOTE_ADDR", 11, h_session->ip, strlen(h_session->ip));
|
||||
}
|
||||
else {
|
||||
uwsgi_error("inet_ntop()");
|
||||
}
|
||||
*/
|
||||
// REMOTE_ADDR
|
||||
memset(ip, 0, INET_ADDRSTRLEN+1);
|
||||
if (inet_ntop(AF_INET, (void *) &http_sin->sin_addr.s_addr, ip, INET_ADDRSTRLEN)) {
|
||||
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, ip, strlen(ip));
|
||||
}
|
||||
else {
|
||||
uwsgi_error("inet_ntop()");
|
||||
}
|
||||
|
||||
//HEADERS
|
||||
base = ptr;
|
||||
|
||||
@@ -84,6 +84,9 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_OK;
|
||||
#endif
|
||||
|
||||
if (uwsgi.no_fd_passing)
|
||||
return UWSGI_OK;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&wsgi_req->msg);
|
||||
while (cmsg != NULL) {
|
||||
if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type && SCM_RIGHTS) {
|
||||
|
||||
+17
-1
@@ -1242,7 +1242,16 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
if (st.st_mtime <= ims) {
|
||||
wsgi_req->status = 304;
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_write_header(wsgi_req, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, " 304 Not Modified\r\n\r\n", 21);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, " 304 Not Modified\r\n", 19);
|
||||
|
||||
struct uwsgi_string_list *ah = uwsgi.additional_headers;
|
||||
while(ah) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ah->value, ah->len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1256,6 +1265,13 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_write_header(wsgi_req, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, " 200 OK\r\n", 9);
|
||||
|
||||
struct uwsgi_string_list *ah = uwsgi.additional_headers;
|
||||
while(ah) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ah->value, ah->len);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
if (uwsgi.file_serve_mode == 1) {
|
||||
wsgi_req->header_cnt = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Accel-Redirect: ", 18);
|
||||
|
||||
@@ -51,7 +51,7 @@ class uWSGIDistribution(Distribution):
|
||||
|
||||
|
||||
setup(name='uWSGI',
|
||||
version='0.9.8-dev',
|
||||
version=uc.uwsgi_version,
|
||||
description='The uWSGI server',
|
||||
author='Unbit',
|
||||
author_email='info@unbit.it',
|
||||
|
||||
@@ -6,6 +6,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
|
||||
int serverfd;
|
||||
struct sockaddr_un *uws_addr;
|
||||
socklen_t len;
|
||||
|
||||
// leave 1 byte for abstract namespace (108 linux -> 104 bsd/mac)
|
||||
if (strlen(socket_name) > 102) {
|
||||
@@ -13,6 +14,13 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (socket_name[0] == '@') {
|
||||
abstract_socket = 1;
|
||||
}
|
||||
else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
|
||||
abstract_socket = 1;
|
||||
}
|
||||
|
||||
uws_addr = malloc(sizeof(struct sockaddr_un));
|
||||
if (uws_addr == NULL) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -36,12 +44,24 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
}
|
||||
|
||||
uws_addr->sun_family = AF_UNIX;
|
||||
memcpy(uws_addr->sun_path + abstract_socket, socket_name, 102);
|
||||
if (socket_name[0] == '@') {
|
||||
memcpy(uws_addr->sun_path + abstract_socket, socket_name+1, UMIN(strlen(socket_name+1), 101));
|
||||
len = strlen(socket_name) + 1;
|
||||
}
|
||||
else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
|
||||
memcpy(uws_addr->sun_path + abstract_socket, socket_name+2, UMIN(strlen(socket_name+2), 101));
|
||||
len = strlen(socket_name+1) + 1;
|
||||
|
||||
}
|
||||
else {
|
||||
memcpy(uws_addr->sun_path + abstract_socket, socket_name, UMIN(strlen(socket_name), 102));
|
||||
len = strlen(socket_name);
|
||||
}
|
||||
|
||||
#ifdef __HAIKU__
|
||||
if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) {
|
||||
#else
|
||||
if (bind(serverfd, (struct sockaddr *) uws_addr, strlen(socket_name) + abstract_socket + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
|
||||
if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
|
||||
#endif
|
||||
uwsgi_error("bind()");
|
||||
uwsgi_nuclear_blast();
|
||||
@@ -251,11 +271,23 @@ int connect_to_unix(char *socket_name, int timeout, int async) {
|
||||
|
||||
struct pollfd uwsgi_poll;
|
||||
struct sockaddr_un uws_addr;
|
||||
socklen_t un_size = sizeof(struct sockaddr_un);
|
||||
|
||||
memset(&uws_addr, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
uws_addr.sun_family = AF_UNIX;
|
||||
memcpy(uws_addr.sun_path, socket_name, 102);
|
||||
|
||||
if (socket_name[0] == '@'){
|
||||
un_size = sizeof(uws_addr.sun_family) + strlen(socket_name) + 1;
|
||||
memcpy(uws_addr.sun_path+1, socket_name+1, UMIN(strlen(socket_name+1), 101));
|
||||
}
|
||||
else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
|
||||
un_size = sizeof(uws_addr.sun_family) + strlen(socket_name+1) + 1;
|
||||
memcpy(uws_addr.sun_path+1, socket_name+2, UMIN(strlen(socket_name+2), 101));
|
||||
}
|
||||
else {
|
||||
memcpy(uws_addr.sun_path, socket_name, UMIN(strlen(socket_name), 102));
|
||||
}
|
||||
|
||||
uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (uwsgi_poll.fd < 0) {
|
||||
@@ -265,7 +297,7 @@ int connect_to_unix(char *socket_name, int timeout, int async) {
|
||||
|
||||
uwsgi_poll.events = POLLIN;
|
||||
|
||||
if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &uws_addr, sizeof(struct sockaddr_un), timeout, async)) {
|
||||
if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &uws_addr, un_size, timeout, async)) {
|
||||
uwsgi_error("connect()");
|
||||
close(uwsgi_poll.fd);
|
||||
return -1;
|
||||
@@ -316,7 +348,6 @@ char *generate_socket_name(char *socket_name) {
|
||||
|
||||
char *asterisk = strchr(socket_name, '*');
|
||||
|
||||
char *new_socket;
|
||||
char *tcp_port;
|
||||
int i;
|
||||
char *ptr = socket_name;
|
||||
@@ -345,6 +376,10 @@ char *generate_socket_name(char *socket_name) {
|
||||
|
||||
if (asterisk) {
|
||||
|
||||
#ifndef UWSGI_HAS_IFADDRS
|
||||
uwsgi_log("your system does not support ifaddrs subsystem\n");
|
||||
#else
|
||||
char *new_socket;
|
||||
uwsgi_log("generate_socket_name(%s)\n", socket_name);
|
||||
// get all the AF_INET addresses available
|
||||
struct ifaddrs *ifap = NULL, *ifa, *ifaf;
|
||||
@@ -381,24 +416,69 @@ char *generate_socket_name(char *socket_name) {
|
||||
}
|
||||
|
||||
uwsgi_log("unable to find avalid socket address\n");
|
||||
#endif
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
return socket_name;
|
||||
}
|
||||
|
||||
socklen_t socket_to_un_addr(char *socket_name, struct sockaddr_un *sun_addr) {
|
||||
|
||||
size_t len = strlen(socket_name);
|
||||
|
||||
if (len > 102) {
|
||||
uwsgi_log("invalid UNIX socket address: %s\n", socket_name);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
memset(sun_addr, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
sun_addr->sun_family = AF_UNIX;
|
||||
|
||||
// abstract socket
|
||||
if (socket_name[0] == '@') {
|
||||
memcpy(sun_addr->sun_path+1, socket_name+1, UMIN(len-1, 101));
|
||||
len = strlen(socket_name) + 1;
|
||||
}
|
||||
else if (len > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
|
||||
memcpy(sun_addr->sun_path+1, socket_name+2, UMIN(len-2, 101));
|
||||
len = strlen(socket_name+1) + 1;
|
||||
}
|
||||
else {
|
||||
memcpy(sun_addr->sun_path, socket_name, UMIN(len, 102));
|
||||
}
|
||||
|
||||
return sizeof(sun_addr->sun_family)+len;
|
||||
}
|
||||
|
||||
socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *sin_addr) {
|
||||
|
||||
memset(sin_addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
sin_addr->sin_family = AF_INET;
|
||||
if (port) {
|
||||
port[0] = 0;
|
||||
sin_addr->sin_port = htons(atoi(port + 1));
|
||||
}
|
||||
|
||||
if (socket_name[0] == 0) {
|
||||
sin_addr->sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
|
||||
}
|
||||
|
||||
return sizeof(struct sockaddr_in);
|
||||
|
||||
}
|
||||
|
||||
int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
|
||||
int serverfd;
|
||||
struct sockaddr_in uws_addr;
|
||||
int reuse = 1;
|
||||
|
||||
memset(&uws_addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
uws_addr.sin_family = AF_INET;
|
||||
if (tcp_port) {
|
||||
tcp_port[0] = 0;
|
||||
uws_addr.sin_port = htons(atoi(tcp_port + 1));
|
||||
}
|
||||
socket_to_in_addr(socket_name, tcp_port, &uws_addr);
|
||||
|
||||
serverfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (serverfd < 0) {
|
||||
@@ -406,14 +486,6 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (socket_name[0] == 0) {
|
||||
uws_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
uws_addr.sin_addr.s_addr = inet_addr(socket_name);
|
||||
}
|
||||
|
||||
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
|
||||
uwsgi_error("setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
@@ -568,6 +640,48 @@ int uwsgi_get_socket_num(struct uwsgi_socket *uwsgi_sock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int uwsgi_get_shared_socket_num(struct uwsgi_socket *uwsgi_sock) {
|
||||
|
||||
int count = 0;
|
||||
struct uwsgi_socket *current_sock = uwsgi.shared_sockets;
|
||||
|
||||
while(current_sock) {
|
||||
if (uwsgi_sock == current_sock) {
|
||||
return count;
|
||||
}
|
||||
count++;
|
||||
current_sock = current_sock->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_socket *uwsgi_new_shared_socket(char *name) {
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.shared_sockets, *old_uwsgi_sock;
|
||||
|
||||
if (!uwsgi_sock) {
|
||||
uwsgi.shared_sockets = uwsgi_malloc(sizeof(struct uwsgi_socket));
|
||||
uwsgi_sock = uwsgi.shared_sockets;
|
||||
}
|
||||
else {
|
||||
while(uwsgi_sock) {
|
||||
old_uwsgi_sock = uwsgi_sock;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_socket));
|
||||
old_uwsgi_sock->next = uwsgi_sock;
|
||||
}
|
||||
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
|
||||
uwsgi_sock->name = name;
|
||||
|
||||
return uwsgi_sock;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_socket *uwsgi_new_socket(char *name) {
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets, *old_uwsgi_sock;
|
||||
@@ -597,6 +711,7 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
|
||||
socklen_t socket_type_len;
|
||||
union uwsgi_sockaddr_ptr gsa, isa;
|
||||
union uwsgi_sockaddr usa;
|
||||
int abstract = 0;
|
||||
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = &usa.sa;
|
||||
@@ -606,7 +721,8 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
|
||||
return;
|
||||
}
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
if (!strcmp(usa.sa_un.sun_path, uwsgi_sock->name)) {
|
||||
if (usa.sa_un.sun_path[0] == 0) abstract = 1;
|
||||
if (!strcmp(usa.sa_un.sun_path+abstract, uwsgi_sock->name+abstract)) {
|
||||
uwsgi_sock->fd = fd;
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
uwsgi_sock->bound = 1;
|
||||
@@ -691,3 +807,46 @@ struct uwsgi_socket *uwsgi_del_socket(struct uwsgi_socket *uwsgi_sock) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_get_shared_socket_fd_by_num(int num) {
|
||||
|
||||
int counter = 0;
|
||||
|
||||
struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.shared_sockets;
|
||||
|
||||
while(uwsgi_sock) {
|
||||
if (counter == num) {
|
||||
found_sock = uwsgi_sock;
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
if (found_sock) {
|
||||
return found_sock->fd;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void uwsgi_add_sockets_to_queue(int queue) {
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
event_queue_add_fd_read(queue, uwsgi_sock->fd);
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_del_sockets_from_queue(int queue) {
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
event_queue_del_fd(queue, uwsgi_sock->fd, event_queue_read());
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -126,10 +126,14 @@ void spooler() {
|
||||
|
||||
// asked by Marco Beri
|
||||
#ifdef __HAIKU__
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("lowering spooler priority to %d\n", B_LOW_PRIORITY);
|
||||
#endif
|
||||
set_thread_priority(find_thread(NULL), B_LOW_PRIORITY);
|
||||
#else
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("lowering spooler priority to %d\n", PRIO_MAX);
|
||||
#endif
|
||||
setpriority(PRIO_PROCESS, getpid(), PRIO_MAX);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ def application(env, start_response):
|
||||
start_response( '200 OK', [ ('Content-Type','text/html') ])
|
||||
start_time = time.time()
|
||||
for i in range(1,100000):
|
||||
uwsgi.green_schedule()
|
||||
uwsgi.suspend()
|
||||
# print every 100
|
||||
if i % 100 == 0:
|
||||
yield "<h1>%d</h1>\n" % i
|
||||
|
||||
+9
-2
@@ -5,12 +5,19 @@ def application(env, start_response):
|
||||
start_response('200 Ok', [('Content-type', 'text/plain')])
|
||||
#for x in env['wsgi.input']:
|
||||
# yield x
|
||||
return env['wsgi.input'].readlines()
|
||||
body = env['wsgi.input'].readline()
|
||||
print body
|
||||
body += env['wsgi.input'].read(100)
|
||||
body += env['wsgi.input'].read(100)
|
||||
body += env['wsgi.input'].read()
|
||||
return body
|
||||
else:
|
||||
start_response('200 Ok', [('Content-type', 'text/html')])
|
||||
return """
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="file" name="file" />
|
||||
<textarea name="pluto">
|
||||
</textarea>
|
||||
<input type="test" name="pippo" />
|
||||
<input type="submit" value="invia" />
|
||||
</form>
|
||||
"""
|
||||
|
||||
@@ -259,6 +259,50 @@ void log_zeromq(char *node) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void log_socket(char *socket_name) {
|
||||
|
||||
int family = AF_UNIX;
|
||||
|
||||
uwsgi.log_socket_addr = uwsgi_malloc(sizeof(union uwsgi_sockaddr));
|
||||
|
||||
char *colon = strchr(socket_name, ':');
|
||||
if (colon) {
|
||||
family = AF_INET;
|
||||
uwsgi.log_socket_size = socket_to_in_addr(socket_name, colon, &uwsgi.log_socket_addr->sa_in);
|
||||
}
|
||||
else {
|
||||
uwsgi.log_socket_size = socket_to_un_addr(socket_name, &uwsgi.log_socket_addr->sa_un);
|
||||
}
|
||||
|
||||
uwsgi.log_socket_fd = socket(family, SOCK_DGRAM, 0);
|
||||
if (uwsgi.log_socket_fd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
// create log connection with the master
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, uwsgi.shared->worker_log_pipe)) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_socket_nb(uwsgi.shared->worker_log_pipe[0]);
|
||||
uwsgi_socket_nb(uwsgi.shared->worker_log_pipe[1]);
|
||||
|
||||
if (uwsgi.shared->worker_log_pipe[1] != 1) {
|
||||
if (dup2(uwsgi.shared->worker_log_pipe[1], 1) < 0) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (dup2(1, 2) < 0) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void log_syslog(char *syslog_opts) {
|
||||
|
||||
@@ -371,69 +415,75 @@ void internal_server_error(struct wsgi_request *wsgi_req, char *message) {
|
||||
uwsgi.wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, message, strlen(message));
|
||||
}
|
||||
|
||||
void uwsgi_as_root() {
|
||||
|
||||
#ifdef __linux__
|
||||
void uwsgi_set_cgroup() {
|
||||
|
||||
char *cgroup_taskfile;
|
||||
int i;
|
||||
FILE *cgroup;
|
||||
char *cgroup_opt;
|
||||
|
||||
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);
|
||||
|
||||
for (i = 0; i < uwsgi.cgroup_opt_cnt; i++) {
|
||||
cgroup_opt = strchr(uwsgi.cgroup_opt[i], '=');
|
||||
if (!cgroup_opt) {
|
||||
cgroup_opt = strchr(uwsgi.cgroup_opt[i], ':');
|
||||
if (!cgroup_opt) {
|
||||
uwsgi_log("invalid cgroup-opt syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
cgroup_opt[0] = 0;
|
||||
cgroup_opt++;
|
||||
|
||||
cgroup_taskfile = uwsgi_concat3(uwsgi.cgroup, "/", uwsgi.cgroup_opt[i]);
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void uwsgi_as_root() {
|
||||
|
||||
|
||||
if (!getuid()) {
|
||||
if (!uwsgi.master_as_root && !uwsgi.uidname) {
|
||||
uwsgi_log("uWSGI running as root, you can use --uid/--gid/--chroot options\n");
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (uwsgi.cgroup) {
|
||||
if (mkdir(uwsgi.cgroup, S_IRWXU | S_IROTH | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
|
||||
uwsgi_log("using Linux cgroup %s\n", uwsgi.cgroup);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("created Linux cgroup %s\n", uwsgi.cgroup);
|
||||
}
|
||||
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\n", (int) getpid()) < 0) {
|
||||
uwsgi_log("could not set cgroup\n");
|
||||
exit(1);
|
||||
}
|
||||
fclose(cgroup);
|
||||
free(cgroup_taskfile);
|
||||
|
||||
for (i = 0; i < uwsgi.cgroup_opt_cnt; i++) {
|
||||
cgroup_opt = strchr(uwsgi.cgroup_opt[i], '=');
|
||||
if (!cgroup_opt) {
|
||||
cgroup_opt = strchr(uwsgi.cgroup_opt[i], ':');
|
||||
if (!cgroup_opt) {
|
||||
uwsgi_log("invalid cgroup-opt syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
cgroup_opt[0] = 0;
|
||||
cgroup_opt++;
|
||||
|
||||
cgroup_taskfile = uwsgi_concat3(uwsgi.cgroup, "/", uwsgi.cgroup_opt[i]);
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (uwsgi.chroot && !uwsgi.reloads) {
|
||||
if (!uwsgi.master_as_root)
|
||||
uwsgi_log("chroot() to %s\n", uwsgi.chroot);
|
||||
@@ -720,6 +770,9 @@ int wsgi_req_accept(struct wsgi_request *wsgi_req) {
|
||||
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 {
|
||||
uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
@@ -852,6 +905,7 @@ void uwsgi_log(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
char logpkt[4096];
|
||||
int rlen = 0;
|
||||
int ret;
|
||||
|
||||
struct timeval tv;
|
||||
char sftime[64];
|
||||
@@ -876,9 +930,21 @@ void uwsgi_log(const char *fmt, ...) {
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
rlen += vsnprintf(logpkt + rlen, 4096 - rlen, fmt, ap);
|
||||
ret = vsnprintf(logpkt + rlen, 4096 - rlen, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret >= 4096) {
|
||||
char *tmp_buf = uwsgi_malloc(rlen + ret + 1);
|
||||
memcpy(tmp_buf, logpkt, rlen);
|
||||
va_start(ap, fmt);
|
||||
ret = vsnprintf(tmp_buf + rlen, ret+1, fmt, ap);
|
||||
va_end(ap);
|
||||
rlen = write(2, tmp_buf, rlen+ret);
|
||||
free(tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
rlen+=ret;
|
||||
// do not check for errors
|
||||
rlen = write(2, logpkt, rlen);
|
||||
}
|
||||
@@ -2166,6 +2232,7 @@ struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list,
|
||||
}
|
||||
|
||||
uwsgi_string->value = value;
|
||||
uwsgi_string->len = strlen(value);
|
||||
uwsgi_string->next = NULL;
|
||||
|
||||
return uwsgi_string;
|
||||
@@ -2195,3 +2262,10 @@ void uwsgi_string_del_list(struct uwsgi_string_list **list, struct uwsgi_string_
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_sig_pause() {
|
||||
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigsuspend(&mask);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ static char *short_options = NULL;
|
||||
|
||||
static char *base_short_options = "s:p:t:x:d:l:v:b:mcaCTiMhrR:z:A:Q:Ly:";
|
||||
|
||||
UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
|
||||
UWSGI_DECLARE_EMBEDDED_PLUGINS;
|
||||
|
||||
static struct option long_base_options[] = {
|
||||
{"socket", required_argument, 0, 's'},
|
||||
{"protocol", required_argument, 0, LONG_ARGS_PROTOCOL},
|
||||
{"socket-protocol", required_argument, 0, LONG_ARGS_SOCKET_PROTOCOL},
|
||||
@@ -62,17 +64,21 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
|
||||
{"single-interpreter", no_argument, 0, 'i'},
|
||||
{"master", no_argument, 0, 'M'},
|
||||
{"emperor", required_argument, 0, LONG_ARGS_EMPEROR},
|
||||
{"early-emperor", no_argument, &uwsgi.early_emperor, 1},
|
||||
{"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},
|
||||
{"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},
|
||||
{"die-on-term", no_argument, &uwsgi.die_on_term, 1},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"usage", no_argument, 0, 'h'},
|
||||
{"reaper", no_argument, 0, 'r'},
|
||||
{"max-requests", required_argument, 0, 'R'},
|
||||
{"socket-timeout", required_argument, 0, 'z'},
|
||||
{"no-fd-passing", no_argument, &uwsgi.no_fd_passing, 1},
|
||||
{"sharedarea", required_argument, 0, 'A'},
|
||||
{"cache", required_argument, 0, LONG_ARGS_CACHE},
|
||||
{"cache-blocksize", required_argument, 0, LONG_ARGS_CACHE_BLOCKSIZE},
|
||||
@@ -154,11 +160,14 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
|
||||
{"logto", required_argument, 0, LONG_ARGS_LOGTO},
|
||||
{"logfile-chown", no_argument, &uwsgi.logfile_chown, 1},
|
||||
{"log-syslog", optional_argument, 0, LONG_ARGS_LOG_SYSLOG},
|
||||
{"log-socket", required_argument, 0, LONG_ARGS_LOG_SOCKET},
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
{"log-zeromq", required_argument, 0, LONG_ARGS_LOG_ZEROMQ},
|
||||
#endif
|
||||
{"log-master", no_argument, 0, LONG_ARGS_LOG_MASTER},
|
||||
{"logdate", optional_argument, 0, LONG_ARGS_LOG_DATE},
|
||||
{"log-date", optional_argument, 0, LONG_ARGS_LOG_DATE},
|
||||
{"log-prefix", optional_argument, 0, LONG_ARGS_LOG_DATE},
|
||||
{"log-zero", no_argument, 0, LONG_ARGS_LOG_ZERO},
|
||||
{"log-slow", required_argument, 0, LONG_ARGS_LOG_SLOW},
|
||||
{"log-4xx", no_argument, 0, LONG_ARGS_LOG_4xx},
|
||||
@@ -170,6 +179,8 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
|
||||
{"chdir", required_argument, 0, LONG_ARGS_CHDIR},
|
||||
{"chdir2", required_argument, 0, LONG_ARGS_CHDIR2},
|
||||
{"lazy", no_argument, &uwsgi.lazy, 1},
|
||||
{"cheap", no_argument, &uwsgi.cheap, 1},
|
||||
{"idle", required_argument, 0, LONG_ARGS_IDLE},
|
||||
{"mount", required_argument, 0, LONG_ARGS_MOUNT},
|
||||
{"grunt", no_argument, &uwsgi.grunt, 1},
|
||||
{"threads", required_argument, 0, LONG_ARGS_THREADS},
|
||||
@@ -178,6 +189,7 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
|
||||
#ifdef UWSGI_ROUTING
|
||||
{"routing", no_argument, &uwsgi.routing, 1},
|
||||
#endif
|
||||
{"add-header", required_argument, 0, LONG_ARGS_ADD_HEADER},
|
||||
{"check-static", required_argument, 0, LONG_ARGS_CHECK_STATIC},
|
||||
{"static-map", required_argument, 0, LONG_ARGS_STATIC_MAP},
|
||||
{"file-serve-mode", required_argument, 0, LONG_ARGS_FILE_SERVE_MODE},
|
||||
@@ -211,48 +223,48 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
|
||||
void uwsgi_configure(void) {
|
||||
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
struct option *aopt;
|
||||
char *val;
|
||||
struct option *aopt;
|
||||
char *val;
|
||||
int i;
|
||||
int is_retry;
|
||||
int found;
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
|
||||
if (uwsgi.exported_opts[i]->configured)
|
||||
continue;
|
||||
if (uwsgi.exported_opts[i]->configured)
|
||||
continue;
|
||||
|
||||
is_retry = 0;
|
||||
retry:
|
||||
retry:
|
||||
found = 0;
|
||||
lopt = uwsgi.long_options;;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
lopt = uwsgi.long_options;;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
|
||||
if (!strcmp(aopt->name, uwsgi.exported_opts[i]->key)) {
|
||||
if (!strcmp(aopt->name, uwsgi.exported_opts[i]->key)) {
|
||||
found = 1;
|
||||
val = uwsgi.exported_opts[i]->value;
|
||||
val = uwsgi.exported_opts[i]->value;
|
||||
|
||||
if (aopt->flag)
|
||||
*aopt->flag = aopt->val;
|
||||
else if (val) {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcasecmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
if (aopt->has_arg == no_argument) {
|
||||
if (!strcasecmp("false", val) || val[0] == '0') {
|
||||
lopt++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
if (aopt->flag)
|
||||
*aopt->flag = aopt->val;
|
||||
else if (val) {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcasecmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
if (aopt->has_arg == no_argument) {
|
||||
if (!strcasecmp("false", val) || val[0] == '0') {
|
||||
lopt++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
if (!found && uwsgi.autoload && !is_retry) {
|
||||
DIR *pdir;
|
||||
@@ -262,7 +274,7 @@ retry:
|
||||
uwsgi_fatal_error("opendir()");
|
||||
}
|
||||
while ((dp = readdir(pdir)) != NULL) {
|
||||
if (!strncmp("_plugin.so", dp->d_name+(strlen(dp->d_name)-10), 19)) {
|
||||
if (!strncmp("_plugin.so", dp->d_name + (strlen(dp->d_name) - 10), 19)) {
|
||||
if (uwsgi_load_plugin(-1, dp->d_name, uwsgi.exported_opts[i]->key, 2)) {
|
||||
uwsgi_log("option \"%s\" found in plugin %s\n", uwsgi.exported_opts[i]->key, dp->d_name);
|
||||
found = 1;
|
||||
@@ -279,7 +291,7 @@ retry:
|
||||
}
|
||||
closedir(pdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -325,26 +337,26 @@ void warn_pipe() {
|
||||
#ifdef UWSGI_THREADING
|
||||
// in threading mode we need to use the cancel pthread subsystem
|
||||
void wait_for_threads() {
|
||||
int i, ret;
|
||||
int i, ret;
|
||||
|
||||
pthread_mutex_lock(&uwsgi.six_feet_under_lock);
|
||||
for(i=0;i<uwsgi.threads;i++) {
|
||||
if (!pthread_equal(uwsgi.core[i]->thread_id, pthread_self())) {
|
||||
pthread_cancel(uwsgi.core[i]->thread_id);
|
||||
}
|
||||
}
|
||||
pthread_mutex_lock(&uwsgi.six_feet_under_lock);
|
||||
for (i = 0; i < uwsgi.threads; i++) {
|
||||
if (!pthread_equal(uwsgi.core[i]->thread_id, pthread_self())) {
|
||||
pthread_cancel(uwsgi.core[i]->thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
// wait for thread termination
|
||||
for(i=0;i<uwsgi.threads;i++) {
|
||||
if (!pthread_equal(uwsgi.core[i]->thread_id, pthread_self())) {
|
||||
ret = pthread_join(uwsgi.core[i]->thread_id, NULL);
|
||||
if (ret) {
|
||||
uwsgi_log("pthread_join() = %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
// wait for thread termination
|
||||
for (i = 0; i < uwsgi.threads; i++) {
|
||||
if (!pthread_equal(uwsgi.core[i]->thread_id, pthread_self())) {
|
||||
ret = pthread_join(uwsgi.core[i]->thread_id, NULL);
|
||||
if (ret) {
|
||||
uwsgi_log("pthread_join() = %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&uwsgi.six_feet_under_lock);
|
||||
pthread_mutex_unlock(&uwsgi.six_feet_under_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -360,7 +372,7 @@ void gracefully_kill(int signum) {
|
||||
if (!uwsgi.core[wsgi_req->async_id]->in_request) {
|
||||
exit(UWSGI_RELOAD_CODE);
|
||||
}
|
||||
return;
|
||||
return;
|
||||
// never here
|
||||
}
|
||||
#endif
|
||||
@@ -396,12 +408,35 @@ void goodbye_cruel_world() {
|
||||
void kill_them_all(int signum) {
|
||||
int i;
|
||||
uwsgi.to_hell = 1;
|
||||
|
||||
if (uwsgi.reload_mercy > 0) {
|
||||
uwsgi.master_mercy = time(NULL) + uwsgi.reload_mercy;
|
||||
}
|
||||
else {
|
||||
uwsgi.master_mercy = time(NULL) + 5;
|
||||
}
|
||||
|
||||
uwsgi_log("SIGINT/SIGQUIT received...killing workers...\n");
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].pid > 0)
|
||||
kill(uwsgi.workers[i].pid, SIGINT);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
kill(uwsgi.shared->spooler_pid, SIGKILL);
|
||||
uwsgi_log("killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (uwsgi.emperor_pid >= 0) {
|
||||
kill(uwsgi.emperor_pid, SIGKILL);
|
||||
waitpid(uwsgi.emperor_pid, &i, 0);
|
||||
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
@@ -415,12 +450,28 @@ void kill_them_all(int signum) {
|
||||
|
||||
void grace_them_all(int signum) {
|
||||
int i;
|
||||
uwsgi.to_heaven = 1;
|
||||
int waitpid_status;
|
||||
|
||||
if (!uwsgi.lazy)
|
||||
uwsgi.to_heaven = 1;
|
||||
|
||||
if (uwsgi.reload_mercy > 0) {
|
||||
uwsgi.master_mercy = time(NULL) + uwsgi.reload_mercy;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
kill(uwsgi.shared->spooler_pid, SIGKILL);
|
||||
uwsgi_log("killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.emperor_pid >= 0) {
|
||||
kill(uwsgi.emperor_pid, SIGKILL);
|
||||
waitpid(uwsgi.emperor_pid, &i, 0);
|
||||
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
@@ -434,10 +485,32 @@ void grace_them_all(int signum) {
|
||||
|
||||
uwsgi_log("...gracefully killing workers...\n");
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].pid > 0)
|
||||
if (uwsgi.auto_snapshot) {
|
||||
if (uwsgi.workers[i].snapshot > 0) {
|
||||
kill(uwsgi.workers[i].snapshot, SIGKILL);
|
||||
if (waitpid(uwsgi.workers[i].snapshot, &waitpid_status, 0) < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
}
|
||||
}
|
||||
if (uwsgi.workers[i].pid > 0) {
|
||||
if (uwsgi.auto_snapshot > 0 && i > uwsgi.auto_snapshot) {
|
||||
uwsgi.workers[i].snapshot = 0;
|
||||
kill(uwsgi.workers[i].pid, SIGHUP);
|
||||
}
|
||||
else {
|
||||
uwsgi.workers[i].snapshot = uwsgi.workers[i].pid;
|
||||
kill(uwsgi.workers[i].pid, SIGURG);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uwsgi.workers[i].pid > 0)
|
||||
kill(uwsgi.workers[i].pid, SIGHUP);
|
||||
}
|
||||
|
||||
if (uwsgi.auto_snapshot) {
|
||||
uwsgi.respawn_workers = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_nuclear_blast() {
|
||||
@@ -456,7 +529,9 @@ void uwsgi_nuclear_blast() {
|
||||
|
||||
void reap_them_all(int signum) {
|
||||
int i;
|
||||
uwsgi.to_heaven = 1;
|
||||
|
||||
if (!uwsgi.lazy)
|
||||
uwsgi.to_heaven = 1;
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
@@ -468,6 +543,12 @@ void reap_them_all(int signum) {
|
||||
kill(uwsgi.gateways[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
if (uwsgi.emperor_pid >= 0) {
|
||||
kill(uwsgi.emperor_pid, SIGKILL);
|
||||
waitpid(uwsgi.emperor_pid, &i, 0);
|
||||
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
|
||||
}
|
||||
|
||||
if (!uwsgi.workers)
|
||||
return;
|
||||
|
||||
@@ -488,6 +569,23 @@ void harakiri() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void snapshot_me(int signum) {
|
||||
// wakeup !!!
|
||||
if (uwsgi.snapshot) {
|
||||
uwsgi.snapshot = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) {
|
||||
wait_for_threads();
|
||||
}
|
||||
#endif
|
||||
uwsgi.snapshot = 1;
|
||||
uwsgi_log("[snapshot] process %d taken\n", (int) getpid());
|
||||
}
|
||||
|
||||
void stats(int signum) {
|
||||
//fix this for better logging(this cause races)
|
||||
struct uwsgi_app *ua = NULL;
|
||||
@@ -586,7 +684,7 @@ static void vacuum(void) {
|
||||
uwsgi_error("chdir()");
|
||||
}
|
||||
}
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->family == AF_UNIX) {
|
||||
if (unlink(uwsgi_sock->name)) {
|
||||
uwsgi_error("unlink()");
|
||||
@@ -676,6 +774,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi.signal_socket = -1;
|
||||
|
||||
uwsgi.emperor_fd_config = -1;
|
||||
uwsgi.emperor_pid = -1;
|
||||
|
||||
uwsgi.cluster_fd = -1;
|
||||
uwsgi.cores = 1;
|
||||
@@ -703,6 +802,14 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi.rl.rlim_cur = 0;
|
||||
uwsgi.rl.rlim_max = 0;
|
||||
|
||||
// are we under systemd ?
|
||||
char *notify_socket = getenv("NOTIFY_SOCKET");
|
||||
if (notify_socket) {
|
||||
uwsgi_systemd_init(notify_socket);
|
||||
}
|
||||
|
||||
uwsgi_notify("initializing uWSGI");
|
||||
|
||||
emperor_env = getenv("UWSGI_EMPEROR_FD");
|
||||
if (emperor_env) {
|
||||
uwsgi.has_emperor = 1;
|
||||
@@ -1105,27 +1212,56 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
fclose(pidfile);
|
||||
}
|
||||
|
||||
/*
|
||||
for (i = 0; i < uwsgi.shared_sockets_cnt; i++) {
|
||||
char *tcp_port = strchr(uwsgi.shared_sockets[i].name, ':');
|
||||
struct uwsgi_socket *shared_sock = uwsgi.shared_sockets;
|
||||
while (shared_sock) {
|
||||
char *tcp_port = strchr(shared_sock->name, ':');
|
||||
if (tcp_port == NULL) {
|
||||
uwsgi.shared_sockets[i].fd = bind_to_unix(uwsgi.shared_sockets[i].name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
uwsgi.shared_sockets[i].family = AF_UNIX;
|
||||
uwsgi_log("uwsgi shared socket %d bound to UNIX address %s fd %d\n", i, uwsgi.shared_sockets[i].name, uwsgi.shared_sockets[i].fd);
|
||||
shared_sock->fd = bind_to_unix(shared_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
shared_sock->family = AF_UNIX;
|
||||
uwsgi_log("uwsgi shared socket %d bound to UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
}
|
||||
else {
|
||||
uwsgi.shared_sockets[i].fd = bind_to_tcp(uwsgi.shared_sockets[i].name, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi.shared_sockets[i].family = AF_INET;
|
||||
uwsgi_log("uwsgi shared socket %d bound to TCP address %s fd %d\n", i, uwsgi.shared_sockets[i].name, uwsgi.shared_sockets[i].fd);
|
||||
shared_sock->fd = bind_to_tcp(shared_sock->name, uwsgi.listen_queue, tcp_port);
|
||||
shared_sock->family = AF_INET;
|
||||
uwsgi_log("uwsgi shared socket %d bound to TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
|
||||
}
|
||||
|
||||
if (uwsgi.shared_sockets[i].fd < 0) {
|
||||
uwsgi_log("unable to create shared socket on: %s\n", uwsgi.shared_sockets[i].name);
|
||||
if (shared_sock->fd < 0) {
|
||||
uwsgi_log("unable to create shared socket on: %s\n", shared_sock->name);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.shared_sockets[i].bound = 1;
|
||||
shared_sock->bound = 1;
|
||||
|
||||
shared_sock = shared_sock->next;
|
||||
}
|
||||
*/
|
||||
|
||||
// start the Emperor if needed
|
||||
if (uwsgi.early_emperor && uwsgi.emperor_dir) {
|
||||
|
||||
if (!uwsgi.sockets && !uwsgi.gateways_cnt && !uwsgi.master_process) {
|
||||
uwsgi_notify_ready();
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.emperor_pid = fork();
|
||||
if (uwsgi.emperor_pid < 0) {
|
||||
uwsgi_error("pid()");
|
||||
exit(1);
|
||||
}
|
||||
else if (uwsgi.emperor_pid == 0) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// call jail systems
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
@@ -1163,17 +1299,17 @@ int uwsgi_start(void *v_argv) {
|
||||
#endif
|
||||
|
||||
|
||||
pid_t pid;
|
||||
int i, j;
|
||||
|
||||
union uwsgi_sockaddr usa;
|
||||
union uwsgi_sockaddr_ptr gsa;
|
||||
socklen_t socket_type_len;
|
||||
|
||||
int emperor_pipe[2];
|
||||
struct uwsgi_socket *uwsgi_sock;
|
||||
|
||||
#ifdef __linux__
|
||||
uwsgi_set_cgroup();
|
||||
|
||||
if (uwsgi.ns) {
|
||||
linux_namespace_jail();
|
||||
}
|
||||
@@ -1254,10 +1390,12 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
|
||||
// start the Emperor if needed
|
||||
if (uwsgi.emperor_dir) {
|
||||
if (!uwsgi.early_emperor && uwsgi.emperor_dir) {
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, emperor_pipe)) {
|
||||
uwsgi_error("socketpair()");
|
||||
if (!uwsgi.sockets && !uwsgi.gateways_cnt && !uwsgi.master_process) {
|
||||
uwsgi_notify_ready();
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1266,22 +1404,16 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_error("pid()");
|
||||
exit(1);
|
||||
}
|
||||
else if (uwsgi.emperor_pid > 0) {
|
||||
close(emperor_pipe[1]);
|
||||
else if (uwsgi.emperor_pid == 0) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
emperor_loop();
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// do not go on if no socket or gateway is defined
|
||||
if (!uwsgi.sockets && !uwsgi.gateways_cnt) {
|
||||
exit(0);
|
||||
}
|
||||
close(emperor_pipe[0]);
|
||||
uwsgi.has_emperor = 1;
|
||||
uwsgi.emperor_fd = emperor_pipe[1];
|
||||
uwsgi.master_process = 1;
|
||||
uwsgi.no_orphans = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1455,7 +1587,7 @@ int uwsgi_start(void *v_argv) {
|
||||
//check for inherited sockets
|
||||
if (uwsgi.is_a_reload) {
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
//a bit overengineering
|
||||
if (uwsgi_sock->name[0] != 0) {
|
||||
for (j = 3; j < sysconf(_SC_OPEN_MAX); j++) {
|
||||
@@ -1480,7 +1612,7 @@ int uwsgi_start(void *v_argv) {
|
||||
gsa.sa = (struct sockaddr *) &usa;
|
||||
if (!getsockname(j, gsa.sa, &socket_type_len)) {
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->fd == j && uwsgi_sock->bound) {
|
||||
useless = 0;
|
||||
break;
|
||||
@@ -1494,7 +1626,7 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
//now bind all the unbound sockets
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
if (!uwsgi_sock->bound) {
|
||||
char *tcp_port = strchr(uwsgi_sock->name, ':');
|
||||
if (tcp_port == NULL) {
|
||||
@@ -1519,7 +1651,7 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
int zero_used = 0;
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->bound && uwsgi_sock->fd == 0) {
|
||||
zero_used = 1;
|
||||
break;
|
||||
@@ -1531,14 +1663,13 @@ int uwsgi_start(void *v_argv) {
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = (struct sockaddr *) &usa;
|
||||
if (!getsockname(0, gsa.sa, &socket_type_len)) {
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
uwsgi_sock = uwsgi_new_socket(usa.sa_un.sun_path);
|
||||
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_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
uwsgi_sock = uwsgi_new_socket(usa.sa_un.sun_path);
|
||||
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_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1560,7 +1691,7 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
// put listening socket in non-blocking state and set the protocol
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
uwsgi_sock->arg = fcntl(uwsgi_sock->fd, F_GETFL, NULL);
|
||||
if (uwsgi_sock->arg < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
@@ -1623,10 +1754,11 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
// initialize request plugin only if workers or master are available
|
||||
if (uwsgi.sockets || uwsgi.master_process) {
|
||||
if (uwsgi.sockets || uwsgi.master_process || uwsgi.no_server) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->init) {
|
||||
uwsgi.p[i]->init();
|
||||
@@ -1664,7 +1796,7 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!uwsgi.sockets && !uwsgi.gateways_cnt && !uwsgi.no_server && !uwsgi.udp_socket) {
|
||||
if (!uwsgi.sockets && !uwsgi.gateways_cnt && !uwsgi.no_server && !uwsgi.udp_socket && !uwsgi.emperor_dir) {
|
||||
uwsgi_log("The -s/--socket option is missing and stdin is not a socket.\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -1677,7 +1809,7 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
so_bufsize_len = sizeof(int);
|
||||
if (getsockopt(uwsgi_sock->fd, SOL_SOCKET, SO_RCVBUF, &so_bufsize, &so_bufsize_len)) {
|
||||
uwsgi_error("getsockopt()");
|
||||
@@ -1776,7 +1908,7 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_log("no-server mode requested. Goodbye.\n");
|
||||
exit(0);
|
||||
}
|
||||
//is this a proxy only worker ?
|
||||
|
||||
|
||||
if (!uwsgi.master_process && uwsgi.numproc == 0) {
|
||||
exit(0);
|
||||
@@ -1840,25 +1972,15 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
}
|
||||
for (i = 2 - uwsgi.master_process; i < uwsgi.numproc + 1; i++) {
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
close(uwsgi.shared->worker_signal_pipe[0]);
|
||||
uwsgi.mypid = getpid();
|
||||
uwsgi.workers[i].pid = uwsgi.mypid;
|
||||
uwsgi.workers[i].id = i;
|
||||
uwsgi.workers[i].last_spawn = time(NULL);
|
||||
uwsgi.workers[i].manage_next_request = 1;
|
||||
uwsgi.mywid = i;
|
||||
break;
|
||||
}
|
||||
else if (pid < 1) {
|
||||
uwsgi_error("fork()");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("spawned uWSGI worker %d (pid: %d, cores: %d)\n", i, pid, uwsgi.cores);
|
||||
//close(uwsgi.workers[i].pipe[1]);
|
||||
|
||||
// uWSGI is ready
|
||||
uwsgi_notify_ready();
|
||||
uwsgi.current_time = time(NULL);
|
||||
|
||||
if (!uwsgi.cheap) {
|
||||
for (i = 2 - uwsgi.master_process; i < uwsgi.numproc + 1; i++) {
|
||||
if (uwsgi_respawn_worker(i))
|
||||
break;
|
||||
gettimeofday(&last_respawn, NULL);
|
||||
uwsgi.respawn_delta = last_respawn.tv_sec;
|
||||
}
|
||||
@@ -1871,58 +1993,58 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
struct uwsgi_string_list *usl = uwsgi.map_socket;
|
||||
while (uwsgi_sock) {
|
||||
struct uwsgi_string_list *usl = uwsgi.map_socket;
|
||||
int enabled = 1;
|
||||
while(usl) {
|
||||
while (usl) {
|
||||
|
||||
char *colon = strchr(usl->value, ':');
|
||||
if (uwsgi_str_num(usl->value, colon-usl->value) == uwsgi_get_socket_num(uwsgi_sock)) {
|
||||
char *colon = strchr(usl->value, ':');
|
||||
if (uwsgi_str_num(usl->value, colon - usl->value) == uwsgi_get_socket_num(uwsgi_sock)) {
|
||||
enabled = 0;
|
||||
char *p = strtok(colon+1, ",");
|
||||
while (p != NULL) {
|
||||
int w = atoi(p);
|
||||
if (w < 1 || w > uwsgi.numproc) {
|
||||
uwsgi_log("invalid worker num: %d\n", w);
|
||||
exit(1);
|
||||
}
|
||||
char *p = strtok(colon + 1, ",");
|
||||
while (p != NULL) {
|
||||
int w = atoi(p);
|
||||
if (w < 1 || w > uwsgi.numproc) {
|
||||
uwsgi_log("invalid worker num: %d\n", w);
|
||||
exit(1);
|
||||
}
|
||||
if (w == uwsgi.mywid) {
|
||||
enabled = 1;
|
||||
uwsgi_log("mapped socket %d (%s) to worker %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi.mywid);
|
||||
break;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
usl = usl->next;
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
int fd = uwsgi_sock->fd;
|
||||
close(fd);
|
||||
fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != uwsgi_sock->fd) {
|
||||
if (dup2(fd, uwsgi_sock->fd)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != uwsgi_sock->fd) {
|
||||
if (dup2(fd, uwsgi_sock->fd)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
uwsgi_sock->disabled = 1;
|
||||
}
|
||||
|
||||
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->disabled) {
|
||||
uwsgi_sock = uwsgi_del_socket(uwsgi_sock);
|
||||
}
|
||||
@@ -1978,9 +2100,9 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
uwsgi.core = uwsgi_malloc(sizeof(struct uwsgi_core *) * uwsgi.cores);
|
||||
for (j = 0; j < uwsgi.cores; j++) {
|
||||
uwsgi.core[j] = uwsgi_malloc(sizeof(struct uwsgi_core));
|
||||
memset(uwsgi.core[j], 0, sizeof(struct uwsgi_core));
|
||||
for (j = 0; j < uwsgi.cores; j++) {
|
||||
uwsgi.core[j] = uwsgi_malloc(sizeof(struct uwsgi_core));
|
||||
memset(uwsgi.core[j], 0, sizeof(struct uwsgi_core));
|
||||
}
|
||||
|
||||
if (uwsgi.master_as_root) {
|
||||
@@ -2083,11 +2205,7 @@ int uwsgi_start(void *v_argv) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
event_queue_add_fd_read(uwsgi.async_queue, uwsgi_sock->fd);
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
uwsgi_add_sockets_to_queue(uwsgi.async_queue);
|
||||
}
|
||||
|
||||
uwsgi.rb_async_timeouts = uwsgi_init_rb_timer();
|
||||
@@ -2115,6 +2233,10 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_unix_signal(SIGINT, end_me);
|
||||
uwsgi_unix_signal(SIGTERM, end_me);
|
||||
|
||||
if (uwsgi.auto_snapshot) {
|
||||
uwsgi_unix_signal(SIGURG, snapshot_me);
|
||||
}
|
||||
|
||||
|
||||
uwsgi_unix_signal(SIGUSR1, stats);
|
||||
|
||||
@@ -2127,10 +2249,10 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
// run fixup handler
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->fixup) {
|
||||
uwsgi.p[i]->fixup();
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->fixup) {
|
||||
uwsgi.p[i]->fixup();
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.chdir2) {
|
||||
if (chdir(uwsgi.chdir2)) {
|
||||
@@ -2190,6 +2312,27 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
uwsgi_ignition();
|
||||
|
||||
// never here
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_ignition() {
|
||||
|
||||
int i;
|
||||
|
||||
// snapshot workers do not enter the loop until a specific signal (SIGURG) is raised...
|
||||
if (uwsgi.snapshot) {
|
||||
wait_for_call_of_duty:
|
||||
uwsgi_sig_pause();
|
||||
if (uwsgi.snapshot)
|
||||
goto wait_for_call_of_duty;
|
||||
uwsgi_log("[snapshot] process %d is the new worker %d\n", (int) getpid(), uwsgi.mywid);
|
||||
}
|
||||
|
||||
if (uwsgi.loop) {
|
||||
void (*u_loop) (void) = uwsgi_get_loop(uwsgi.loop);
|
||||
uwsgi_log("running %s loop %p\n", uwsgi.loop, u_loop);
|
||||
@@ -2238,8 +2381,11 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
}
|
||||
|
||||
if (uwsgi.snapshot) {
|
||||
uwsgi_ignition();
|
||||
}
|
||||
// never here
|
||||
return 0;
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static int manage_base_opt(int i, char *optarg) {
|
||||
@@ -2297,6 +2443,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
}
|
||||
build_options();
|
||||
return 1;
|
||||
case LONG_ARGS_IDLE:
|
||||
uwsgi.idle = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CHDIR:
|
||||
uwsgi.chdir = optarg;
|
||||
return 1;
|
||||
@@ -2353,9 +2502,22 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_RELOAD_MERCY:
|
||||
uwsgi.reload_mercy = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_AUTO_SNAPSHOT:
|
||||
uwsgi.auto_snapshot = -1;
|
||||
if (optarg) {
|
||||
uwsgi.auto_snapshot = atoi(optarg);
|
||||
}
|
||||
uwsgi.lazy = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_LOG_MASTER:
|
||||
uwsgi.log_master = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_LOG_SOCKET:
|
||||
uwsgi.log_socket = 1;
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
log_socket(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_LOG_SYSLOG:
|
||||
log_syslog(optarg);
|
||||
uwsgi.log_syslog = 1;
|
||||
@@ -2363,12 +2525,12 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
case LONG_ARGS_LOG_ZEROMQ:
|
||||
log_zeromq(optarg);
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_LOG_ZEROMQ:
|
||||
log_zeromq(optarg);
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_PRINT:
|
||||
uwsgi_log("%s\n", optarg);
|
||||
return 1;
|
||||
@@ -2441,6 +2603,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi.erlang_cookie = optarg;
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_ADD_HEADER:
|
||||
uwsgi_string_new_list(&uwsgi.additional_headers, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CHECK_STATIC:
|
||||
uwsgi.check_static = realpath(optarg, NULL);
|
||||
uwsgi.check_static_len = strlen(uwsgi.check_static);
|
||||
@@ -2725,15 +2890,7 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi_new_socket(generate_socket_name(optarg));
|
||||
return 1;
|
||||
case LONG_ARGS_SHARED_SOCKET:
|
||||
/*
|
||||
if (uwsgi.shared_sockets_cnt < MAX_SOCKETS) {
|
||||
uwsgi.shared_sockets[uwsgi.shared_sockets_cnt].name = generate_socket_name(optarg);
|
||||
uwsgi.shared_sockets_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can specify at most 8 --socket options\n");
|
||||
}
|
||||
*/
|
||||
uwsgi_new_shared_socket(generate_socket_name(optarg));
|
||||
return 1;
|
||||
#ifdef UWSGI_XML
|
||||
case 'x':
|
||||
@@ -3599,48 +3756,49 @@ void uwsgi_init_all_apps() {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->init_apps) {
|
||||
uwsgi.p[i]->init_apps();
|
||||
}
|
||||
}
|
||||
if (uwsgi.p[i]->init_apps) {
|
||||
uwsgi.p[i]->init_apps();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->init_apps) {
|
||||
uwsgi.gp[i]->init_apps();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->init_apps) {
|
||||
uwsgi.gp[i]->init_apps();
|
||||
}
|
||||
}
|
||||
|
||||
/*parse xml for <app> tags */
|
||||
/*parse xml for <app> tags */
|
||||
#ifdef UWSGI_XML
|
||||
if (uwsgi.xml_round2 && uwsgi.xml_config != NULL) {
|
||||
uwsgi_xml_config(uwsgi.xml_config, uwsgi.wsgi_req, 1, NULL);
|
||||
}
|
||||
if (uwsgi.xml_round2 && uwsgi.xml_config != NULL) {
|
||||
uwsgi_xml_config(uwsgi.xml_config, uwsgi.wsgi_req, 1, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < uwsgi.mounts_cnt; i++) {
|
||||
char *what = strchr(uwsgi.mounts[i], '=');
|
||||
if (what) {
|
||||
what[0] = 0;
|
||||
what++;
|
||||
uwsgi_log("mounting %s on %s\n", what, uwsgi.mounts[i]);
|
||||
for (j = 0; j < 0xFF; j++) {
|
||||
if (uwsgi.p[j]->mount_app) {
|
||||
if (uwsgi.p[j]->mount_app(uwsgi.mounts[i], what) != -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
what--;
|
||||
what[0] = '=';
|
||||
}
|
||||
else {
|
||||
uwsgi_log("invalid mountpoint: %s\n", uwsgi.mounts[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < uwsgi.mounts_cnt; i++) {
|
||||
char *what = strchr(uwsgi.mounts[i], '=');
|
||||
if (what) {
|
||||
what[0] = 0;
|
||||
what++;
|
||||
uwsgi_log("mounting %s on %s\n", what, uwsgi.mounts[i]);
|
||||
for (j = 0; j < 0xFF; j++) {
|
||||
if (uwsgi.p[j]->mount_app) {
|
||||
if (uwsgi.p[j]->mount_app(uwsgi.mounts[i], what) != -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
what--;
|
||||
what[0] = '=';
|
||||
}
|
||||
else {
|
||||
uwsgi_log("invalid mountpoint: %s\n", uwsgi.mounts[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// no app initialized and virtualhosting enabled
|
||||
if (uwsgi.apps_cnt == 0 && uwsgi.vhost) {
|
||||
uwsgi.apps_cnt = 1;
|
||||
}
|
||||
// no app initialized and virtualhosting enabled
|
||||
if (uwsgi.apps_cnt == 0) {
|
||||
uwsgi_log("*** no app loaded. going in full dynamic mode ***\n");
|
||||
uwsgi.apps_cnt = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
/* indent -i8 -br -brs -brf -l0 -npsl -nip -npcs -npsl -di1 */
|
||||
|
||||
#define UWSGI_VERSION "0.9.8-dev"
|
||||
|
||||
#define UMAX16 65536
|
||||
|
||||
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
@@ -12,6 +10,9 @@
|
||||
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
|
||||
#define uwsgi_rawlog(x) if (write(2, x, strlen(x)) != strlen(x)) uwsgi_error("write()")
|
||||
|
||||
#define uwsgi_notify(x) if (uwsgi.notify) uwsgi.notify(x)
|
||||
#define uwsgi_notify_ready() if (uwsgi.notify_ready) uwsgi.notify_ready()
|
||||
|
||||
#define wsgi_req_time ((wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec) - (wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec))/1000
|
||||
|
||||
#define ushared uwsgi.shared
|
||||
@@ -93,7 +94,9 @@
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#ifdef UWSGI_HAS_IFADDRS
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
@@ -246,6 +249,7 @@ struct uwsgi_static_map {
|
||||
struct uwsgi_string_list {
|
||||
|
||||
char *value;
|
||||
size_t len;
|
||||
struct uwsgi_string_list *next;
|
||||
};
|
||||
|
||||
@@ -429,6 +433,10 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_LOG_ZEROMQ 17104
|
||||
#define LONG_ARGS_PROFILER 17105
|
||||
#define LONG_ARGS_SQLITE3 17106
|
||||
#define LONG_ARGS_AUTO_SNAPSHOT 17107
|
||||
#define LONG_ARGS_LOG_SOCKET 17108
|
||||
#define LONG_ARGS_ADD_HEADER 17109
|
||||
#define LONG_ARGS_IDLE 17120
|
||||
|
||||
|
||||
#define UWSGI_OK 0
|
||||
@@ -465,6 +473,8 @@ struct uwsgi_opt {
|
||||
#define UWSGI_OPTION_LOG_5xx 12
|
||||
#define UWSGI_OPTION_LOG_BIG 13
|
||||
#define UWSGI_OPTION_LOG_SENDFILE 14
|
||||
#define UWSGI_OPTION_BACKLOG_STATUS 15
|
||||
#define UWSGI_OPTION_BACKLOG_ERRORS 16
|
||||
|
||||
#define UWSGI_MODIFIER_ADMIN_REQUEST 10
|
||||
#define UWSGI_MODIFIER_SPOOL_REQUEST 17
|
||||
@@ -661,8 +671,10 @@ struct wsgi_request {
|
||||
struct msghdr msg;
|
||||
union {
|
||||
struct cmsghdr cmsg;
|
||||
#ifndef __NetBSD__
|
||||
char control [CMSG_SPACE (sizeof (int))];
|
||||
} msg_control;
|
||||
#endif
|
||||
} msg_control;
|
||||
|
||||
struct timeval start_of_request;
|
||||
struct timeval end_of_request;
|
||||
@@ -830,14 +842,27 @@ struct uwsgi_server {
|
||||
|
||||
int autoload;
|
||||
|
||||
int snapshot;
|
||||
int auto_snapshot;
|
||||
pid_t restore_snapshot;
|
||||
int respawn_workers;
|
||||
unsigned int reloads;
|
||||
int master_as_root;
|
||||
int die_on_term;
|
||||
|
||||
int no_fd_passing;
|
||||
|
||||
time_t current_time;
|
||||
uint64_t master_cycles;
|
||||
|
||||
int lazy;
|
||||
int cheap;
|
||||
int idle;
|
||||
|
||||
int has_emperor;
|
||||
int emperor_fd;
|
||||
int emperor_fd_config;
|
||||
int early_emperor;
|
||||
char *emperor_dir;
|
||||
pid_t emperor_pid;
|
||||
struct uwsgi_config_template *vassals_templates;
|
||||
@@ -847,6 +872,8 @@ struct uwsgi_server {
|
||||
char *emperor_amqp_username;
|
||||
char *emperor_amqp_password;
|
||||
|
||||
struct uwsgi_string_list *additional_headers;
|
||||
|
||||
time_t master_mercy;
|
||||
|
||||
int cpu_affinity;
|
||||
@@ -888,6 +915,12 @@ struct uwsgi_server {
|
||||
|
||||
int log_master;
|
||||
int log_syslog;
|
||||
|
||||
int log_socket;
|
||||
int log_socket_fd;
|
||||
union uwsgi_sockaddr *log_socket_addr;
|
||||
socklen_t log_socket_size;
|
||||
|
||||
char *check_static;
|
||||
size_t check_static_len;
|
||||
int file_serve_mode;
|
||||
@@ -1101,9 +1134,6 @@ struct uwsgi_server {
|
||||
void *zmq_log_socket;
|
||||
#endif
|
||||
struct uwsgi_socket *sockets;
|
||||
// leave a slot for no-orphan mode
|
||||
|
||||
int shared_sockets_cnt;
|
||||
struct uwsgi_socket *shared_sockets;
|
||||
|
||||
struct uwsgi_string_list *map_socket;
|
||||
@@ -1125,6 +1155,11 @@ struct uwsgi_server {
|
||||
|
||||
struct wsgi_request *(*current_wsgi_req) (void);
|
||||
|
||||
void (*notify) (char *);
|
||||
void (*notify_ready) (void);
|
||||
int notification_fd;
|
||||
void *notification_object;
|
||||
|
||||
// usedby suspend/resume loops
|
||||
void (*schedule_to_main) (struct wsgi_request *);
|
||||
void (*schedule_to_req) (void);
|
||||
@@ -1279,7 +1314,7 @@ struct uwsgi_shared {
|
||||
//vga 80 x25 specific !
|
||||
char warning_message[81];
|
||||
|
||||
uint32_t options[0xFF];
|
||||
uint32_t options[256];
|
||||
|
||||
struct uwsgi_cluster_node nodes[MAX_CLUSTER_NODES];
|
||||
|
||||
@@ -1354,9 +1389,17 @@ struct uwsgi_core {
|
||||
int in_request;
|
||||
};
|
||||
|
||||
struct uwsgi_snapshot {
|
||||
char *name;
|
||||
pid_t pid;
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
struct uwsgi_worker {
|
||||
int id;
|
||||
pid_t pid;
|
||||
|
||||
pid_t snapshot;
|
||||
uint64_t status;
|
||||
|
||||
time_t last_spawn;
|
||||
@@ -1922,6 +1965,7 @@ char *uwsgi_netstring(char *, size_t, char **, size_t *);
|
||||
|
||||
int uwsgi_get_socket_num(struct uwsgi_socket *);
|
||||
struct uwsgi_socket *uwsgi_new_socket(char *);
|
||||
struct uwsgi_socket *uwsgi_new_shared_socket(char *);
|
||||
struct uwsgi_socket *uwsgi_del_socket(struct uwsgi_socket *);
|
||||
|
||||
void uwsgi_close_all_sockets(void);
|
||||
@@ -1934,3 +1978,28 @@ void uwsgi_init_all_apps(void);
|
||||
void uwsgi_socket_nb(int);
|
||||
|
||||
void uwsgi_destroy_request(struct wsgi_request *);
|
||||
|
||||
void uwsgi_systemd_init(char *);
|
||||
|
||||
void uwsgi_sig_pause(void);
|
||||
|
||||
void uwsgi_ignition(void);
|
||||
|
||||
void master_check_cluster_nodes(void);
|
||||
int uwsgi_respawn_worker(int);
|
||||
|
||||
void log_socket(char *);
|
||||
|
||||
socklen_t socket_to_in_addr(char *, char *, struct sockaddr_in *);
|
||||
socklen_t socket_to_un_addr(char *, struct sockaddr_un *);
|
||||
|
||||
int uwsgi_get_shared_socket_fd_by_num(int);
|
||||
|
||||
int uwsgi_get_shared_socket_num(struct uwsgi_socket *);
|
||||
|
||||
#ifdef __linux__
|
||||
void uwsgi_set_cgroup(void);
|
||||
#endif
|
||||
|
||||
void uwsgi_add_sockets_to_queue(int);
|
||||
void uwsgi_del_sockets_from_queue(int);
|
||||
|
||||
+52
-1
@@ -1,5 +1,7 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '0.9.8'
|
||||
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
@@ -23,6 +25,8 @@ GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
|
||||
if not GCC:
|
||||
GCC = 'gcc'
|
||||
|
||||
|
||||
|
||||
|
||||
def spcall(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=open('/dev/null','w'))
|
||||
@@ -34,6 +38,12 @@ def spcall(cmd):
|
||||
else:
|
||||
return None
|
||||
|
||||
if uwsgi_version.endswith('-dev') and os.path.exists('%s/.hg' % os.path.dirname(os.path.abspath( __file__ ))):
|
||||
try:
|
||||
uwsgi_version += spcall('hg tip --template "-{rev}"')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def spcall2(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
|
||||
@@ -156,7 +166,7 @@ class uConf(object):
|
||||
self.config = ConfigParser.ConfigParser()
|
||||
print("using profile: %s" % filename)
|
||||
self.config.read(filename)
|
||||
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'emperor',
|
||||
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify',
|
||||
'plugins', 'lock', 'cache', 'queue', 'event', 'signal', 'rpc', 'gateway', 'loop', 'lib/rbtree', 'lib/amqp', 'rb_timers', 'uwsgi']
|
||||
# add protocols
|
||||
self.gcc_list.append('proto/base')
|
||||
@@ -227,12 +237,18 @@ class uConf(object):
|
||||
|
||||
def get_gcll(self):
|
||||
|
||||
global uwsgi_version
|
||||
|
||||
self.cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
|
||||
kvm_list = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly']
|
||||
|
||||
if os.path.exists('/usr/include/ifaddrs.h') or os.path.exists('/usr/local/include/ifaddrs.h'):
|
||||
self.cflags.append('-DUWSGI_HAS_IFADDRS')
|
||||
|
||||
if uwsgi_os == 'SunOS':
|
||||
self.libs.append('-lsendfile')
|
||||
self.gcc_list.append('lib/sun_fixes')
|
||||
self.ldflags.append('-L/lib')
|
||||
if not uwsgi_os_v.startswith('Nexenta'):
|
||||
self.libs.remove('-rdynamic')
|
||||
|
||||
@@ -394,6 +410,41 @@ class uConf(object):
|
||||
if os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so'):
|
||||
self.libs.append('-luuid')
|
||||
|
||||
if self.get('append_version'):
|
||||
if not self.get('append_version').startswith('-'):
|
||||
uwsgi_version += '-'
|
||||
uwsgi_version += self.get('append_version')
|
||||
|
||||
self.cflags.append('-DUWSGI_VERSION="\\"' + uwsgi_version + '\\""')
|
||||
|
||||
uver_whole = uwsgi_version.split('-', 1)
|
||||
if len(uver_whole) == 1:
|
||||
uver_custom = ''
|
||||
else:
|
||||
uver_custom = uver_whole[1]
|
||||
|
||||
uver_dots = uver_whole[0].split('.')
|
||||
|
||||
uver_base = uver_dots[0]
|
||||
uver_maj = uver_dots[1]
|
||||
uver_min = '0'
|
||||
uver_rev = '0'
|
||||
|
||||
if len(uver_dots) > 2:
|
||||
uver_min = uver_dots[2]
|
||||
|
||||
if len(uver_dots) > 3:
|
||||
uver_rev = uver_dots[3]
|
||||
|
||||
|
||||
self.cflags.append('-DUWSGI_VERSION_BASE="' + uver_base + '"')
|
||||
self.cflags.append('-DUWSGI_VERSION_MAJOR="' + uver_maj + '"')
|
||||
self.cflags.append('-DUWSGI_VERSION_MINOR="' + uver_min + '"')
|
||||
self.cflags.append('-DUWSGI_VERSION_REVISION="' + uver_rev + '"')
|
||||
self.cflags.append('-DUWSGI_VERSION_CUSTOM="\\"' + uver_custom + '\\""')
|
||||
|
||||
|
||||
|
||||
if self.get('async'):
|
||||
self.cflags.append("-DUWSGI_ASYNC")
|
||||
self.gcc_list.append('async')
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
@@ -0,0 +1,6 @@
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World! app2 !!!"
|
||||
@@ -0,0 +1,6 @@
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World! app3"
|
||||
@@ -0,0 +1,6 @@
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World! app4"
|
||||
@@ -0,0 +1,6 @@
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World! app5"
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
sendfile on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
gzip on;
|
||||
|
||||
upstream uwsgi_server {
|
||||
server 127.0.0.1:3031;
|
||||
}
|
||||
|
||||
include uwsgi_params;
|
||||
uwsgi_param UWSGI_FILE $app;
|
||||
uwsgi_param UWSGI_PYHOME $virtualenv;
|
||||
|
||||
|
||||
server {
|
||||
listen 8026;
|
||||
server_name flask001;
|
||||
set $app vhosttest/flask001/app1.py;
|
||||
set $virtualenv vhosttest/venv001;
|
||||
location / {
|
||||
uwsgi_pass uwsgi_server;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8026;
|
||||
server_name flask002;
|
||||
set $app vhosttest/flask002/app2.py;
|
||||
set $virtualenv vhosttest/venv001;
|
||||
location / {
|
||||
uwsgi_pass uwsgi_server;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import uwsgi
|
||||
|
||||
|
||||
def serve_logo(e, sr):
|
||||
sr('200 OK', [('Content-Type', 'image/png')])
|
||||
return uwsgi.sendfile('logo_uWSGI.png')
|
||||
|
||||
def serve_options(e, sr):
|
||||
sr('200 OK', [('Content-Type', 'text/html')])
|
||||
for opt in xrange(0,256):
|
||||
yield "%d = %d<br/>" % (opt, uwsgi.get_option(opt))
|
||||
|
||||
def serve_config(e, sr):
|
||||
sr('200 OK', [('Content-Type', 'text/html')])
|
||||
for opt in uwsgi.opt.keys():
|
||||
yield "%s = %s<br/>" % (opt, uwsgi.opt[opt])
|
||||
|
||||
routes = {}
|
||||
routes['/logo'] = serve_logo
|
||||
routes['/config'] = serve_config
|
||||
routes['/options'] = serve_options
|
||||
|
||||
def application(env, start_response):
|
||||
|
||||
if routes.has_key(env['PATH_INFO']):
|
||||
return routes[env['PATH_INFO']](env, start_response)
|
||||
|
||||
start_response('200 OK', [('Content-Type', 'text/html')])
|
||||
|
||||
return """
|
||||
<img src="/logo"/> version %s<br/>
|
||||
<hr size="1"/>
|
||||
|
||||
Configuration<br/>
|
||||
<iframe src="/config"></iframe><br/>
|
||||
|
||||
<br/>
|
||||
|
||||
Dynamic options<br/>
|
||||
<iframe src="/options"></iframe><br/>
|
||||
|
||||
""" % (uwsgi.version)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
"workers": 8,
|
||||
"module": "werkzeug.testapp:test_app",
|
||||
"master": true,
|
||||
"socket": [ "/tmp/uwsgi.sock", "127.0.0.1:3031" ],
|
||||
"socket": [ "/tmp/uwsgi.sock", "127.0.0.1:3031", "@foobar" ],
|
||||
"pythonpath": [ "/foo", "/bar" ],
|
||||
"show-config": true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user