mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df0f2a549e | ||
|
|
9b7cbab37c | ||
|
|
ac46cb2371 | ||
|
|
c858c88bb3 | ||
|
|
a05f5d9860 | ||
|
|
e6914b91e1 | ||
|
|
b624bd2d35 | ||
|
|
e3c9b2c0bf | ||
|
|
576a1e7cb2 | ||
|
|
55c3ba73d3 | ||
|
|
2246d30bbe | ||
|
|
789e333736 | ||
|
|
283904107f | ||
|
|
8d92261852 | ||
|
|
e8f5d82b78 | ||
|
|
0a8643155e | ||
|
|
61793201c7 | ||
|
|
41f2982074 | ||
|
|
27b86f1b79 | ||
|
|
d69892c91e | ||
|
|
296549d1bf | ||
|
|
7d2f147172 | ||
|
|
aa56f99ee2 | ||
|
|
ca82b99f42 | ||
|
|
d204a5b844 | ||
|
|
0a98550770 | ||
|
|
0c0c2736a7 | ||
|
|
27e2d984ce | ||
|
|
14eeae09b1 | ||
|
|
16eb47070d | ||
|
|
1f69f58593 | ||
|
|
1b4421e013 | ||
|
|
f13400d592 | ||
|
|
e29f0323ea | ||
|
|
15a582d046 | ||
|
|
1e01f8be17 | ||
|
|
8cc73991a3 | ||
|
|
ecce74ade5 | ||
|
|
836efaaf70 | ||
|
|
46f8e7dc00 | ||
|
|
88cd033ca6 | ||
|
|
984df3bcdf | ||
|
|
7673cdb1aa | ||
|
|
8af700ce37 | ||
|
|
ffb8752190 | ||
|
|
71fa3ab3af | ||
|
|
09501cfa74 | ||
|
|
d84ae12733 | ||
|
|
05f292abe6 | ||
|
|
a75833d322 | ||
|
|
ca3f56de5c | ||
|
|
9d75f2c9c7 | ||
|
|
a58cbf92b0 | ||
|
|
7bac76fae5 | ||
|
|
9c71b39edd | ||
|
|
52f731c6b7 | ||
|
|
735d1cb689 | ||
|
|
5a0977f412 | ||
|
|
1da1fccbc7 | ||
|
|
ca5a528818 | ||
|
|
a9ef806a37 | ||
|
|
de112b7788 | ||
|
|
ef7baba274 | ||
|
|
3a9d13b011 | ||
|
|
5b5493aab0 | ||
|
|
5f208d8f12 | ||
|
|
47c077d066 | ||
|
|
d2ac69b6c1 | ||
|
|
8860cac7dd | ||
|
|
28bcc73c70 | ||
|
|
af20c2d8f0 | ||
|
|
44213ca510 | ||
|
|
ab21a1ac00 | ||
|
|
a67f366501 | ||
|
|
b32251e5aa | ||
|
|
16e0accb74 | ||
|
|
c6ce291cbf |
@@ -24,3 +24,4 @@ d1e57707f6317f134fea7d12f6588d8690f74f3f 0.9.8-rc1
|
||||
e91bc724325e14c13b8f548c0b6a315c48a1c32a 0.9.8-rc2
|
||||
4fb424d52f226a0a087fea89709f5eb540e03f25 0.9.8-rc3
|
||||
0f1f3924ee5309a9990d9af1ffc68846e3dfb31b 0.9.8-rc4
|
||||
42efe1f329005618c8b44f901979ebcecd5216fb 0.9.8
|
||||
|
||||
@@ -1,4 +1,47 @@
|
||||
*** may 2011 ***
|
||||
*** june 2011 ***
|
||||
|
||||
* 0.9.8.1 [20110625]
|
||||
|
||||
- the build system has been improved
|
||||
- various threading fixes
|
||||
- fix python GIL status after reload
|
||||
- new option --propagate-touch
|
||||
- fixed uwsgi.sendfile
|
||||
- fixed readline() support in wsgi.input
|
||||
- fixed dynamic touch reload
|
||||
- new option --logto2
|
||||
- export %c in config files
|
||||
- fixed libyaml support
|
||||
- support passing modifiers in subscription system
|
||||
- reset random seed in spooler
|
||||
- subscribe from a list in a text file
|
||||
- allow binding on port 0 (auto-assignment)
|
||||
- reset random seed on grunt
|
||||
- fix vhost mode for empty hostname
|
||||
- fixed python3+virtualenv support
|
||||
- tasks are now allowed to chdir() in spooler
|
||||
- better zeromq+clustering support
|
||||
- clustering has been refactored
|
||||
- fixed rpc
|
||||
- report correct worker id in cheap mode
|
||||
- fixed a fd-leak in attach-daemon
|
||||
- use setsid() in attach-daemon
|
||||
- zerg mode
|
||||
- added psgix.harakiri
|
||||
- allows magic vars in sqlite3 config db
|
||||
- added UWSGI_FASTROUTER_KEY var
|
||||
- slowdown async-queue-is-full messages
|
||||
- new option --cron
|
||||
- --vassals-start-hook and --vassals-stop-hook
|
||||
- the proxy plugin has been removed
|
||||
|
||||
* 0.9.8 [20110605]
|
||||
|
||||
- support for --callable in virtualhosting mode
|
||||
- a NetBSD fix
|
||||
- abstract unix socket can be prefixed with \0 (nginx-style)
|
||||
- add /lib to the linker in sun-like systems
|
||||
- a mercy mode of 5 seconds is enabled by default on SIGINT/SIGQUIT
|
||||
|
||||
* 0.9.8-rc4 [20110602]
|
||||
|
||||
@@ -14,6 +57,8 @@
|
||||
- fixed idle mode in single-process
|
||||
- fixed solaris iovec
|
||||
|
||||
*** may 2011 ***
|
||||
|
||||
* 0.9.8-rc3 [20110530]
|
||||
|
||||
- snapshotting support
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
all:
|
||||
python uwsgiconfig.py --build
|
||||
|
||||
clean:
|
||||
python uwsgiconfig.py --clean
|
||||
|
||||
@@ -202,10 +202,12 @@ void *async_loop(void *arg1) {
|
||||
int is_a_new_connection;
|
||||
int proto_parser_status;
|
||||
|
||||
time_t now, last_now = 0;
|
||||
|
||||
static struct uwsgi_async_request *current_request = NULL, *next_async_request = NULL;
|
||||
|
||||
void *events = event_queue_alloc(64);
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
struct uwsgi_socket *uwsgi_sock;
|
||||
|
||||
uwsgi.async_runqueue = NULL;
|
||||
uwsgi.async_runqueue_cnt = 0;
|
||||
@@ -260,7 +262,11 @@ void *async_loop(void *arg1) {
|
||||
|
||||
uwsgi.wsgi_req = find_first_available_wsgi_req();
|
||||
if (uwsgi.wsgi_req == NULL) {
|
||||
uwsgi_log("async queue is full !!!\n");
|
||||
now = time(NULL);
|
||||
if (now > last_now) {
|
||||
uwsgi_log("async queue is full !!!\n");
|
||||
last_now = now;
|
||||
}
|
||||
break;;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ struct uwsgi_subscriber_name *uwsgi_get_subscriber(struct uwsgi_dict *udict, cha
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uwsgi_add_subscriber(struct uwsgi_dict *udict, char *key, uint16_t keylen, char *address, uint64_t address_len) {
|
||||
void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *usr) {
|
||||
|
||||
char *ptr;
|
||||
uint64_t vallen = 0;
|
||||
@@ -139,11 +139,11 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, char *key, uint16_t keylen,
|
||||
int found = 0;
|
||||
int i;
|
||||
|
||||
ptr = uwsgi_dict_get(udict, key, keylen, &vallen);
|
||||
ptr = uwsgi_dict_get(udict, usr->key, usr->keylen, &vallen);
|
||||
if (ptr && vallen) {
|
||||
usub = (struct uwsgi_subscriber *) ptr;
|
||||
for(i=0;i<(int)usub->nodes;i++) {
|
||||
if (!uwsgi_strncmp(usub->names[i].name, usub->names[i].len, address, address_len)) {
|
||||
if (!uwsgi_strncmp(usub->names[i].name, usub->names[i].len, usr->address, usr->address_len)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@@ -157,8 +157,10 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, char *key, uint16_t keylen,
|
||||
break;
|
||||
}
|
||||
}
|
||||
usub->names[found].len = address_len;
|
||||
memcpy(usub->names[found].name, address, address_len);
|
||||
usub->names[found].len = usr->address_len;
|
||||
usub->names[found].modifier1 = usr->modifier1;
|
||||
usub->names[found].modifier2 = usr->modifier2;
|
||||
memcpy(usub->names[found].name, usr->address, usr->address_len);
|
||||
if (found == (int) usub->nodes) {
|
||||
usub->nodes++;
|
||||
}
|
||||
@@ -168,8 +170,10 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, char *key, uint16_t keylen,
|
||||
else {
|
||||
nusub.nodes = 1;
|
||||
nusub.current = 0;
|
||||
memcpy(nusub.names[0].name, address, address_len);
|
||||
uwsgi_dict_set(udict, key, keylen, (char *) &nusub, sizeof(struct uwsgi_subscriber));
|
||||
memcpy(nusub.names[0].name, usr->address, usr->address_len);
|
||||
nusub.names[0].modifier1 = usr->modifier1;
|
||||
nusub.names[0].modifier2 = usr->modifier2;
|
||||
uwsgi_dict_set(udict, usr->key, usr->keylen, (char *) &nusub, sizeof(struct uwsgi_subscriber));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import uwsgi
|
||||
from uwsgidecorators import *
|
||||
|
||||
from uwsgicc import app as application
|
||||
|
||||
import time
|
||||
|
||||
|
||||
@rpc("helloworld")
|
||||
def hello_world():
|
||||
return "Hello World"
|
||||
|
||||
@signal(1)
|
||||
def what_time_is_it(num):
|
||||
print(time.asctime())
|
||||
|
||||
|
||||
@timer(2, 3)
|
||||
def salut(num):
|
||||
print("Salut !!! 3 seconds elapsed and signal %d raised" % num)
|
||||
|
||||
@rbtimer(3, 10)
|
||||
def tenseconds(num):
|
||||
print("red black timer !!! 10 seconds elapsed and signal %d raised" % num)
|
||||
|
||||
@filemon(4, "/tmp")
|
||||
def tmpmodified(num):
|
||||
print("/tmp has been modified")
|
||||
@@ -84,6 +84,12 @@ void emperor_del(struct uwsgi_instance *c_ui) {
|
||||
close(c_ui->pipe_config[0]);
|
||||
}
|
||||
|
||||
if (uwsgi.vassals_stop_hook) {
|
||||
uwsgi_log("running vassal stop-hook: %s %s\n", uwsgi.vassals_stop_hook, c_ui->name);
|
||||
int stop_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_stop_hook, c_ui->name);
|
||||
uwsgi_log("%s stop-hook returned %d\n", c_ui->name, stop_hook_ret);
|
||||
}
|
||||
|
||||
uwsgi_log("removed uwsgi instance %s\n", c_ui->name);
|
||||
|
||||
free(c_ui);
|
||||
@@ -131,6 +137,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
char *uef;
|
||||
char **uenvs;
|
||||
int counter;
|
||||
int i;
|
||||
|
||||
sleep(1);
|
||||
|
||||
@@ -276,6 +283,20 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
uct = uct->next;
|
||||
}
|
||||
argv[counter] = NULL;
|
||||
|
||||
// close all of the unneded fd
|
||||
for(i=3;i<sysconf(_SC_OPEN_MAX);i++) {
|
||||
if (i != n_ui->pipe[1]) {
|
||||
close(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.vassals_start_hook) {
|
||||
uwsgi_log("running vassal start-hook: %s %s\n", uwsgi.vassals_start_hook, n_ui->name);
|
||||
int start_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_start_hook, n_ui->name);
|
||||
uwsgi_log("%s start-hook returned %d\n", n_ui->name, start_hook_ret);
|
||||
}
|
||||
|
||||
// start !!!
|
||||
if (execvp(argv[0], argv)) {
|
||||
uwsgi_error("execvp()");
|
||||
@@ -422,6 +443,7 @@ reconnect:
|
||||
ui_current->config = config;
|
||||
ui_current->config_len = msgsize;
|
||||
if (!msgsize) {
|
||||
// SAFE
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
else {
|
||||
@@ -480,6 +502,7 @@ reconnect:
|
||||
char byte;
|
||||
ssize_t rlen = read(interesting_fd, &byte, 1);
|
||||
if (rlen <= 0) {
|
||||
// SAFE
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
else {
|
||||
@@ -609,12 +632,14 @@ reconnect:
|
||||
if (amqp_fd > -1) {
|
||||
if (!ui_current->loyal && (time(NULL)-ui_current->last_loyal) > 60) {
|
||||
uwsgi_log("!!! no loyalty showed by instance %s !!!\n", ui_current->name);
|
||||
// SAFE
|
||||
emperor_del(ui_current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ui_current->status == 1) {
|
||||
if (ui_current->config) free(ui_current->config);
|
||||
// SAFE
|
||||
emperor_del(ui_current);
|
||||
break;
|
||||
}
|
||||
@@ -625,9 +650,11 @@ reconnect:
|
||||
if (ui_current->status == 0) {
|
||||
// respawn an accidentally dead instance if its exit code is not UWSGI_EXILE_CODE
|
||||
if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_EXILE_CODE) {
|
||||
// SAFE
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
else {
|
||||
// UNSAFE
|
||||
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len);
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
@@ -636,6 +663,7 @@ reconnect:
|
||||
else if (ui_current->status == 1) {
|
||||
// remove 'marked for dead' instance
|
||||
if (ui_current->config) free(ui_current->config);
|
||||
// SAFE
|
||||
emperor_del(ui_current);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -591,7 +591,9 @@ int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
||||
|
||||
*id = inotify_add_watch(ifd, filename, IN_ATTRIB|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MODIFY|IN_MOVE_SELF|IN_MOVED_FROM|IN_MOVED_TO);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("added watch %d for filename %s\n", *id, filename);
|
||||
#endif
|
||||
|
||||
if (add_to_queue) {
|
||||
return event_queue_add_fd_read(eq, ifd);
|
||||
@@ -630,7 +632,9 @@ struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
||||
}
|
||||
else {
|
||||
items = isize/(sizeof(struct inotify_event));
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("inotify returned %d items\n", items);
|
||||
#endif
|
||||
for(j=0;j<items;j++) {
|
||||
iie = &bie[j];
|
||||
for(i=0;i<ushared->files_monitored_cnt;i++) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
app.debug = True
|
||||
|
||||
@app.route('/')
|
||||
def hello_world():
|
||||
return "<form method='POST' enctype='multipart/form-data' action='/upload'><input type='text' name='pippo'/><input type='file' name='ufile'/><input type='submit' value='upload'/></form>"
|
||||
|
||||
@app.route('/upload', methods=['GET', 'POST'])
|
||||
def upload_file():
|
||||
return str(len(request.form.get('pippo', 'boh'))) + request.form.get('pippo', 'boh')
|
||||
return request.files['ufile'].read()
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>it.unbit.uwsgi.emperor</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Users/roberta/uwsgi/uwsgi</string>
|
||||
<string>--emperor</string>
|
||||
<string>/Users/*/Library/uwsgi/*.{xml,ini,yml,yaml,js}</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>it.unbit.uwsgi</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Users/roberta/uwsgi/uwsgi</string>
|
||||
<string>--socket</string>
|
||||
<string>:3032</string>
|
||||
<string>--module</string>
|
||||
<string>welcome</string>
|
||||
<string>--master</string>
|
||||
<string>--die-on-term</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -25,6 +25,16 @@
|
||||
|
||||
#include "../uwsgi.h"
|
||||
|
||||
static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
|
||||
{
|
||||
rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
|
||||
}
|
||||
static inline void rb_set_color(struct rb_node *rb, int color)
|
||||
{
|
||||
rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
|
||||
}
|
||||
|
||||
|
||||
static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
|
||||
{
|
||||
struct rb_node *right = node->rb_right;
|
||||
@@ -282,3 +292,18 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
|
||||
if (color == RB_BLACK)
|
||||
__rb_erase_color(child, parent, root);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
void rb_link_node(struct rb_node * node, struct rb_node * parent,
|
||||
struct rb_node ** rb_link)
|
||||
#else
|
||||
inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
|
||||
struct rb_node ** rb_link)
|
||||
#endif
|
||||
{
|
||||
node->rb_parent_color = (unsigned long )parent;
|
||||
node->rb_left = node->rb_right = NULL;
|
||||
|
||||
*rb_link = node;
|
||||
}
|
||||
|
||||
|
||||
+7
-19
@@ -37,7 +37,6 @@ struct rb_root
|
||||
struct rb_node *rb_node;
|
||||
};
|
||||
|
||||
|
||||
#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
|
||||
#define rb_color(r) ((r)->rb_parent_color & 1)
|
||||
#define rb_is_red(r) (!rb_color(r))
|
||||
@@ -45,24 +44,13 @@ struct rb_root
|
||||
#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
|
||||
#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
|
||||
|
||||
static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
|
||||
{
|
||||
rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
|
||||
}
|
||||
static inline void rb_set_color(struct rb_node *rb, int color)
|
||||
{
|
||||
rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
|
||||
}
|
||||
|
||||
void rb_insert_color(struct rb_node *, struct rb_root *);
|
||||
void rb_erase(struct rb_node *, struct rb_root *);
|
||||
|
||||
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
|
||||
struct rb_node ** rb_link)
|
||||
{
|
||||
node->rb_parent_color = (unsigned long )parent;
|
||||
node->rb_left = node->rb_right = NULL;
|
||||
|
||||
*rb_link = node;
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
void rb_link_node(struct rb_node *, struct rb_node *,
|
||||
struct rb_node **);
|
||||
#else
|
||||
inline void rb_link_node(struct rb_node *, struct rb_node *,
|
||||
struct rb_node **);
|
||||
#endif
|
||||
|
||||
@@ -173,6 +173,8 @@ void get_memusage() {
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
kv = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, NULL);
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
kv = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
|
||||
#else
|
||||
kv = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
|
||||
#endif
|
||||
|
||||
@@ -66,19 +66,19 @@ void *simple_loop(void *arg1) {
|
||||
#endif
|
||||
|
||||
// initialize the main event queue to monitor sockets
|
||||
uwsgi.main_queue = event_queue_init();
|
||||
int main_queue = event_queue_init();
|
||||
|
||||
uwsgi_add_sockets_to_queue(uwsgi.main_queue);
|
||||
uwsgi_add_sockets_to_queue(main_queue);
|
||||
|
||||
if (uwsgi.signal_socket > -1) {
|
||||
event_queue_add_fd_read(uwsgi.main_queue, uwsgi.signal_socket);
|
||||
event_queue_add_fd_read(main_queue, uwsgi.signal_socket);
|
||||
}
|
||||
|
||||
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
|
||||
wsgi_req_setup(wsgi_req, core_id, NULL);
|
||||
|
||||
if (wsgi_req_accept(wsgi_req)) {
|
||||
if (wsgi_req_accept(main_queue, wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,18 @@ void *simple_loop(void *arg1) {
|
||||
}
|
||||
|
||||
// end of the loop
|
||||
if (uwsgi.workers[uwsgi.mywid].destroy && uwsgi.workers[0].pid > 0) {
|
||||
#ifdef __APPLE__
|
||||
kill(uwsgi.workers[0].pid, SIGTERM);
|
||||
#else
|
||||
if (uwsgi.propagate_touch) {
|
||||
kill(uwsgi.workers[0].pid, SIGHUP);
|
||||
}
|
||||
else {
|
||||
gracefully_kill(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,32 +42,24 @@ void expire_rb_timeouts(struct rb_root *root) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_subscribe(char *subscription) {
|
||||
|
||||
void uwsgi_send_subscription(char *udp_address, char *key, size_t keysize, char *modifier1, size_t modifier1_len) {
|
||||
char *ssb;
|
||||
char subscrbuf[4096];
|
||||
|
||||
uint16_t ustrlen;
|
||||
|
||||
char *udp_address = strchr(subscription,':');
|
||||
if (!udp_address) return;
|
||||
ssb = subscrbuf;
|
||||
|
||||
char *subscription_key = strchr(udp_address+1, ':');
|
||||
if (!subscription_key) return;
|
||||
udp_address = uwsgi_concat2n(subscription, subscription_key-subscription, "", 0);
|
||||
|
||||
ssb = subscrbuf;
|
||||
|
||||
ustrlen = 3;
|
||||
ustrlen = 3;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "key", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = strlen(subscription_key+1);
|
||||
ustrlen = keysize;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, subscription_key+1, ustrlen);
|
||||
memcpy(ssb, key, ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = 7;
|
||||
@@ -82,8 +74,106 @@ void uwsgi_subscribe(char *subscription) {
|
||||
memcpy(ssb, uwsgi.sockets->name, ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
if (modifier1) {
|
||||
ustrlen = 9;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, "modifier1", ustrlen);
|
||||
ssb+=ustrlen;
|
||||
|
||||
ustrlen = modifier1_len;
|
||||
*ssb++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ssb++ = (uint8_t) ((ustrlen >>8) & 0xff);
|
||||
memcpy(ssb, modifier1, ustrlen);
|
||||
ssb+=ustrlen;
|
||||
}
|
||||
|
||||
send_udp_message(224, udp_address, subscrbuf, ssb-subscrbuf);
|
||||
free(udp_address);
|
||||
}
|
||||
|
||||
void uwsgi_subscribe(char *subscription) {
|
||||
|
||||
int subfile_size;
|
||||
int i;
|
||||
char *key = NULL;
|
||||
int keysize = 0;
|
||||
char *modifier1 = NULL;
|
||||
int modifier1_len = 0;
|
||||
|
||||
char *udp_address = strchr(subscription,':');
|
||||
if (!udp_address) return;
|
||||
|
||||
char *subscription_key = strchr(udp_address+1, ':');
|
||||
if (!subscription_key) return;
|
||||
|
||||
udp_address = uwsgi_concat2n(subscription, subscription_key-subscription, "", 0);
|
||||
|
||||
if (subscription_key[1] == '@') {
|
||||
if (!uwsgi_file_exists(subscription_key+2)) goto clear;
|
||||
char *lines = uwsgi_open_and_read(subscription_key+2, &subfile_size, 1, NULL);
|
||||
if (subfile_size > 0) {
|
||||
key = lines;
|
||||
for(i=0;i<subfile_size;i++) {
|
||||
if (lines[i] == 0) {
|
||||
if (keysize > 0) {
|
||||
if (key[0] != '#' && key[0] != '\n') {
|
||||
modifier1 = strchr(key, ':');
|
||||
if (modifier1) {
|
||||
modifier1[0] = 0;
|
||||
modifier1++;
|
||||
modifier1_len = strlen(modifier1);
|
||||
keysize = strlen(key);
|
||||
}
|
||||
uwsgi_send_subscription(udp_address, key, keysize, modifier1, modifier1_len);
|
||||
modifier1 = NULL;
|
||||
modifier1_len = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (lines[i] == '\n') {
|
||||
if (keysize > 0) {
|
||||
if (key[0] != '#' && key[0] != '\n') {
|
||||
lines[i] = 0;
|
||||
modifier1 = strchr(key, ':');
|
||||
if (modifier1) {
|
||||
modifier1[0] = 0;
|
||||
modifier1++;
|
||||
modifier1_len = strlen(modifier1);
|
||||
keysize = strlen(key);
|
||||
}
|
||||
uwsgi_send_subscription(udp_address, key, keysize, modifier1, modifier1_len);
|
||||
modifier1 = NULL;
|
||||
modifier1_len = 0;
|
||||
lines[i] = '\n';
|
||||
}
|
||||
}
|
||||
key = lines+i+1;
|
||||
keysize = 0;
|
||||
continue;
|
||||
}
|
||||
keysize++;
|
||||
}
|
||||
|
||||
free(lines);
|
||||
}
|
||||
}
|
||||
else {
|
||||
modifier1 = strchr(subscription_key+1, ':');
|
||||
if (modifier1) {
|
||||
modifier1[0] = 0;
|
||||
modifier1++;
|
||||
modifier1_len = strlen(modifier1);
|
||||
}
|
||||
|
||||
uwsgi_send_subscription(udp_address, subscription_key+1, strlen(subscription_key+1), modifier1, modifier1_len);
|
||||
if (modifier1)
|
||||
modifier1[-1] = ':';
|
||||
}
|
||||
|
||||
clear:
|
||||
|
||||
free(udp_address);
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +200,10 @@ void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t val
|
||||
|
||||
char *tmpstr;
|
||||
struct uwsgi_cluster_node *ucn = (struct uwsgi_cluster_node *) data;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%.*s = %.*s\n", keylen, key, vallen, val);
|
||||
#endif
|
||||
|
||||
if (!uwsgi_strncmp("hostname", 8, key, keylen)) {
|
||||
strncpy(ucn->nodename, val, UMIN(vallen, 255));
|
||||
@@ -187,7 +280,6 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
struct uwsgi_rb_timer *min_timeout;
|
||||
struct rb_root *rb_timers = uwsgi_init_rb_timer();
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
uwsgi.current_time = time(NULL);
|
||||
|
||||
@@ -206,7 +298,6 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_unix_signal(SIGURG, uwsgi_restore_auto_snapshot);
|
||||
}
|
||||
|
||||
|
||||
uwsgi.master_queue = event_queue_init();
|
||||
|
||||
/* route signals to workers... */
|
||||
@@ -228,6 +319,12 @@ void master_loop(char **argv, char **environ) {
|
||||
if (uwsgi.has_emperor) {
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.emperor_fd);
|
||||
}
|
||||
|
||||
if (uwsgi.zerg_server) {
|
||||
uwsgi.zerg_server_fd = bind_to_unix(uwsgi.zerg_server, uwsgi.listen_queue, 0, 0);
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.zerg_server_fd);
|
||||
uwsgi_log("*** Zerg server enabled on %s ***\n", uwsgi.zerg_server);
|
||||
}
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket) {
|
||||
udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
|
||||
@@ -600,70 +697,11 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
// check uwsgi-cron table
|
||||
if (ushared->cron_cnt) {
|
||||
uwsgi.current_time = time(NULL);
|
||||
uwsgi_cron_delta = localtime( &uwsgi.current_time );
|
||||
uwsgi_manage_signal_cron(time(NULL));
|
||||
}
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
for(i=0;i<ushared->cron_cnt;i++) {
|
||||
|
||||
struct uwsgi_cron *ucron = &ushared->cron[i];
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uc_minute = ucron->minute;
|
||||
uc_hour = ucron->hour;
|
||||
uc_day = ucron->day;
|
||||
uc_month = ucron->month;
|
||||
uc_week = ucron->week;
|
||||
|
||||
if (ucron->minute == -1) uc_minute = uwsgi_cron_delta->tm_min;
|
||||
if (ucron->hour == -1) uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
if (ucron->month == -1) uc_month = uwsgi_cron_delta->tm_mon;
|
||||
|
||||
// mday and wday are ORed
|
||||
if (ucron->day == -1 && ucron->week == -1) {
|
||||
if (ucron->day == -1) uc_day = uwsgi_cron_delta->tm_mday;
|
||||
if (ucron->week == -1) uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->day == -1) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
else if (ucron->week == -1) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else {
|
||||
if (ucron->day == uwsgi_cron_delta->tm_mday) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->week == uwsgi_cron_delta->tm_wday) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute &&
|
||||
uwsgi_cron_delta->tm_hour == uc_hour &&
|
||||
uwsgi_cron_delta->tm_mon == uc_month &&
|
||||
uwsgi_cron_delta->tm_mday == uc_day &&
|
||||
uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
|
||||
|
||||
// date match, signal it ?
|
||||
if (uwsgi.current_time - ucron->last_job > 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = uwsgi.current_time;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("localtime()");
|
||||
}
|
||||
if (uwsgi.crons) {
|
||||
uwsgi_manage_command_cron(time(NULL));
|
||||
}
|
||||
|
||||
if (rlen > 0) {
|
||||
@@ -693,12 +731,62 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.zerg_server) {
|
||||
if (interesting_fd == uwsgi.zerg_server_fd) {
|
||||
struct sockaddr_un zsun;
|
||||
socklen_t zsun_len = sizeof(struct sockaddr_un);
|
||||
int zerg_client = accept(uwsgi.zerg_server_fd, (struct sockaddr *) &zsun, &zsun_len);
|
||||
if (zerg_client < 0) {
|
||||
uwsgi_error("zerg: accept()");
|
||||
continue;
|
||||
}
|
||||
|
||||
struct msghdr zerg_msg;
|
||||
void *zerg_msg_control = uwsgi_malloc(CMSG_SPACE (sizeof (int) * uwsgi_count_sockets(uwsgi.sockets)));
|
||||
struct iovec zerg_iov;
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
zerg_iov.iov_base = "uwsgi-zerg";
|
||||
zerg_iov.iov_len = 10;
|
||||
|
||||
zerg_msg.msg_name = NULL;
|
||||
zerg_msg.msg_namelen = 0;
|
||||
zerg_msg.msg_iov = &zerg_iov;
|
||||
zerg_msg.msg_iovlen = 1;
|
||||
zerg_msg.msg_flags = 0;
|
||||
zerg_msg.msg_control = zerg_msg_control;
|
||||
zerg_msg.msg_controllen = CMSG_SPACE (sizeof (int) * uwsgi_count_sockets(uwsgi.sockets));
|
||||
|
||||
cmsg = CMSG_FIRSTHDR (&zerg_msg);
|
||||
cmsg->cmsg_len = CMSG_LEN (sizeof (int) * uwsgi_count_sockets(uwsgi.sockets));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
unsigned char *zerg_fd_ptr = CMSG_DATA(cmsg);
|
||||
while(uwsgi_sock) {
|
||||
memcpy(zerg_fd_ptr, &uwsgi_sock->fd, sizeof(int));
|
||||
zerg_fd_ptr += sizeof(int);
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
if (sendmsg(zerg_client, &zerg_msg, 0) < 0) {
|
||||
uwsgi_error("sendmsg()");
|
||||
}
|
||||
|
||||
|
||||
close(zerg_client);
|
||||
|
||||
free(zerg_msg_control);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.has_emperor) {
|
||||
if (interesting_fd == uwsgi.emperor_fd) {
|
||||
char byte;
|
||||
rlen = read(uwsgi.emperor_fd, &byte, 1);
|
||||
if (rlen > 0) {
|
||||
uwsgi_log("received message %d from emperor\n", byte);
|
||||
uwsgi_log_verbose("received message %d from emperor\n", byte);
|
||||
// remove me
|
||||
if (byte == 0) {
|
||||
close(uwsgi.emperor_fd);
|
||||
@@ -888,7 +976,7 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
uwsgi_log("received uwsgi signal %d from workers\n", uwsgi_signal);
|
||||
uwsgi_log_verbose("received uwsgi signal %d from a worker\n", uwsgi_signal);
|
||||
uwsgi_route_signal(uwsgi_signal);
|
||||
}
|
||||
else {
|
||||
|
||||
+207
-47
@@ -7,63 +7,223 @@ void master_check_cluster_nodes() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
struct uwsgi_cluster_node *ucn = &uwsgi.shared->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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
int i;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
if (uwsgi.master_process && (uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (pid < 1) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
if (respawns > 0) {
|
||||
uwsgi_log("Respawned uWSGI worker %d (new pid: %d)\n", wid, (int) pid);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("spawned uWSGI worker %d (pid: %d, cores: %d)\n", wid, pid, uwsgi.cores);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_manage_signal_cron(time_t now) {
|
||||
|
||||
struct tm *uwsgi_cron_delta;
|
||||
int i;
|
||||
|
||||
uwsgi.current_time = now;
|
||||
uwsgi_cron_delta = localtime(&uwsgi.current_time);
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
for (i = 0; i < ushared->cron_cnt; i++) {
|
||||
|
||||
struct uwsgi_cron *ucron = &ushared->cron[i];
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uc_minute = ucron->minute;
|
||||
uc_hour = ucron->hour;
|
||||
uc_day = ucron->day;
|
||||
uc_month = ucron->month;
|
||||
uc_week = ucron->week;
|
||||
|
||||
if (ucron->minute == -1)
|
||||
uc_minute = uwsgi_cron_delta->tm_min;
|
||||
if (ucron->hour == -1)
|
||||
uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
if (ucron->month == -1)
|
||||
uc_month = uwsgi_cron_delta->tm_mon;
|
||||
|
||||
// mday and wday are ORed
|
||||
if (ucron->day == -1 && ucron->week == -1) {
|
||||
if (ucron->day == -1)
|
||||
uc_day = uwsgi_cron_delta->tm_mday;
|
||||
if (ucron->week == -1)
|
||||
uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->day == -1) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
else if (ucron->week == -1) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else {
|
||||
if (ucron->day == uwsgi_cron_delta->tm_mday) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->week == uwsgi_cron_delta->tm_wday) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
|
||||
|
||||
// date match, signal it ?
|
||||
if (uwsgi.current_time - ucron->last_job > 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = uwsgi.current_time;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("localtime()");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_manage_command_cron(time_t now) {
|
||||
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
struct uwsgi_cron *current_cron = uwsgi.crons;
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uwsgi.current_time = now;
|
||||
uwsgi_cron_delta = localtime(&uwsgi.current_time);
|
||||
|
||||
|
||||
if (!uwsgi_cron_delta) {
|
||||
uwsgi_error("localtime()");
|
||||
return;
|
||||
}
|
||||
|
||||
while (current_cron) {
|
||||
|
||||
|
||||
uc_minute = current_cron->minute;
|
||||
uc_hour = current_cron->hour;
|
||||
uc_day = current_cron->day;
|
||||
uc_month = current_cron->month;
|
||||
uc_week = current_cron->week;
|
||||
|
||||
if (current_cron->minute == -1)
|
||||
uc_minute = uwsgi_cron_delta->tm_min;
|
||||
if (current_cron->hour == -1)
|
||||
uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
if (current_cron->month == -1)
|
||||
uc_month = uwsgi_cron_delta->tm_mon;
|
||||
|
||||
// mday and wday are ORed
|
||||
if (current_cron->day == -1 && current_cron->week == -1) {
|
||||
if (current_cron->day == -1)
|
||||
uc_day = uwsgi_cron_delta->tm_mday;
|
||||
if (current_cron->week == -1)
|
||||
uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (current_cron->day == -1) {
|
||||
current_cron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
else if (current_cron->week == -1) {
|
||||
current_cron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else {
|
||||
if (current_cron->day == uwsgi_cron_delta->tm_mday) {
|
||||
current_cron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (current_cron->week == uwsgi_cron_delta->tm_wday) {
|
||||
current_cron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
|
||||
|
||||
// date match, run command ?
|
||||
if (uwsgi.current_time - current_cron->last_job > 60) {
|
||||
//call command
|
||||
if (current_cron->command) {
|
||||
if (uwsgi_run_command(current_cron->command) >=0) {
|
||||
uwsgi_log_verbose("[uWSGI-cron] running %s\n", current_cron->command);
|
||||
}
|
||||
}
|
||||
current_cron->last_job = uwsgi.current_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
current_cron = current_cron->next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-8
@@ -1,14 +1,9 @@
|
||||
import werkzeug
|
||||
|
||||
def web3_app(environ):
|
||||
status = b'200 OK'
|
||||
headers = [(b'Content-type', b'text/plain')]
|
||||
body = [b'I am a Web3 app\n']
|
||||
return body, status, headers
|
||||
import uwsgi
|
||||
|
||||
def zero_app(e,s):
|
||||
s('200 OK', [ ('Content-Type', 'text/plain') ])
|
||||
return ""
|
||||
return "0"
|
||||
|
||||
def not_found(e,s):
|
||||
s('404 Not Found', [ ('Content-Type', 'text/plain') ])
|
||||
@@ -24,4 +19,4 @@ def internal_server_error(e, s):
|
||||
s('500 Internal Server Error', [ ('Content-Type', 'text/plain') ])
|
||||
return ""
|
||||
|
||||
applications = {'':web3_app, '/wsgi':wsgi_app, '/test':werkzeug.test_app, '/zero':zero_app, '/notfound':not_found, '/ise':internal_server_error}
|
||||
uwsgi.applications = {'/wsgi':wsgi_app, '/test':werkzeug.test_app, '/zero':zero_app, '/notfound':not_found, '/ise':internal_server_error}
|
||||
|
||||
@@ -5,7 +5,7 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_echo_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
wsgi_req->response_size = wsgi_req->socket_proto_write(wsgi_req, wsgi_req->buffer, wsgi_req->uh.pktsize);
|
||||
wsgi_req->response_size = wsgi_req->socket->proto_write(wsgi_req, wsgi_req->buffer, wsgi_req->uh.pktsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ void fastrouter_manage_subscription(char *key, uint16_t keylen, char *val, uint1
|
||||
usr->address = val;
|
||||
usr->address_len = vallen;
|
||||
}
|
||||
|
||||
else if (!uwsgi_strncmp("modifier1", 9, key, keylen)) {
|
||||
usr->modifier1 = uwsgi_str_num(val, vallen);
|
||||
}
|
||||
}
|
||||
|
||||
struct fastrouter_session {
|
||||
@@ -126,6 +130,8 @@ struct fastrouter_session {
|
||||
char *hostname;
|
||||
uint16_t hostname_len;
|
||||
|
||||
int has_key;
|
||||
|
||||
char *instance_address;
|
||||
uint64_t instance_address_len;
|
||||
|
||||
@@ -134,6 +140,8 @@ struct fastrouter_session {
|
||||
|
||||
struct uwsgi_rb_timer *timeout;
|
||||
int instance_failed;
|
||||
|
||||
uint8_t modifier1;
|
||||
};
|
||||
|
||||
static void close_session(struct fastrouter_session **fr_table, struct fastrouter_session *fr_session) {
|
||||
@@ -187,7 +195,14 @@ void fr_get_hostname(char *key, uint16_t keylen, char *val, uint16_t vallen, voi
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uwsgi_strncmp("HTTP_HOST", 9, key, keylen)) {
|
||||
if (!uwsgi_strncmp("HTTP_HOST", 9, key, keylen) && !fr_session->has_key) {
|
||||
fr_session->hostname = val;
|
||||
fr_session->hostname_len = vallen;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uwsgi_strncmp("UWSGI_FASTROUTER_KEY", 20, key, keylen)) {
|
||||
fr_session->has_key = 1;
|
||||
fr_session->hostname = val;
|
||||
fr_session->hostname_len = vallen;
|
||||
return;
|
||||
@@ -360,7 +375,7 @@ void fastrouter_loop() {
|
||||
if (len > 0) {
|
||||
memset(&usr, 0, sizeof(struct uwsgi_subscribe_req));
|
||||
uwsgi_hooked_parse(bbuf+4, len-4, fastrouter_manage_subscription, &usr);
|
||||
uwsgi_add_subscriber(ufr.subscription_dict, usr.key, usr.keylen, usr.address, usr.address_len);
|
||||
uwsgi_add_subscriber(ufr.subscription_dict, &usr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -414,7 +429,9 @@ void fastrouter_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
//uwsgi_log("requested domain %.*s\n", fr_session->hostname_len, fr_session->hostname);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("requested domain %.*s\n", fr_session->hostname_len, fr_session->hostname);
|
||||
#endif
|
||||
if (ufr.use_cache) {
|
||||
fr_session->instance_address = uwsgi_cache_get(fr_session->hostname, fr_session->hostname_len, &fr_session->instance_address_len);
|
||||
}
|
||||
@@ -430,6 +447,7 @@ void fastrouter_loop() {
|
||||
if (fr_session->un && fr_session->un->len) {
|
||||
fr_session->instance_address = fr_session->un->name;
|
||||
fr_session->instance_address_len = fr_session->un->len;
|
||||
fr_session->modifier1 = fr_session->un->modifier1;
|
||||
}
|
||||
}
|
||||
else if (ufr.base) {
|
||||
@@ -487,6 +505,8 @@ void fastrouter_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
fr_session->uh.modifier1 = fr_session->modifier1;
|
||||
|
||||
iov[0].iov_base = &fr_session->uh;
|
||||
iov[0].iov_len = 4;
|
||||
iov[1].iov_base = fr_session->buffer;
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ void http_loop() {
|
||||
if (len > 0) {
|
||||
memset(&usr, 0, sizeof(struct uwsgi_subscribe_req));
|
||||
uwsgi_hooked_parse(bbuf+4, len-4, http_manage_subscription, &usr);
|
||||
uwsgi_add_subscriber(uhttp.subscription_dict, usr.key, usr.keylen, usr.address, usr.address_len);
|
||||
uwsgi_add_subscriber(uhttp.subscription_dict, &usr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -16,6 +16,16 @@ NAME='jvm'
|
||||
JVM_INCPATH = "/usr/lib/jvm/java-6-sun-1.6.0.15/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.15/include/linux"
|
||||
JVM_LIBPATH = "/usr/lib/jvm/java-6-sun-1.6.0.15/jre/lib/i386/server/"
|
||||
|
||||
try:
|
||||
JVM_INCPATH = os.environ['UWSGICONFIG_JVM_INCPATH']
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
JVM_LIBPATH = os.environ['UWSGICONFIG_JVM_LIBPATH']
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
JVM_INCPATH = os.environ['UWSGICONFIG_JVM_INCPATH']
|
||||
except:
|
||||
|
||||
+14
-11
@@ -16,7 +16,7 @@ struct option nagios_options[] = {
|
||||
int nagios() {
|
||||
|
||||
char *tcp_port;
|
||||
struct pollfd nagios_poll;
|
||||
struct wsgi_request nagios_req;
|
||||
// connect and send
|
||||
|
||||
if (!use_nagios) {
|
||||
@@ -34,27 +34,30 @@ int nagios() {
|
||||
|
||||
tcp_port[0] = 0;
|
||||
|
||||
nagios_poll.fd = connect_to_tcp(uwsgi.sockets->name, atoi(tcp_port + 1), uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
if (nagios_poll.fd < 0) {
|
||||
int fd = connect_to_tcp(uwsgi.sockets->name, atoi(tcp_port + 1), uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
|
||||
if (fd < 0) {
|
||||
fprintf(stdout, "UWSGI CRITICAL: could not connect() to workers\n");
|
||||
exit(2);
|
||||
}
|
||||
uwsgi.wsgi_req->uh.modifier1 = UWSGI_MODIFIER_PING;
|
||||
uwsgi.wsgi_req->uh.pktsize = 0;
|
||||
uwsgi.wsgi_req->uh.modifier2 = 0;
|
||||
if (write(nagios_poll.fd, uwsgi.wsgi_req, 4) != 4) {
|
||||
nagios_req.uh.modifier1 = UWSGI_MODIFIER_PING;
|
||||
nagios_req.uh.pktsize = 0;
|
||||
nagios_req.uh.modifier2 = 0;
|
||||
if (write(fd, &nagios_req.uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
fprintf(stdout, "UWSGI CRITICAL: could not send ping packet to workers\n");
|
||||
exit(2);
|
||||
}
|
||||
nagios_poll.events = POLLIN;
|
||||
if (!uwsgi_parse_response(&nagios_poll, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) uwsgi.wsgi_req, uwsgi.wsgi_req->buffer, uwsgi_proto_uwsgi_parser)) {
|
||||
|
||||
nagios_req.poll.fd = fd;
|
||||
nagios_req.poll.events = POLLIN;
|
||||
|
||||
if (!uwsgi_parse_packet(&nagios_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
|
||||
fprintf(stdout, "UWSGI CRITICAL: timed out waiting for response\n");
|
||||
exit(2);
|
||||
}
|
||||
else {
|
||||
if (uwsgi.wsgi_req->uh.pktsize > 0) {
|
||||
fprintf(stdout, "UWSGI WARNING: %.*s\n", uwsgi.wsgi_req->uh.pktsize, uwsgi.wsgi_req->buffer);
|
||||
if (nagios_req.uh.pktsize > 0) {
|
||||
fprintf(stdout, "UWSGI WARNING: %.*s\n", nagios_req.uh.pktsize, nagios_req.buffer);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
|
||||
+18
-11
@@ -15,32 +15,38 @@ struct option uwsgi_ping_options[] = {
|
||||
|
||||
static void ping() {
|
||||
|
||||
struct uwsgi_header uh;
|
||||
struct pollfd uwsgi_poll;
|
||||
struct wsgi_request ping_req;
|
||||
char *buf = uwsgi_malloc(uwsgi.buffer_size);
|
||||
|
||||
// use a 3 secs timeout by default
|
||||
if (!uping.ping_timeout) uping.ping_timeout = 3;
|
||||
|
||||
uwsgi_log("PING uwsgi host %s (timeout: %d)\n", uping.ping, uping.ping_timeout);
|
||||
|
||||
uwsgi_poll.fd = uwsgi_connect(uping.ping, uping.ping_timeout, 0);
|
||||
if (uwsgi_poll.fd < 0) {
|
||||
int fd = uwsgi_connect(uping.ping, uping.ping_timeout, 0);
|
||||
if (fd < 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uh.modifier1 = UWSGI_MODIFIER_PING;
|
||||
uh.pktsize = 0;
|
||||
uh.modifier2 = 0;
|
||||
if (write(uwsgi_poll.fd, &uh, 4) != 4) {
|
||||
memset(&ping_req, 0, sizeof(struct wsgi_request));
|
||||
ping_req.uh.modifier1 = UWSGI_MODIFIER_PING;
|
||||
ping_req.uh.pktsize = 0;
|
||||
ping_req.uh.modifier2 = 0;
|
||||
if (write(fd, &ping_req.uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
exit(2);
|
||||
}
|
||||
uwsgi_poll.events = POLLIN;
|
||||
if (!uwsgi_parse_response(&uwsgi_poll, uping.ping_timeout, &uh, NULL, uwsgi_proto_uwsgi_parser)) {
|
||||
ping_req.poll.fd = fd;
|
||||
ping_req.poll.events = POLLIN;
|
||||
|
||||
ping_req.buffer = buf;
|
||||
|
||||
if (!uwsgi_parse_packet(&ping_req, uping.ping_timeout)) {
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
if (uh.pktsize > 0) {
|
||||
if (ping_req.uh.pktsize > 0) {
|
||||
uwsgi_log("[WARNING] node %s message: %.*s\n", uping.ping, ping_req.uh.pktsize, buf);
|
||||
exit(2);
|
||||
}
|
||||
else {
|
||||
@@ -92,6 +98,7 @@ int uwsgi_ping_manage_options(int i, char *optarg) {
|
||||
|
||||
switch(i) {
|
||||
case LONG_ARGS_PING:
|
||||
uwsgi.no_server = 1;
|
||||
uping.ping = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PING_TIMEOUT:
|
||||
|
||||
@@ -1,490 +0,0 @@
|
||||
/*
|
||||
|
||||
uWSGI proxy
|
||||
|
||||
it needs one of this tecnology to work:
|
||||
|
||||
- epoll (linux 2.6)
|
||||
- kqueue (various BSD and Darwin)
|
||||
- /dev/poll (Solaris)
|
||||
|
||||
*/
|
||||
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
#define LONG_ARGS_PROXY_WORKERS 50000
|
||||
|
||||
struct uwsgi_proxy {
|
||||
char *socket_name;
|
||||
int add_me;
|
||||
int workers;
|
||||
int fd;
|
||||
} uproxy;
|
||||
|
||||
struct option proxy_options[] = {
|
||||
{"proxy", required_argument, 0, LONG_ARGS_PROXY},
|
||||
{"proxy-node", required_argument, 0, LONG_ARGS_PROXY_NODE},
|
||||
{"proxy-max-connections", required_argument, 0, LONG_ARGS_PROXY_MAX_CONNECTIONS},
|
||||
{"proxy-workers", required_argument, 0, LONG_ARGS_PROXY_WORKERS},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
#define UWSGI_PROXY_CONNECTING 1
|
||||
#define UWSGI_PROXY_WAITING 2
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct uwsgi_proxy_connection {
|
||||
|
||||
int dest_fd;
|
||||
int status;
|
||||
int retry;
|
||||
int node;
|
||||
};
|
||||
|
||||
static void end_proxy(void) {
|
||||
exit(UWSGI_END_CODE);
|
||||
}
|
||||
|
||||
|
||||
static void reload_proxy(void) {
|
||||
exit(UWSGI_RELOAD_CODE);
|
||||
}
|
||||
|
||||
static void uwsgi_proxy_close(struct uwsgi_proxy_connection *upcs, int fd) {
|
||||
|
||||
if (upcs[fd].dest_fd >= 0) {
|
||||
close(upcs[fd].dest_fd);
|
||||
upcs[upcs[fd].dest_fd].dest_fd = -1;
|
||||
upcs[upcs[fd].dest_fd].status = 0;
|
||||
upcs[upcs[fd].dest_fd].retry = 0;
|
||||
if (upcs[upcs[fd].dest_fd].node > -1) {
|
||||
if (uwsgi.shared->nodes[upcs[upcs[fd].dest_fd].node].connections > 0)
|
||||
uwsgi.shared->nodes[upcs[upcs[fd].dest_fd].node].connections--;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
upcs[fd].dest_fd = -1;
|
||||
upcs[fd].status = 0;
|
||||
upcs[fd].retry = 0;
|
||||
if (upcs[fd].node > -1) {
|
||||
if (uwsgi.shared->nodes[upcs[fd].node].connections > 0)
|
||||
uwsgi.shared->nodes[upcs[fd].node].connections--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int uwsgi_proxy_find_next_node(int current_node) {
|
||||
int i;
|
||||
|
||||
current_node++;
|
||||
if (current_node >= MAX_CLUSTER_NODES) {
|
||||
current_node = 0;
|
||||
}
|
||||
|
||||
// is it a good node ?
|
||||
if (uwsgi.shared->nodes[current_node].name[0] != 0 && uwsgi.shared->nodes[current_node].status == UWSGI_NODE_OK) {
|
||||
if (uwsgi.shared->nodes[current_node].connections < uwsgi.shared->nodes[current_node].workers)
|
||||
return current_node;
|
||||
}
|
||||
|
||||
// try to find a better one
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
if (uwsgi.shared->nodes[i].name[0] != 0 && uwsgi.shared->nodes[i].status == UWSGI_NODE_OK) {
|
||||
if (uwsgi.shared->nodes[i].connections < uwsgi.shared->nodes[i].workers)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, it is a very loaded system, fallback to round robin
|
||||
if (uwsgi.shared->nodes[current_node].name[0] != 0 && uwsgi.shared->nodes[current_node].status == UWSGI_NODE_OK) {
|
||||
return current_node;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
if (uwsgi.shared->nodes[i].name[0] != 0 && uwsgi.shared->nodes[i].status == UWSGI_NODE_OK) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void proxy_loop() {
|
||||
|
||||
int efd;
|
||||
|
||||
#ifdef __linux__
|
||||
struct epoll_event *eevents;
|
||||
struct epoll_event ev;
|
||||
#elif defined(__sun__)
|
||||
struct pollfd *eevents;
|
||||
struct pollfd ev;
|
||||
#else
|
||||
struct kevent *eevents;
|
||||
struct kevent ev;
|
||||
#endif
|
||||
|
||||
int max_events = 64;
|
||||
int nevents, i;
|
||||
const int nonblocking = 1;
|
||||
const int blocking = 0;
|
||||
|
||||
char buffer[4096];
|
||||
ssize_t rlen;
|
||||
ssize_t wlen;
|
||||
int max_connections = sysconf(_SC_OPEN_MAX);
|
||||
|
||||
int soopt;
|
||||
socklen_t solen = sizeof(int);
|
||||
|
||||
int rc;
|
||||
|
||||
struct uwsgi_proxy_connection *upcs;
|
||||
|
||||
struct sockaddr_in upc_addr;
|
||||
socklen_t upc_len = sizeof(struct sockaddr_in);
|
||||
|
||||
int next_node = -1;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log( "allocating space for %d concurrent proxy connections\n", max_connections);
|
||||
#endif
|
||||
|
||||
// allocate memory for connections
|
||||
upcs = malloc(sizeof(struct uwsgi_proxy_connection) * max_connections);
|
||||
if (!upcs) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
memset(upcs, 0, sizeof(struct uwsgi_proxy_connection) * max_connections);
|
||||
|
||||
if (uproxy.add_me) {
|
||||
uwsgi_cluster_simple_add_node(uwsgi.sockets[0].name, 1, CLUSTER_NODE_STATIC);
|
||||
}
|
||||
|
||||
efd = async_queue_init(uproxy.fd);
|
||||
if (efd < 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
eevents = malloc(sizeof(struct epoll_event) * max_events);
|
||||
memset(&ev, 0, sizeof(struct epoll_event));
|
||||
#elif defined(__sun)
|
||||
eevents = malloc(sizeof(struct pollfd) * max_events);
|
||||
memset(&ev, 0, sizeof(struct pollfd));
|
||||
#else
|
||||
eevents = malloc(sizeof(struct kevent) * max_events);
|
||||
memset(&ev, 0, sizeof(struct kevent));
|
||||
#endif
|
||||
|
||||
if (!eevents) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGINT, (void *) &end_proxy);
|
||||
signal(SIGTERM, (void *) &reload_proxy);
|
||||
signal(SIGHUP, (void *) &reload_proxy);
|
||||
// and welcome to the loop...
|
||||
|
||||
for (;;) {
|
||||
|
||||
nevents = async_wait(efd, eevents, max_events, -1, 0);
|
||||
if (nevents < 0) {
|
||||
uwsgi_error("epoll_wait()");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < nevents; i++) {
|
||||
|
||||
if ( (int)eevents[i].ASYNC_FD == uproxy.fd) {
|
||||
|
||||
if (eevents[i].ASYNC_IS_IN) {
|
||||
// new connection, accept it
|
||||
ev.ASYNC_FD = accept(uproxy.fd, (struct sockaddr *) &upc_addr, &upc_len);
|
||||
if ( (int) ev.ASYNC_FD < 0) {
|
||||
uwsgi_error("accept()");
|
||||
continue;
|
||||
}
|
||||
upcs[ev.ASYNC_FD].node = -1;
|
||||
|
||||
// now connect to the first worker available
|
||||
|
||||
upcs[ev.ASYNC_FD].dest_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (upcs[ev.ASYNC_FD].dest_fd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].node = -1;
|
||||
|
||||
// set nonblocking
|
||||
if (ioctl(upcs[ev.ASYNC_FD].dest_fd, FIONBIO, &nonblocking)) {
|
||||
uwsgi_error("ioctl()");
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
upcs[ev.ASYNC_FD].status = 0;
|
||||
upcs[ev.ASYNC_FD].retry = 0;
|
||||
next_node = uwsgi_proxy_find_next_node(next_node);
|
||||
if (next_node == -1) {
|
||||
uwsgi_log( "unable to find an available worker in the cluster !\n");
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].node = next_node;
|
||||
rc = connect(upcs[ev.ASYNC_FD].dest_fd, (struct sockaddr *) &uwsgi.shared->nodes[next_node].ucn_addr, sizeof(struct sockaddr_in));
|
||||
uwsgi.shared->nodes[next_node].connections++;
|
||||
|
||||
if (!rc) {
|
||||
// connected to worker, put it in the epoll_list
|
||||
|
||||
if (async_add(efd, ev.ASYNC_FD, ASYNC_IN)) {
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].dest_fd = ev.ASYNC_FD;
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].status = 0;
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].retry = 0;
|
||||
|
||||
ev.ASYNC_FD = upcs[ev.ASYNC_FD].dest_fd;
|
||||
|
||||
if (async_add(efd, ev.ASYNC_FD, ASYNC_IN)) {
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
// re-set blocking
|
||||
if (ioctl(upcs[upcs[ev.ASYNC_FD].dest_fd].dest_fd, FIONBIO, &blocking)) {
|
||||
uwsgi_error("ioctl()");
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
else if (errno == EINPROGRESS) {
|
||||
// the socket is waiting, set status to CONNECTING
|
||||
upcs[ev.ASYNC_FD].status = UWSGI_PROXY_WAITING;
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].dest_fd = ev.ASYNC_FD;
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].status = UWSGI_PROXY_CONNECTING;
|
||||
upcs[upcs[ev.ASYNC_FD].dest_fd].retry = 0;
|
||||
|
||||
ev.ASYNC_FD = upcs[ev.ASYNC_FD].dest_fd;
|
||||
if (async_add(efd, ev.ASYNC_FD, ASYNC_OUT)) {
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// connection failed, retry with the next node ?
|
||||
uwsgi_error("connect()");
|
||||
// close only when all node are tried
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "!!! something horrible happened to the uWSGI proxy, reloading it !!!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// this is for clients/workers
|
||||
if (eevents[i].ASYNC_IS_IN) {
|
||||
|
||||
// is this a connected client/worker ?
|
||||
//uwsgi_log("ready %d\n", upcs[eevents[i].data.fd].status);
|
||||
|
||||
if (!upcs[eevents[i].ASYNC_FD].status) {
|
||||
if (upcs[eevents[i].ASYNC_FD].dest_fd >= 0) {
|
||||
|
||||
rlen = read(eevents[i].ASYNC_FD, buffer, 4096);
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("read()");
|
||||
uwsgi_proxy_close(upcs, eevents[i].ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
else if (rlen == 0) {
|
||||
uwsgi_proxy_close(upcs, eevents[i].ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
wlen = write(upcs[eevents[i].ASYNC_FD].dest_fd, buffer, rlen);
|
||||
if (wlen != rlen) {
|
||||
uwsgi_error("write()");
|
||||
uwsgi_proxy_close(upcs, eevents[i].ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_proxy_close(upcs, eevents[i].ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (upcs[eevents[i].ASYNC_FD].status == UWSGI_PROXY_WAITING) {
|
||||
// disconnected node
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "UNKNOWN STATUS %d\n", upcs[eevents[i].ASYNC_FD].status);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (eevents[i].ASYNC_IS_OUT) {
|
||||
if (upcs[eevents[i].ASYNC_FD].status == UWSGI_PROXY_CONNECTING) {
|
||||
|
||||
|
||||
#ifdef UWSGI_PROXY_USE_KQUEUE
|
||||
if (getsockopt(eevents[i].ASYNC_FD, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) {
|
||||
uwsgi_error("getsockopt()");
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
/* is something bad ? */
|
||||
if (soopt) {
|
||||
uwsgi_log( "connect() %s\n", strerror(soopt));
|
||||
// increase errors on node
|
||||
uwsgi_log( "*** marking cluster node %d/%s as failed ***\n", upcs[eevents[i].ASYNC_FD].node, uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].name);
|
||||
if (uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].type == CLUSTER_NODE_DYNAMIC) {
|
||||
uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].name[0] = 0 ;
|
||||
}
|
||||
else {
|
||||
uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].errors++;
|
||||
uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].status = UWSGI_NODE_FAILED;
|
||||
}
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
// increase errors on node
|
||||
#endif
|
||||
ev.ASYNC_FD = upcs[eevents[i].ASYNC_FD].dest_fd;
|
||||
upcs[ev.ASYNC_FD].status = 0;
|
||||
if (async_add(efd, ev.ASYNC_FD, ASYNC_IN)) {
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
|
||||
ev.ASYNC_FD = upcs[ev.ASYNC_FD].dest_fd;
|
||||
upcs[ev.ASYNC_FD].status = 0;
|
||||
|
||||
if (async_mod(efd, ev.ASYNC_FD, ASYNC_IN)) {
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
// re-set blocking
|
||||
if (ioctl(ev.ASYNC_FD, FIONBIO, &blocking)) {
|
||||
uwsgi_error("ioctl()");
|
||||
uwsgi_proxy_close(upcs, ev.ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "strange event for %d\n", (int) eevents[i].ASYNC_FD);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (upcs[eevents[i].ASYNC_FD].status == UWSGI_PROXY_CONNECTING) {
|
||||
if (getsockopt(eevents[i].ASYNC_FD, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) {
|
||||
uwsgi_error("getsockopt()");
|
||||
}
|
||||
/* is something bad ? */
|
||||
if (soopt) {
|
||||
uwsgi_log( "connect() %s\n", strerror(soopt));
|
||||
}
|
||||
|
||||
// increase errors on node
|
||||
uwsgi_log( "*** marking cluster node %d/%s as failed ***\n", upcs[eevents[i].ASYNC_FD].node, uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].name);
|
||||
if (uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].type == CLUSTER_NODE_DYNAMIC) {
|
||||
uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].name[0] = 0;
|
||||
}
|
||||
else {
|
||||
uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].errors++;
|
||||
uwsgi.shared->nodes[upcs[eevents[i].ASYNC_FD].node].status = UWSGI_NODE_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "STRANGE EVENT !!! %d %d %d\n", (int) eevents[i].ASYNC_FD, (int) eevents[i].ASYNC_EV, upcs[eevents[i].ASYNC_FD].status);
|
||||
}
|
||||
uwsgi_proxy_close(upcs, eevents[i].ASYNC_FD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int proxy_init() {
|
||||
int i;
|
||||
char *tcp_port;
|
||||
|
||||
if (!uproxy.workers) uproxy.workers = 1 ;
|
||||
|
||||
if (uproxy.socket_name) {
|
||||
|
||||
tcp_port = strchr(uproxy.socket_name, ':');
|
||||
|
||||
if (tcp_port == NULL) {
|
||||
uproxy.fd = bind_to_unix(uproxy.socket_name, UWSGI_LISTEN_QUEUE, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
}
|
||||
else {
|
||||
uproxy.fd = bind_to_tcp(uproxy.socket_name, UWSGI_LISTEN_QUEUE, tcp_port);
|
||||
tcp_port[0] = ':';
|
||||
}
|
||||
|
||||
if (uproxy.fd < 0) {
|
||||
uwsgi_log( "unable to create the proxy server socket.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for(i=0;i<uproxy.workers;i++) {
|
||||
if (register_gateway("proxy", proxy_loop) == NULL) {
|
||||
uwsgi_log("unable to register the proxy gateway\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proxy_opt(int i, char *optarg) {
|
||||
|
||||
switch(i) {
|
||||
|
||||
case LONG_ARGS_PROXY_NODE:
|
||||
if (uwsgi.cluster_fd >= 0 && !strcmp(optarg, "@self")) {
|
||||
uproxy.add_me = 1;
|
||||
}
|
||||
else {
|
||||
uwsgi_cluster_simple_add_node(optarg, 1, CLUSTER_NODE_STATIC);
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_PROXY:
|
||||
uproxy.socket_name = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PROXY_WORKERS:
|
||||
uproxy.workers = atoi(optarg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_plugin proxy_plugin = {
|
||||
|
||||
.options = proxy_options,
|
||||
.manage_opt = proxy_opt,
|
||||
.init = proxy_init,
|
||||
};
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
NAME='proxy'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['proxy']
|
||||
@@ -257,6 +257,10 @@ SV *build_psgi_env(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (!hv_store(env, "psgix.input.buffered", 20, newSViv(wsgi_req->body_as_file), 0)) goto clear;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
if (!hv_store(env, "psgix.harakiri", 14, newSViv(1), 0)) goto clear;
|
||||
}
|
||||
|
||||
SV *pe = uwsgi_perl_obj_new("uwsgi::error", 12);
|
||||
if (!hv_store(env, "psgi.errors", 11, pe, 0)) goto clear;
|
||||
|
||||
@@ -281,6 +285,10 @@ int uwsgi_perl_init(){
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
|
||||
if (setenv("PLACK_SERVER", "uwsgi", 0)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
|
||||
#ifdef PERL_VERSION_STRING
|
||||
uwsgi_log("initializing Perl %s environment\n", PERL_VERSION_STRING);
|
||||
#else
|
||||
@@ -364,6 +372,7 @@ void uwsgi_perl_enable_threads() {
|
||||
|
||||
int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
SV **harakiri;
|
||||
SV *psgi_func = uperl.psgi_main;
|
||||
// ugly hack
|
||||
register PerlInterpreter *my_perl = uperl.main;
|
||||
@@ -426,6 +435,12 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
clear2:
|
||||
// check for psgix.harakiri
|
||||
harakiri = hv_fetch((HV*)SvRV( (SV*)wsgi_req->async_environ), "psgix.harakiri.commit", 21, 0);
|
||||
if (harakiri) {
|
||||
if (SvTRUE(*harakiri)) wsgi_req->async_plagued = 1;
|
||||
}
|
||||
|
||||
SvREFCNT_dec(wsgi_req->async_environ);
|
||||
SvREFCNT_dec(wsgi_req->async_result);
|
||||
clear:
|
||||
@@ -441,6 +456,12 @@ void uwsgi_perl_after_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_LOGGING])
|
||||
log_request(wsgi_req);
|
||||
|
||||
if (wsgi_req->async_plagued) {
|
||||
uwsgi_log("*** psgix.harakiri.commit requested ***\n");
|
||||
goodbye_cruel_world();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_perl_init_thread(int core_id) {
|
||||
|
||||
@@ -57,6 +57,7 @@ int psgi_response(struct wsgi_request *wsgi_req, PerlInterpreter *my_perl, AV *r
|
||||
struct http_status_codes *http_sc;
|
||||
int i,vi, base;
|
||||
char *chitem;
|
||||
SV **harakiri;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
@@ -84,6 +85,12 @@ int psgi_response(struct wsgi_request *wsgi_req, PerlInterpreter *my_perl, AV *r
|
||||
SvREFCNT_dec(closed);
|
||||
}
|
||||
|
||||
// check for psgix.harakiri
|
||||
harakiri = hv_fetch((HV*)SvRV( (SV*)wsgi_req->async_environ), "psgix.harakiri.commit", 21, 0);
|
||||
if (harakiri) {
|
||||
if (SvTRUE(*harakiri)) wsgi_req->async_plagued = 1;
|
||||
}
|
||||
|
||||
SvREFCNT_dec(wsgi_req->async_environ);
|
||||
SvREFCNT_dec(wsgi_req->async_result);
|
||||
|
||||
|
||||
@@ -4,15 +4,19 @@ extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
void gil_real_get() {
|
||||
//uwsgi_log("LOCK %d\n", uwsgi.mywid);
|
||||
#ifndef PYTHREE
|
||||
PyEval_AcquireLock();
|
||||
PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_gil_key));
|
||||
#else
|
||||
PyEval_RestoreThread((PyThreadState *) pthread_getspecific(up.upt_gil_key));
|
||||
#endif
|
||||
|
||||
//uwsgi_log("LOCKED !!! %d\n", uwsgi.mywid);
|
||||
}
|
||||
|
||||
void gil_real_release() {
|
||||
//uwsgi_log("UNLOCK %d\n", uwsgi.mywid);
|
||||
#ifndef PYTHREE
|
||||
pthread_setspecific(up.upt_gil_key, (void *) PyThreadState_Swap(NULL));
|
||||
PyEval_ReleaseLock();
|
||||
|
||||
@@ -38,7 +38,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
|
||||
struct uwsgi_app *wi;
|
||||
|
||||
|
||||
if (wsgi_req->script_name_len == 0) {
|
||||
wsgi_req->script_name = "";
|
||||
}
|
||||
@@ -50,7 +49,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
}
|
||||
|
||||
|
||||
if (uwsgi.vhost && wsgi_req->host_len > 0) {
|
||||
if (uwsgi.vhost) {
|
||||
mountpoint = uwsgi_concat3n(wsgi_req->host, wsgi_req->host_len, "|", 1, wsgi_req->script_name, wsgi_req->script_name_len);
|
||||
}
|
||||
else {
|
||||
@@ -304,6 +303,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
if (uwsgi.threads > 1 && id) {
|
||||
// if we have multiple threads we need to initialize a PyThreadState for each one
|
||||
for(i=0;i<uwsgi.threads;i++) {
|
||||
//uwsgi_log("%p\n", uwsgi.core[i]->ts[id]);
|
||||
uwsgi.core[i]->ts[id] = PyThreadState_New( ((PyThreadState *)wi->interpreter)->interp);
|
||||
if (!uwsgi.core[i]->ts[id]) {
|
||||
uwsgi_log("unable to allocate new PyThreadState structure for app %s", mountpoint);
|
||||
@@ -439,7 +439,7 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
|
||||
if (quick_callable[strlen(quick_callable) -2 ] == '(' && quick_callable[strlen(quick_callable) -1] ==')') {
|
||||
quick_callable[strlen(quick_callable) -2 ] = 0;
|
||||
tmp_callable = PyDict_GetItemString(wsgi_dict, quick_callable);
|
||||
quick_callable[strlen(quick_callable) -2 ] = '(';
|
||||
quick_callable[strlen(quick_callable)] = '(';
|
||||
if (tmp_callable) {
|
||||
return python_call(tmp_callable, PyTuple_New(0), 0);
|
||||
}
|
||||
@@ -524,7 +524,10 @@ PyObject *uwsgi_file_loader(void *arg1) {
|
||||
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
|
||||
if (!wsgi_file_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wsgi_file_dict = PyModule_GetDict(wsgi_file_module);
|
||||
if (!wsgi_file_dict) {
|
||||
|
||||
@@ -89,14 +89,15 @@ int uwsgi_python_init() {
|
||||
if (up.home != NULL) {
|
||||
#ifdef PYTHREE
|
||||
wchar_t *wpyhome;
|
||||
wpyhome = malloc((sizeof(wchar_t) * strlen(up.home)) + 2);
|
||||
wpyhome = malloc((sizeof(wchar_t) * strlen(up.home)) + sizeof(wchar_t) );
|
||||
if (!wpyhome) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
mbstowcs(wpyhome, up.home, strlen(up.home));
|
||||
Py_SetPythonHome(wpyhome);
|
||||
free(wpyhome);
|
||||
// do not free this memory !!!
|
||||
//free(wpyhome);
|
||||
#else
|
||||
Py_SetPythonHome(up.home);
|
||||
#endif
|
||||
@@ -136,27 +137,32 @@ int uwsgi_python_init() {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_post_fork() {
|
||||
void uwsgi_python_reset_random_seed() {
|
||||
|
||||
PyObject *random_module, *random_dict, *random_seed;
|
||||
|
||||
// reinitialize the random seed (thanks Jonas Borgström)
|
||||
random_module = PyImport_ImportModule("random");
|
||||
if (random_module) {
|
||||
random_dict = PyModule_GetDict(random_module);
|
||||
if (random_dict) {
|
||||
random_seed = PyDict_GetItemString(random_dict, "seed");
|
||||
if (random_seed) {
|
||||
PyObject *random_args = PyTuple_New(1);
|
||||
// pass no args
|
||||
PyTuple_SetItem(random_args, 0, Py_None);
|
||||
PyEval_CallObject(random_seed, random_args);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// reinitialize the random seed (thanks Jonas Borgström)
|
||||
random_module = PyImport_ImportModule("random");
|
||||
if (random_module) {
|
||||
random_dict = PyModule_GetDict(random_module);
|
||||
if (random_dict) {
|
||||
random_seed = PyDict_GetItemString(random_dict, "seed");
|
||||
if (random_seed) {
|
||||
PyObject *random_args = PyTuple_New(1);
|
||||
// pass no args
|
||||
PyTuple_SetItem(random_args, 0, Py_None);
|
||||
PyEval_CallObject(random_seed, random_args);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_python_post_fork() {
|
||||
|
||||
uwsgi_python_reset_random_seed();
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
// call the post_fork_hook
|
||||
@@ -189,12 +195,12 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_log("failed to open python file %s\n", filename);
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(fileno(pyfile), &pystat)) {
|
||||
uwsgi_error("fstat()");
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (S_ISDIR(pystat.st_mode)) {
|
||||
@@ -204,7 +210,9 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
pyfile = fopen(real_filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_error_open(real_filename);
|
||||
exit(1);
|
||||
free(real_filename);
|
||||
fclose(pyfile);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +220,9 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
if (!py_file_node) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("failed to parse file %s\n", real_filename);
|
||||
exit(1);
|
||||
free(real_filename);
|
||||
fclose(pyfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(pyfile);
|
||||
@@ -226,7 +236,7 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
if (!py_file_node) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("failed to parse url %s\n", real_filename);
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,13 +246,13 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
if (!py_compiled_node) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("failed to compile python file %s\n", real_filename);
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
py_file_module = PyImport_ExecCodeModule(name, py_compiled_node);
|
||||
if (!py_file_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_DECREF(py_compiled_node);
|
||||
@@ -365,6 +375,10 @@ void init_uwsgi_vars() {
|
||||
else {
|
||||
// this is a filepath that need to be mapped
|
||||
tmp_module = uwsgi_pyimport_by_filename(up.pymodule_alias[i], value + 1);
|
||||
if (!tmp_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
uwsgi_log("mapped virtual pymodule \"%s\" to real pymodule \"%s\"\n", up.pymodule_alias[i], value + 1);
|
||||
// reset original value
|
||||
@@ -822,6 +836,29 @@ void uwsgi_python_init_apps() {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_master_fixup(int step) {
|
||||
|
||||
static int master_fixed = 0;
|
||||
static int worker_fixed = 0;
|
||||
|
||||
if (!uwsgi.master_process) return;
|
||||
|
||||
if (uwsgi.has_threads) {
|
||||
if (step == 0) {
|
||||
if (!master_fixed) {
|
||||
UWSGI_RELEASE_GIL;
|
||||
master_fixed = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!worker_fixed) {
|
||||
UWSGI_GET_GIL;
|
||||
worker_fixed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_python_enable_threads() {
|
||||
|
||||
PyEval_InitThreads();
|
||||
@@ -841,9 +878,12 @@ void uwsgi_python_enable_threads() {
|
||||
up.gil_get = gil_real_get;
|
||||
up.gil_release = gil_real_release;
|
||||
|
||||
up.swap_ts = threaded_swap_ts;
|
||||
up.reset_ts = threaded_reset_ts;
|
||||
if (uwsgi.threads > 1) {
|
||||
up.swap_ts = threaded_swap_ts;
|
||||
up.reset_ts = threaded_reset_ts;
|
||||
}
|
||||
uwsgi_log("threads support enabled\n");
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_init_thread(int core_id) {
|
||||
@@ -994,9 +1034,15 @@ void uwsgi_python_add_item(char *key, uint16_t keylen, char *val, uint16_t valle
|
||||
|
||||
int uwsgi_python_spooler(char *buf, uint16_t len) {
|
||||
|
||||
static int random_seed_reset = 0;
|
||||
PyObject *spool_dict = PyDict_New();
|
||||
PyObject *spool_func, *pyargs, *ret;
|
||||
|
||||
if (!random_seed_reset) {
|
||||
uwsgi_python_reset_random_seed();
|
||||
random_seed_reset = 1;
|
||||
}
|
||||
|
||||
if (!up.embedded_dict) {
|
||||
// ignore
|
||||
return 0;
|
||||
@@ -1068,6 +1114,7 @@ struct uwsgi_plugin python_plugin = {
|
||||
.init_apps = uwsgi_python_init_apps,
|
||||
|
||||
.fixup = uwsgi_python_fixup,
|
||||
.master_fixup = uwsgi_python_master_fixup,
|
||||
|
||||
.mount_app = uwsgi_python_mount_app,
|
||||
|
||||
|
||||
@@ -12,8 +12,12 @@ PyObject *python_call(PyObject *callable, PyObject *args, int catch) {
|
||||
|
||||
PyObject *pyret;
|
||||
|
||||
//uwsgi_log("ready to call %p %p\n", callable, args);
|
||||
|
||||
pyret = PyEval_CallObject(callable, args);
|
||||
|
||||
//uwsgi_log("called\n");
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
|
||||
uwsgi_log("Memory Error detected !!!\n");
|
||||
|
||||
@@ -115,6 +115,7 @@ char *uwsgi_encode_pydict(PyObject * pydict, uint16_t * size) {
|
||||
|
||||
if (!key || !val) {
|
||||
PyErr_Print();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!PyString_Check(key) || !PyString_Check(val)) {
|
||||
@@ -309,15 +310,15 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
char *node, *func;
|
||||
uint16_t size = 0;
|
||||
PyObject *py_node, *py_func;
|
||||
struct uwsgi_header uh;
|
||||
struct wsgi_request rpc_req;
|
||||
int argc = PyTuple_Size(args);
|
||||
char *argv[0xff];
|
||||
int i, fd;
|
||||
uint16_t pktsize = 0, ulen;
|
||||
char *bufptr;
|
||||
int rlen;
|
||||
int rpc_args = 0;
|
||||
|
||||
struct pollfd upoll;
|
||||
|
||||
// TODO better error reporting
|
||||
if (argc < 2)
|
||||
@@ -341,10 +342,16 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
|
||||
for (i = 0; i < (argc - 2); i++) {
|
||||
argv[i] = PyString_AsString(PyTuple_GetItem(args, i + 2));
|
||||
rpc_args++;
|
||||
}
|
||||
|
||||
if (node == (char *) "") {
|
||||
size = uwsgi_rpc(func, 0, NULL, buffer);
|
||||
if (!strcmp(node, "")) {
|
||||
if (!rpc_args) {
|
||||
size = uwsgi_rpc(func, 0, NULL, buffer);
|
||||
}
|
||||
else {
|
||||
size = uwsgi_rpc(func, rpc_args, argv, buffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -361,9 +368,11 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
pktsize += 2 + strlen(argv[i]);
|
||||
}
|
||||
|
||||
uh.modifier1 = 173;
|
||||
uh.pktsize = pktsize;
|
||||
uh.modifier2 = 0;
|
||||
memset(&rpc_req, 0, sizeof(struct wsgi_request));
|
||||
|
||||
rpc_req.uh.modifier1 = 173;
|
||||
rpc_req.uh.pktsize = pktsize;
|
||||
rpc_req.uh.modifier2 = 0;
|
||||
|
||||
bufptr = buffer;
|
||||
|
||||
@@ -381,7 +390,7 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
bufptr += ulen;
|
||||
}
|
||||
|
||||
if (write(fd, &uh, 4) != 4) {
|
||||
if (write(fd, &rpc_req.uh, 4) != 4) {
|
||||
uwsgi_error("write()");
|
||||
close(fd);
|
||||
goto clear;
|
||||
@@ -395,10 +404,11 @@ PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
|
||||
|
||||
rlen = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (rlen > 0) {
|
||||
upoll.fd = fd;
|
||||
upoll.events = POLLIN;
|
||||
if (uwsgi_parse_response(&upoll, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], &uh, buffer, uwsgi_proto_uwsgi_parser)) {
|
||||
size = uh.pktsize;
|
||||
rpc_req.poll.fd = fd;
|
||||
rpc_req.poll.events = POLLIN;
|
||||
rpc_req.buffer = buffer;
|
||||
if (uwsgi_parse_packet(&rpc_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
|
||||
size = rpc_req.uh.pktsize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,8 +436,7 @@ PyObject *py_uwsgi_register_rpc(PyObject * self, PyObject * args) {
|
||||
|
||||
|
||||
if (uwsgi_register_rpc(name, 0, argc, func)) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
return PyErr_Format(PyExc_ValueError, "unable to register rpc function");
|
||||
}
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
@@ -478,9 +487,11 @@ PyObject *py_uwsgi_signal(PyObject * self, PyObject * args) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("sending %d to master\n", uwsgi_signal);
|
||||
#endif
|
||||
|
||||
rlen = write(uwsgi.shared->worker_signal_pipe[1], &uwsgi_signal, 1);
|
||||
rlen = write(uwsgi.signal_socket, &uwsgi_signal, 1);
|
||||
if (rlen != 1) {
|
||||
uwsgi_error("write()");
|
||||
}
|
||||
@@ -746,6 +757,7 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
||||
off_t pos = 0;
|
||||
size_t filesize = 0;
|
||||
struct stat stat_buf;
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
|
||||
int fd = -1;
|
||||
|
||||
@@ -770,7 +782,7 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
||||
goto clear;
|
||||
|
||||
// check for mixing file_wrapper and sendfile
|
||||
if (fd == uwsgi.wsgi_req->sendfile_fd) {
|
||||
if (fd == wsgi_req->sendfile_fd) {
|
||||
Py_INCREF(what);
|
||||
}
|
||||
}
|
||||
@@ -792,7 +804,7 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
||||
if (!chunk)
|
||||
chunk = 4096;
|
||||
|
||||
uwsgi.wsgi_req->response_size += uwsgi_do_sendfile(uwsgi.wsgi_req->poll.fd, fd, filesize, chunk, &pos, 0);
|
||||
uwsgi.wsgi_req->response_size += uwsgi_do_sendfile(wsgi_req->poll.fd, fd, filesize, chunk, &pos, 0);
|
||||
|
||||
close(fd);
|
||||
Py_INCREF(Py_True);
|
||||
@@ -1234,7 +1246,7 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
|
||||
int managed;
|
||||
struct pollfd *multipoll;
|
||||
char *buffer;
|
||||
struct uwsgi_header uh;
|
||||
|
||||
PyObject *arg_cluster;
|
||||
|
||||
PyObject *cluster_node;
|
||||
@@ -1348,9 +1360,11 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
|
||||
goto megamulticlear;
|
||||
}
|
||||
else {
|
||||
// TODO fix
|
||||
/*
|
||||
for (i = 0; i < clen; i++) {
|
||||
if (multipoll[i].revents & POLLIN) {
|
||||
if (!uwsgi_parse_response(&multipoll[i], PyInt_AsLong(arg_timeout), &uh, &buffer[i], uwsgi_proto_uwsgi_parser)) {
|
||||
if (!uwsgi_parse_packet(&multipoll[i], PyInt_AsLong(arg_timeout), &uh, &buffer[i], uwsgi_proto_uwsgi_parser)) {
|
||||
goto megamulticlear;
|
||||
}
|
||||
else {
|
||||
@@ -1363,6 +1377,7 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2200,6 +2215,9 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
|
||||
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
|
||||
// this field will be overwrite after each call
|
||||
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
|
||||
|
||||
// reset the random seed
|
||||
uwsgi_python_reset_random_seed();
|
||||
// TODO
|
||||
// manage thread in grunt processes
|
||||
Py_INCREF(Py_True);
|
||||
@@ -2272,7 +2290,9 @@ PyObject *py_uwsgi_cluster_node_name(PyObject * self, PyObject * args) {
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
if (ucn->name[0] != 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("node_name: %s %s\n", node, ucn->name);
|
||||
#endif
|
||||
if (!strcmp(ucn->name, node)) {
|
||||
return PyString_FromString(ucn->nodename);
|
||||
}
|
||||
@@ -2495,6 +2515,7 @@ PyObject *py_uwsgi_cache_exists(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
if (remote && strlen(remote) > 0) {
|
||||
// TODO FIX THIS !!!
|
||||
uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (valsize > 0) {
|
||||
Py_INCREF(Py_True);
|
||||
@@ -2657,6 +2678,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
|
||||
char *key;
|
||||
uint64_t valsize;
|
||||
uint16_t valsize16;
|
||||
Py_ssize_t keylen = 0;
|
||||
char *value = NULL;
|
||||
char *remote = NULL;
|
||||
@@ -2672,8 +2694,8 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
if (remote && strlen(remote) > 0) {
|
||||
//uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (valsize > 0) {
|
||||
uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize16, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (valsize16 > 0) {
|
||||
value = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,3 +221,5 @@ void threaded_reset_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
void simple_reset_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
|
||||
int uwsgi_python_profiler_call(PyObject *, PyFrameObject *, int, PyObject *);
|
||||
|
||||
void uwsgi_python_reset_random_seed(void);
|
||||
|
||||
@@ -44,8 +44,9 @@ PyObject *uwsgi_Input_getline(uwsgi_Input *self) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
res = PyString_FromStringAndSize(ptr + self->readline_pos, self->readline_size - self->readline_pos);
|
||||
self->readline_pos = 0;
|
||||
return PyString_FromStringAndSize(ptr + self->readline_pos, self->readline_size - self->readline_pos);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +75,7 @@ PyObject *uwsgi_Input_getline(uwsgi_Input *self) {
|
||||
|
||||
for(i=0;i<(size_t)rlen;i++) {
|
||||
if (self->readline[i] == '\n') {
|
||||
res = PyString_FromStringAndSize(self->readline, i);
|
||||
res = PyString_FromStringAndSize(self->readline, i+1);
|
||||
self->readline_pos+= i+1;
|
||||
if (self->readline_pos >= self->readline_size) self->readline_pos = 0;
|
||||
return res;
|
||||
|
||||
@@ -5,9 +5,8 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
char *argv[0xff];
|
||||
uint8_t argc;
|
||||
int i;
|
||||
char *argv[256];
|
||||
uint8_t argc = 0xff;
|
||||
|
||||
/* Standard RPC request */
|
||||
if (!wsgi_req->uh.pktsize) {
|
||||
@@ -15,17 +14,25 @@ int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_log("parsing array\n");
|
||||
/*
|
||||
for(argc=0;argc<wsgi_req->uh.pktsize;argc++) {
|
||||
uwsgi_log("rpc: %c\n", wsgi_req->buffer[argc]);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("RPC pktsize %d\n", wsgi_req->uh.pktsize);
|
||||
#endif
|
||||
|
||||
if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh.pktsize, argv, &argc)) {
|
||||
uwsgi_log("Invalid RPC request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
uwsgi_log("done\n");
|
||||
|
||||
for(i=0;i<argc;i++) {
|
||||
uwsgi_log("arg %d %s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("RPC args %d\n", argc-1);
|
||||
#endif
|
||||
|
||||
wsgi_req->uh.pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, wsgi_req->buffer);
|
||||
|
||||
if (wsgi_req->uh.modifier2 == 0) {
|
||||
|
||||
+2
-2
@@ -254,7 +254,7 @@ ssize_t uwsgi_proto_fastcgi_sendfile(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
len = read(wsgi_req->sendfile_fd, buf, ntohs(fr.cl));
|
||||
if (len != ntohs(fr.cl)) {
|
||||
if (len != (ssize_t) ntohs(fr.cl)) {
|
||||
uwsgi_error("read()");
|
||||
return -1;
|
||||
}
|
||||
@@ -270,7 +270,7 @@ ssize_t uwsgi_proto_fastcgi_sendfile(struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
len = read(wsgi_req->sendfile_fd, buf, ntohs(fr.cl));
|
||||
if (len != ntohs(fr.cl)) {
|
||||
if (len != (ssize_t) ntohs(fr.cl)) {
|
||||
uwsgi_error("read()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) {
|
||||
|
||||
/* check for max buffer size */
|
||||
if (wsgi_req->uh.pktsize > uwsgi.buffer_size) {
|
||||
uwsgi_log("invalid request block size: %d...skip\n", wsgi_req->uh.pktsize);
|
||||
uwsgi_log("invalid request block size: %d (max %d)...skip\n", wsgi_req->uh.pktsize, uwsgi.buffer_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
+35
-12
@@ -173,6 +173,8 @@ ssize_t send_udp_message(uint8_t modifier1, char *host, char *message, uint16_t
|
||||
}
|
||||
close(fd);
|
||||
|
||||
udp_port[0] = ':';
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
@@ -339,7 +341,7 @@ ssize_t uwsgi_send_message(int fd, uint8_t modifier1, uint8_t modifier2, char *m
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_parse_response(struct pollfd *upoll, int timeout, struct uwsgi_header *uh, char *buffer, int (*socket_proto)(struct wsgi_request *)) {
|
||||
int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
|
||||
int rlen;
|
||||
int status = UWSGI_AGAIN;
|
||||
|
||||
@@ -347,7 +349,7 @@ int uwsgi_parse_response(struct pollfd *upoll, int timeout, struct uwsgi_header
|
||||
timeout = 1;
|
||||
|
||||
while(status == UWSGI_AGAIN) {
|
||||
rlen = poll(upoll, 1, timeout * 1000);
|
||||
rlen = poll(&wsgi_req->poll, 1, timeout * 1000);
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("poll()");
|
||||
exit(1);
|
||||
@@ -357,7 +359,12 @@ int uwsgi_parse_response(struct pollfd *upoll, int timeout, struct uwsgi_header
|
||||
//close(upoll->fd);
|
||||
return 0;
|
||||
}
|
||||
status = socket_proto((struct wsgi_request *) uh);
|
||||
if (wsgi_req->socket) {
|
||||
status = wsgi_req->socket->proto(wsgi_req);
|
||||
}
|
||||
else {
|
||||
status = uwsgi_proto_uwsgi_parser(wsgi_req);
|
||||
}
|
||||
if (status < 0) {
|
||||
uwsgi_log("error parsing request\n");
|
||||
//close(upoll->fd);
|
||||
@@ -393,6 +400,7 @@ int uwsgi_parse_array(char *buffer, uint16_t size, char **argv, uint8_t *argc) {
|
||||
if (ptrbuf + strsize <= bufferend) {
|
||||
// item
|
||||
argv[*argc] = uwsgi_cheap_string(ptrbuf, strsize);
|
||||
uwsgi_log("arg %s\n", argv[*argc]);
|
||||
ptrbuf += strsize;
|
||||
*argc = *argc + 1;
|
||||
}
|
||||
@@ -754,7 +762,7 @@ int uwsgi_ping_node(int node, struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
uwsgi_poll.events = POLLIN;
|
||||
if (!uwsgi_parse_response(&uwsgi_poll, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) wsgi_req, wsgi_req->buffer, uwsgi_proto_uwsgi_parser)) {
|
||||
if (!uwsgi_parse_packet(wsgi_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -819,7 +827,9 @@ int uwsgi_get_dgram(int fd, struct wsgi_request *wsgi_req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_log("recevied request from %s\n", inet_ntoa(sin.sin_addr));
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("received request from %s\n", inet_ntoa(sin.sin_addr));
|
||||
#endif
|
||||
|
||||
if (rlen < 4) {
|
||||
uwsgi_log("invalid uwsgi packet\n");
|
||||
@@ -843,7 +853,9 @@ int uwsgi_get_dgram(int fd, struct wsgi_request *wsgi_req) {
|
||||
|
||||
wsgi_req->buffer = buffer+4;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("request received %d %d\n", wsgi_req->uh.modifier1, wsgi_req->uh.modifier2);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -909,20 +921,27 @@ int uwsgi_hooked_parse_dict_dgram(int fd, char *buffer, size_t len, uint8_t modi
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_log("recevied request from %s\n", inet_ntoa(sin.sin_addr));
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("RLEN: %d\n", rlen);
|
||||
#endif
|
||||
|
||||
// check for valid dict 4(header) 2(non-zero key)+1 2(value)
|
||||
if (rlen < (4+2+1+2)) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("invalid uwsgi dictionary\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_log("received message from %s\n", inet_ntoa(sin.sin_addr));
|
||||
|
||||
uh = (struct uwsgi_header *) buffer;
|
||||
|
||||
if (uh->modifier1 != modifier1 || uh->modifier2 != modifier2) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("invalid uwsgi dictionary received, modifier1: %d modifier2: %d\n", uh->modifier1, uh->modifier2);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -942,7 +961,9 @@ int uwsgi_hooked_parse_dict_dgram(int fd, char *buffer, size_t len, uint8_t modi
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%p %p %d\n", ptrbuf, bufferend, bufferend-ptrbuf);
|
||||
#endif
|
||||
|
||||
uwsgi_hooked_parse(ptrbuf, bufferend-ptrbuf, hook, data);
|
||||
|
||||
@@ -1096,8 +1117,7 @@ uint16_t fcgi_get_record(int fd, char *buf) {
|
||||
|
||||
char *uwsgi_simple_message_string(char *socket_name, uint8_t modifier1, uint8_t modifier2, char *what, uint16_t what_len, char *buffer, uint16_t *response_len, int timeout) {
|
||||
|
||||
struct uwsgi_header uh;
|
||||
struct pollfd upoll;
|
||||
struct wsgi_request msg_req;
|
||||
|
||||
int fd = uwsgi_connect(socket_name, timeout, 0);
|
||||
|
||||
@@ -1112,19 +1132,22 @@ char *uwsgi_simple_message_string(char *socket_name, uint8_t modifier1, uint8_t
|
||||
return NULL;
|
||||
}
|
||||
|
||||
upoll.fd = fd;
|
||||
upoll.events = POLLIN;
|
||||
memset(&msg_req, 0, sizeof(struct wsgi_request));
|
||||
msg_req.poll.fd = fd;
|
||||
msg_req.poll.events = POLLIN;
|
||||
msg_req.buffer = buffer;
|
||||
|
||||
if (buffer) {
|
||||
if (!uwsgi_parse_response(&upoll, timeout, &uh, buffer, uwsgi_proto_uwsgi_parser)) {
|
||||
if (!uwsgi_parse_packet(&msg_req, timeout)) {
|
||||
close(fd);
|
||||
if (response_len) *response_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (response_len) *response_len = msg_req.uh.pktsize;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
if (response_len) *response_len = uh.pktsize;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@ int uwsgi_register_rpc(char *name, uint8_t modifier1, uint8_t args, void *func)
|
||||
struct uwsgi_rpc *urpc;
|
||||
int ret = -1;
|
||||
|
||||
if (uwsgi.mywid != 0) {
|
||||
uwsgi_log("you can register RPC functions only in the master\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_lock(uwsgi.rpc_table_lock);
|
||||
|
||||
if (uwsgi.shared->rpc_count < MAX_RPC) {
|
||||
|
||||
@@ -76,7 +76,9 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
|
||||
}
|
||||
|
||||
if (sf_ret) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("sf_len = %d\n", sf_len);
|
||||
#endif
|
||||
uwsgi_error("sendfile()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,10 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
len = strlen(socket_name+1) + 1;
|
||||
|
||||
}
|
||||
else if (abstract_socket) {
|
||||
memcpy(uws_addr->sun_path + 1, socket_name, UMIN(strlen(socket_name), 101));
|
||||
len = strlen(socket_name)+1;
|
||||
}
|
||||
else {
|
||||
memcpy(uws_addr->sun_path + abstract_socket, socket_name, UMIN(strlen(socket_name), 102));
|
||||
len = strlen(socket_name);
|
||||
@@ -380,7 +384,10 @@ char *generate_socket_name(char *socket_name) {
|
||||
uwsgi_log("your system does not support ifaddrs subsystem\n");
|
||||
#else
|
||||
char *new_socket;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("generate_socket_name(%s)\n", socket_name);
|
||||
#endif
|
||||
// get all the AF_INET addresses available
|
||||
struct ifaddrs *ifap = NULL, *ifa, *ifaf;
|
||||
if (getifaddrs(&ifap)) {
|
||||
@@ -391,7 +398,9 @@ char *generate_socket_name(char *socket_name) {
|
||||
// here socket_name will be truncated
|
||||
asterisk[0] = 0;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("asterisk found\n");
|
||||
#endif
|
||||
|
||||
char new_addr[16];
|
||||
struct sockaddr_in *sin;
|
||||
@@ -491,6 +500,17 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (uwsgi.reuse_port) {
|
||||
#ifdef SO_REUSEPORT
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEPORT, (const void *) &uwsgi.reuse_port, sizeof(int)) < 0) {
|
||||
uwsgi_error("setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
#else
|
||||
uwsgi_log("!!! your system does not support SO_REUSEPORT !!!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!uwsgi.no_defer_accept) {
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -624,6 +644,17 @@ int timed_connect(struct pollfd *fdpoll, const struct sockaddr *addr, int addr_s
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_count_sockets(struct uwsgi_socket *uwsgi_sock) {
|
||||
|
||||
int count = 0;
|
||||
while(uwsgi_sock) {
|
||||
count++;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int uwsgi_get_socket_num(struct uwsgi_socket *uwsgi_sock) {
|
||||
|
||||
int count = 0;
|
||||
@@ -685,6 +716,8 @@ struct uwsgi_socket *uwsgi_new_shared_socket(char *name) {
|
||||
struct uwsgi_socket *uwsgi_new_socket(char *name) {
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets, *old_uwsgi_sock;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t socket_type_len;
|
||||
|
||||
if (!uwsgi_sock) {
|
||||
uwsgi.sockets = uwsgi_malloc(sizeof(struct uwsgi_socket));
|
||||
@@ -702,6 +735,29 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) {
|
||||
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
|
||||
uwsgi_sock->name = name;
|
||||
|
||||
char *tcp_port = strchr(name, ':');
|
||||
if (tcp_port) {
|
||||
// INET socket, check for 0 port
|
||||
if (tcp_port[1] == 0 || tcp_port[1] == '0') {
|
||||
uwsgi_sock->fd = bind_to_tcp(name, uwsgi.listen_queue, tcp_port);
|
||||
uwsgi_sock->family = AF_INET;
|
||||
uwsgi_sock->bound = 1;
|
||||
|
||||
uwsgi_sock->auto_port = 1;
|
||||
|
||||
socket_type_len = sizeof(struct sockaddr_in);
|
||||
|
||||
if (getsockname(uwsgi_sock->fd, (struct sockaddr *)&sin, &socket_type_len)) {
|
||||
uwsgi_error("getsockname()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
|
||||
uwsgi_sock->name = uwsgi_concat3n(name, tcp_port-name, ":", 1, auto_port, strlen(auto_port));
|
||||
}
|
||||
}
|
||||
|
||||
return uwsgi_sock;
|
||||
}
|
||||
@@ -722,6 +778,15 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
|
||||
}
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
if (usa.sa_un.sun_path[0] == 0) abstract = 1;
|
||||
// is it a zerg ?
|
||||
if (uwsgi_sock->name == NULL) {
|
||||
uwsgi_sock->fd = fd;
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_sock->name = uwsgi_concat2(usa.sa_un.sun_path+abstract, "");
|
||||
uwsgi_log("uwsgi zerg socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path+abstract, uwsgi_sock->fd);
|
||||
return;
|
||||
}
|
||||
if (!strcmp(usa.sa_un.sun_path+abstract, uwsgi_sock->name+abstract)) {
|
||||
uwsgi_sock->fd = fd;
|
||||
uwsgi_sock->family = AF_UNIX;
|
||||
@@ -747,6 +812,17 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
|
||||
else {
|
||||
computed_addr = uwsgi_concat3(ipv4a, ":", computed_port);
|
||||
}
|
||||
|
||||
// is it a zerg ?
|
||||
if (uwsgi_sock->name == NULL) {
|
||||
uwsgi_sock->fd = fd;
|
||||
uwsgi_sock->family = AF_INET;
|
||||
uwsgi_sock->bound = 1;
|
||||
uwsgi_sock->name = uwsgi_concat2(computed_addr, "");
|
||||
uwsgi_log("uwsgi zerg socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
|
||||
free(computed_addr);
|
||||
return;
|
||||
}
|
||||
char *asterisk = strchr(uwsgi_sock->name, '*');
|
||||
int match = 1;
|
||||
if (asterisk) {
|
||||
|
||||
@@ -27,6 +27,12 @@ pid_t spooler_start() {
|
||||
|
||||
void destroy_spool(char *file) {
|
||||
|
||||
if (chdir(uwsgi.spool_dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
uwsgi_log("something horrible happened to the spooler. Better to kill it.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (unlink(file)) {
|
||||
uwsgi_error("unlink()");
|
||||
uwsgi_log("something horrible happened to the spooler. Better to kill it.\n");
|
||||
@@ -119,10 +125,6 @@ void spooler() {
|
||||
|
||||
char spool_buf[0xffff];
|
||||
|
||||
if (chdir(uwsgi.spool_dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// asked by Marco Beri
|
||||
#ifdef __HAIKU__
|
||||
@@ -150,7 +152,11 @@ void spooler() {
|
||||
|
||||
for (;;) {
|
||||
|
||||
sleep(uwsgi.shared->spooler_frequency);
|
||||
|
||||
if (chdir(uwsgi.spool_dir)) {
|
||||
uwsgi_error("chdir()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sdir = opendir(uwsgi.spool_dir);
|
||||
if (sdir) {
|
||||
@@ -227,6 +233,8 @@ void spooler() {
|
||||
uwsgi_error("opendir()");
|
||||
}
|
||||
|
||||
sleep(uwsgi.shared->spooler_frequency);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,19 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
static int uwsgi_sqlite3_config_callback(void *foo, int field_count, char **fields, char **col) {
|
||||
|
||||
static int uwsgi_sqlite3_config_callback(void *magic_table, int field_count, char **fields, char **col) {
|
||||
// make a copy of the string
|
||||
if (field_count >= 2) {
|
||||
add_exported_option( uwsgi_strncopy(fields[0], strlen(fields[0])), uwsgi_strncopy(fields[1], strlen(fields[1])), 0);
|
||||
int value_len = strlen(fields[1]) + 1;
|
||||
char *value = magic_sub(fields[1], value_len, &value_len, (char **) magic_table);
|
||||
add_exported_option( uwsgi_strncopy(fields[0], strlen(fields[0])), value, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_sqlite3_config(char *file) {
|
||||
void uwsgi_sqlite3_config(char *file, char *magic_table[]) {
|
||||
|
||||
sqlite3 *db;
|
||||
char *err = NULL;
|
||||
@@ -43,7 +44,7 @@ void uwsgi_sqlite3_config(char *file) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sqlite3_exec(db, query, uwsgi_sqlite3_config_callback, 0, &err)) {
|
||||
if (sqlite3_exec(db, query, uwsgi_sqlite3_config_callback, (void *) magic_table, &err)) {
|
||||
uwsgi_log("sqlite3 error: %s\n", err);
|
||||
sqlite3_close(db);
|
||||
exit(1);
|
||||
|
||||
+4
-3
@@ -5,8 +5,9 @@ def application(env, start_response):
|
||||
start_response('200 Ok', [('Content-type', 'text/plain')])
|
||||
#for x in env['wsgi.input']:
|
||||
# yield x
|
||||
body = env['wsgi.input'].readline()
|
||||
print body
|
||||
body = env['wsgi.input'].read(int(env['CONTENT_LENGTH']))
|
||||
body += env['wsgi.input'].readline()
|
||||
#print body
|
||||
body += env['wsgi.input'].read(100)
|
||||
body += env['wsgi.input'].read(100)
|
||||
body += env['wsgi.input'].read()
|
||||
@@ -17,7 +18,7 @@ def application(env, start_response):
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<textarea name="pluto">
|
||||
</textarea>
|
||||
<input type="test" name="pippo" />
|
||||
<input type="file" name="pippo" />
|
||||
<input type="submit" value="invia" />
|
||||
</form>
|
||||
"""
|
||||
|
||||
@@ -716,7 +716,7 @@ int wsgi_req_recv(struct wsgi_request *wsgi_req) {
|
||||
gettimeofday(&wsgi_req->start_of_request, NULL);
|
||||
|
||||
if (!wsgi_req->socket->edge_trigger) {
|
||||
if (!uwsgi_parse_response(&wsgi_req->poll, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) wsgi_req, wsgi_req->buffer, wsgi_req->socket->proto)) {
|
||||
if (!uwsgi_parse_packet(wsgi_req, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -747,14 +747,14 @@ int wsgi_req_simple_accept(struct wsgi_request *wsgi_req, int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wsgi_req_accept(struct wsgi_request *wsgi_req) {
|
||||
int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
|
||||
|
||||
int ret;
|
||||
int interesting_fd;
|
||||
char uwsgi_signal;
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
|
||||
ret = event_queue_wait(uwsgi.main_queue, uwsgi.edge_triggered - 1, &interesting_fd);
|
||||
ret = event_queue_wait(queue, uwsgi.edge_triggered - 1, &interesting_fd);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -775,7 +775,9 @@ int wsgi_req_accept(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
}
|
||||
@@ -1233,8 +1235,10 @@ int uwsgi_get_app_id(char *script_name, int script_name_len, int modifier1) {
|
||||
struct stat st;
|
||||
|
||||
for (i = 0; i < uwsgi.apps_cnt; i++) {
|
||||
//uwsgi_log("searching for %.*s in %.*s %p\n", script_name_len, script_name, uwsgi.apps[i].mountpoint_len, uwsgi.apps[i].mountpoint, uwsgi.apps[i].callable);
|
||||
if (!uwsgi.apps[i].mountpoint_len) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("searching for %.*s in %.*s %p\n", script_name_len, script_name, uwsgi.apps[i].mountpoint_len, uwsgi.apps[i].mountpoint, uwsgi.apps[i].callable);
|
||||
#endif
|
||||
if (!uwsgi.apps[i].callable) {
|
||||
continue;
|
||||
}
|
||||
if (!uwsgi_strncmp(uwsgi.apps[i].mountpoint, uwsgi.apps[i].mountpoint_len, script_name, script_name_len)) {
|
||||
@@ -1243,7 +1247,13 @@ int uwsgi_get_app_id(char *script_name, int script_name_len, int modifier1) {
|
||||
if (st.st_mtime != uwsgi.apps[i].touch_reload_mtime) {
|
||||
// serve the new request and reload
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
|
||||
return -1;
|
||||
if (uwsgi.threads > 1) {
|
||||
uwsgi.workers[uwsgi.mywid].destroy = 1;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("mtime %d %d\n", st.st_mtime, uwsgi.apps[i].touch_reload_mtime);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1289,7 +1299,7 @@ int uwsgi_read_whole_body_in_mem(struct wsgi_request *wsgi_req, char *buf) {
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
uwsgi_log("buffering POST data timedout !!!\n");
|
||||
uwsgi_log("buffering POST data timed-out !!!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1566,6 +1576,11 @@ char *uwsgi_resolve_ip(char *domain) {
|
||||
return inet_ntoa(*(struct in_addr *) he->h_addr_list[0]);
|
||||
}
|
||||
|
||||
int uwsgi_file_exists(char *filename) {
|
||||
// TODO check for http url or stdin
|
||||
return !access(filename, R_OK);
|
||||
}
|
||||
|
||||
char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[]) {
|
||||
|
||||
int fd;
|
||||
@@ -1867,11 +1882,7 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
|
||||
char *argv[64];
|
||||
char *a;
|
||||
int cnt = 1;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, ud->pipe)) {
|
||||
uwsgi_error("socketpair()");
|
||||
return;
|
||||
}
|
||||
int devnull = -1;
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
@@ -1880,7 +1891,6 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
close(ud->pipe[1]);
|
||||
ud->pid = pid;
|
||||
ud->status = 1;
|
||||
if (ud->respawns == 0) {
|
||||
@@ -1892,23 +1902,27 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
// close uwsgi sockets
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
close(uwsgi_sock->fd);
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
close(ud->pipe[0]);
|
||||
uwsgi_close_all_sockets();
|
||||
|
||||
// stdin will become the pipe
|
||||
if (ud->pipe[1] != 0) {
|
||||
if (dup2(ud->pipe[1], 0)) {
|
||||
// /dev/null will became stdin
|
||||
devnull = open("/dev/null", O_RDONLY);
|
||||
if (devnull < 0) {
|
||||
uwsgi_error("/dev/null open()");
|
||||
exit(1);
|
||||
}
|
||||
if (devnull != 0) {
|
||||
if (dup2(devnull, 0)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (setsid() < 0) {
|
||||
uwsgi_error("setsid()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
|
||||
uwsgi_error("prctl()");
|
||||
@@ -2269,3 +2283,140 @@ void uwsgi_sig_pause() {
|
||||
sigemptyset(&mask);
|
||||
sigsuspend(&mask);
|
||||
}
|
||||
|
||||
int uwsgi_run_command_and_wait(char *command, ...) {
|
||||
|
||||
va_list ap;
|
||||
|
||||
int waitpid_status = 0;
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
if (waitpid(pid, &waitpid_status, 0) < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WEXITSTATUS(waitpid_status);
|
||||
}
|
||||
|
||||
va_start(ap, command);
|
||||
execlp(command, command, ap, (char *) NULL);
|
||||
va_end(ap);
|
||||
|
||||
uwsgi_error("execlp()");
|
||||
//never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int uwsgi_run_command(char *command) {
|
||||
|
||||
char *argv[4];
|
||||
|
||||
int waitpid_status = 0;
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
if (waitpid(pid, &waitpid_status, WNOHANG) < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WEXITSTATUS(waitpid_status);
|
||||
}
|
||||
|
||||
uwsgi_close_all_sockets();
|
||||
|
||||
if (setsid() < 0) {
|
||||
uwsgi_error("setsid()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
argv[0] = "/bin/sh";
|
||||
argv[1] = "-c";
|
||||
argv[2] = command;
|
||||
argv[3] = NULL;
|
||||
|
||||
execvp("/bin/sh", argv);
|
||||
|
||||
uwsgi_error("execvp()");
|
||||
//never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int *uwsgi_attach_fd(int fd, int count, char *code, size_t code_len) {
|
||||
|
||||
struct msghdr msg;
|
||||
ssize_t len;
|
||||
char *id = NULL;
|
||||
|
||||
struct iovec iov;
|
||||
struct cmsghdr *cmsg;
|
||||
int *ret;
|
||||
int i;
|
||||
|
||||
void *msg_control = uwsgi_malloc(CMSG_SPACE(sizeof(int) * count));
|
||||
|
||||
memset( msg_control, 0, CMSG_SPACE(sizeof(int) * count));
|
||||
|
||||
if (code && code_len > 0) {
|
||||
id = uwsgi_malloc(code_len);
|
||||
memset(id, 0, code_len);
|
||||
}
|
||||
|
||||
iov.iov_base = id;
|
||||
iov.iov_len = code_len;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = msg_control;
|
||||
msg.msg_controllen = CMSG_SPACE(sizeof(int) * count);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
len = recvmsg(fd, &msg, 0);
|
||||
if (len <= 0) {
|
||||
uwsgi_error("recvmsg()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (code && code_len > 0) {
|
||||
if (strcmp(id, code)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (!cmsg) return NULL;
|
||||
|
||||
if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = uwsgi_malloc(sizeof(int) * (count + 1));
|
||||
for(i=0;i<count+1;i++) {
|
||||
ret[i] = -1;
|
||||
}
|
||||
|
||||
if ((size_t) (cmsg->cmsg_len - ((char *)CMSG_DATA(cmsg)- (char *)cmsg)) > (size_t) (sizeof(int) * (count + 1))) {
|
||||
uwsgi_log("not enough space for sockets data, consider increasing it\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(ret, CMSG_DATA(cmsg), cmsg->cmsg_len - ((char *)CMSG_DATA(cmsg)- (char *)cmsg));
|
||||
|
||||
free(msg_control);
|
||||
if (code && code_len > 0) {
|
||||
free(id);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ static struct option long_base_options[] = {
|
||||
{"emperor-amqp-username", required_argument, 0, LONG_ARGS_EMPEROR_AMQP_USERNAME},
|
||||
{"emperor-amqp-password", required_argument, 0, LONG_ARGS_EMPEROR_AMQP_PASSWORD},
|
||||
{"vassals-inherit", required_argument, 0, LONG_ARGS_VASSALS_INHERIT},
|
||||
{"vassals-start-hook", required_argument, 0, LONG_ARGS_VASSALS_START_HOOK},
|
||||
{"vassals-stop-hook", required_argument, 0, LONG_ARGS_VASSALS_STOP_HOOK},
|
||||
{"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},
|
||||
@@ -127,6 +129,7 @@ static struct option long_base_options[] = {
|
||||
{"reload-on-as", required_argument, 0, LONG_ARGS_RELOAD_ON_AS},
|
||||
{"reload-on-rss", required_argument, 0, LONG_ARGS_RELOAD_ON_RSS},
|
||||
{"touch-reload", required_argument, 0, LONG_ARGS_TOUCH_RELOAD},
|
||||
{"propagate-touch", no_argument, &uwsgi.propagate_touch, 1},
|
||||
{"limit-post", required_argument, 0, LONG_ARGS_LIMIT_POST},
|
||||
{"no-orphans", no_argument, &uwsgi.no_orphans, 1},
|
||||
{"prio", required_argument, 0, LONG_ARGS_PRIO},
|
||||
@@ -158,6 +161,7 @@ static struct option long_base_options[] = {
|
||||
{"async", required_argument, 0, LONG_ARGS_ASYNC},
|
||||
#endif
|
||||
{"logto", required_argument, 0, LONG_ARGS_LOGTO},
|
||||
{"logto2", required_argument, 0, LONG_ARGS_LOGTO2},
|
||||
{"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},
|
||||
@@ -206,6 +210,10 @@ static struct option long_base_options[] = {
|
||||
{"namespace-net", required_argument, 0, LONG_ARGS_LINUX_NS_NET},
|
||||
{"ns-net", required_argument, 0, LONG_ARGS_LINUX_NS_NET},
|
||||
#endif
|
||||
{"reuse-port", no_argument, &uwsgi.reuse_port, 1},
|
||||
{"zerg", required_argument, 0, LONG_ARGS_ZERG},
|
||||
{"zerg-server", required_argument, 0, LONG_ARGS_ZERG_SERVER},
|
||||
{"cron", required_argument, 0, LONG_ARGS_CRON},
|
||||
{"loop", required_argument, 0, LONG_ARGS_LOOP},
|
||||
{"worker-exec", required_argument, 0, LONG_ARGS_WORKER_EXEC},
|
||||
{"attach-daemon", required_argument, 0, LONG_ARGS_ATTACH_DAEMON},
|
||||
@@ -222,14 +230,29 @@ static struct option long_base_options[] = {
|
||||
|
||||
void uwsgi_configure(void) {
|
||||
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
struct option *lopt;
|
||||
struct option *aopt;
|
||||
char *val;
|
||||
int i;
|
||||
int is_retry;
|
||||
int found;
|
||||
|
||||
// option must be processed in reverse (to have a consistent template system)
|
||||
// but first load plugins...
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (uwsgi.exported_opts[i]->configured)
|
||||
continue;
|
||||
|
||||
if (!strcmp("plugin", uwsgi.exported_opts[i]->key) || !strcmp("plugins", uwsgi.exported_opts[i]->key)) {
|
||||
manage_opt(LONG_ARGS_PLUGINS, uwsgi.exported_opts[i]->value);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = uwsgi.exported_opts_cnt-1; i >= 0; i--) {
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("i = %d %p\n", i, uwsgi.exported_opts[i]);
|
||||
#endif
|
||||
|
||||
if (uwsgi.exported_opts[i]->configured)
|
||||
continue;
|
||||
@@ -297,6 +320,8 @@ void uwsgi_configure(void) {
|
||||
|
||||
void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
|
||||
char *tmp = NULL;
|
||||
|
||||
magic_table['o'] = filename;
|
||||
if (filename[0] == '/') {
|
||||
magic_table['p'] = filename;
|
||||
@@ -306,6 +331,16 @@ void config_magic_table_fill(char *filename, char **magic_table) {
|
||||
}
|
||||
magic_table['s'] = uwsgi_get_last_char(magic_table['p'], '/') + 1;
|
||||
magic_table['d'] = uwsgi_concat2n(magic_table['p'], magic_table['s'] - magic_table['p'], "", 0);
|
||||
if (magic_table['d'][strlen(magic_table['d'])-1] == '/') {
|
||||
tmp = magic_table['d'] + (strlen(magic_table['d']) -1) ;
|
||||
uwsgi_log("tmp = %c\n", *tmp);
|
||||
*tmp = 0;
|
||||
}
|
||||
if (uwsgi_get_last_char(magic_table['d'], '/'))
|
||||
magic_table['c'] = uwsgi_get_last_char(magic_table['d'], '/') + 1;
|
||||
|
||||
if (tmp) *tmp = '/';
|
||||
|
||||
if (uwsgi_get_last_char(filename, '.'))
|
||||
magic_table['e'] = uwsgi_get_last_char(filename, '.') + 1;
|
||||
if (uwsgi_get_last_char(magic_table['s'], '.'))
|
||||
@@ -439,7 +474,7 @@ void kill_them_all(int signum) {
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
kill(-uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gateways_cnt; i++) {
|
||||
@@ -474,7 +509,7 @@ void grace_them_all(int signum) {
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
kill(-uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gateways_cnt; i++) {
|
||||
@@ -535,7 +570,7 @@ void reap_them_all(int signum) {
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
kill(-uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gateways_cnt; i++) {
|
||||
@@ -725,7 +760,6 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
char *magic_table[0xff];
|
||||
char *optname;
|
||||
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
@@ -848,19 +882,18 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
//initialize embedded plugins
|
||||
UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
// now a bit of magic, if the argv[0] contains a _ try to automatically load a plugin
|
||||
// now a bit of magic, if the argv[0] basename contains a 'uwsgi_' string,
|
||||
// try to automatically load a plugin
|
||||
//uwsgi_log("executable name: %s\n", argv[0]);
|
||||
char *p = strtok(argv[0], "_");
|
||||
plugins_requested = NULL;
|
||||
while (p != NULL) {
|
||||
p = strtok(NULL, "_");
|
||||
if (p)
|
||||
plugins_requested = p;
|
||||
}
|
||||
|
||||
if (plugins_requested) {
|
||||
uwsgi_log("plugin = %s\n", plugins_requested);
|
||||
uwsgi_load_plugin(0, plugins_requested, NULL, 0);
|
||||
char *p = strrchr(argv[0], '/');
|
||||
if (p == NULL) p = argv[0];
|
||||
p = strstr(p, "uwsgi_");
|
||||
if (p != NULL) {
|
||||
plugins_requested = strchr(p, '_');
|
||||
if (plugins_requested != NULL && *(++plugins_requested) != '\0') {
|
||||
uwsgi_log("plugin = %s\n", plugins_requested);
|
||||
uwsgi_load_plugin(0, plugins_requested, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
plugins_requested = getenv("UWSGI_PLUGINS");
|
||||
@@ -996,7 +1029,8 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
#endif
|
||||
#ifdef UWSGI_SQLITE3
|
||||
if (uwsgi.sqlite3 != NULL) {
|
||||
uwsgi_sqlite3_config(uwsgi.sqlite3);
|
||||
config_magic_table_fill(uwsgi.sqlite3, magic_table);
|
||||
uwsgi_sqlite3_config(uwsgi.sqlite3, magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_LDAP
|
||||
@@ -1036,13 +1070,13 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
#endif
|
||||
#ifdef UWSGI_SQLITE3
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".db")) {
|
||||
uwsgi_sqlite3_config(uct->filename);
|
||||
uwsgi_sqlite3_config(uct->filename, magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 7, ".sqlite")) {
|
||||
uwsgi_sqlite3_config(uct->filename);
|
||||
uwsgi_sqlite3_config(uct->filename, magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 8, ".sqlite3")) {
|
||||
uwsgi_sqlite3_config(uct->filename);
|
||||
uwsgi_sqlite3_config(uct->filename, magic_table);
|
||||
}
|
||||
#endif
|
||||
uct = uct->next;
|
||||
@@ -1319,6 +1353,10 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
|
||||
if (uwsgi.logto2) {
|
||||
logto(uwsgi.logto2);
|
||||
}
|
||||
|
||||
if (uwsgi.chdir) {
|
||||
if (chdir(uwsgi.chdir)) {
|
||||
uwsgi_error("chdir()");
|
||||
@@ -1585,11 +1623,26 @@ int uwsgi_start(void *v_argv) {
|
||||
if (!uwsgi.no_server) {
|
||||
|
||||
//check for inherited sockets
|
||||
if (uwsgi.is_a_reload) {
|
||||
if (uwsgi.is_a_reload || uwsgi.zerg) {
|
||||
|
||||
if (uwsgi.zerg) {
|
||||
int zerg_fd;
|
||||
i = 0;
|
||||
for(;;) {
|
||||
zerg_fd = uwsgi.zerg[i];
|
||||
if (zerg_fd == -1) {
|
||||
break;
|
||||
}
|
||||
uwsgi_sock = uwsgi_new_socket(NULL);
|
||||
uwsgi_add_socket_from_fd(uwsgi_sock, zerg_fd);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
//a bit overengineering
|
||||
if (uwsgi_sock->name[0] != 0) {
|
||||
if (uwsgi_sock->name[0] != 0 && !uwsgi_sock->bound) {
|
||||
for (j = 3; j < sysconf(_SC_OPEN_MAX); j++) {
|
||||
uwsgi_add_socket_from_fd(uwsgi_sock, j);
|
||||
}
|
||||
@@ -1687,6 +1740,15 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check for auto_port socket
|
||||
uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (uwsgi_sock->auto_port) {
|
||||
uwsgi_log("uwsgi socket %d bound to TCP address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
|
||||
}
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
}
|
||||
|
||||
|
||||
// put listening socket in non-blocking state and set the protocol
|
||||
@@ -1834,6 +1896,15 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi_log("your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue);
|
||||
#endif
|
||||
|
||||
if (uwsgi.crons) {
|
||||
struct uwsgi_cron *ucron = uwsgi.crons;
|
||||
while(ucron) {
|
||||
uwsgi_log("command \"%s\" registered as uWSGI-cron task\n", ucron->command);
|
||||
ucron = ucron->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
memset(uwsgi.apps, 0, sizeof(uwsgi.apps));
|
||||
|
||||
@@ -1899,6 +1970,14 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
uwsgi_rawlog(" ***\n");
|
||||
|
||||
// even the master has cores..
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
//init apps hook (if not lazy)
|
||||
if (!uwsgi.lazy) {
|
||||
uwsgi_init_all_apps();
|
||||
@@ -1949,6 +2028,15 @@ int uwsgi_start(void *v_argv) {
|
||||
routing_setup();
|
||||
#endif
|
||||
|
||||
// master fixup
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->master_fixup) {
|
||||
uwsgi.p[i]->master_fixup(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!uwsgi.master_process) {
|
||||
if (uwsgi.numproc == 1) {
|
||||
uwsgi_log("spawned uWSGI worker 1 (and the only) (pid: %d, cores: %d)\n", masterpid, uwsgi.cores);
|
||||
@@ -2099,12 +2187,6 @@ int uwsgi_start(void *v_argv) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
if (uwsgi.master_as_root) {
|
||||
uwsgi_as_root();
|
||||
}
|
||||
@@ -2206,17 +2288,17 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
|
||||
uwsgi_add_sockets_to_queue(uwsgi.async_queue);
|
||||
|
||||
uwsgi.rb_async_timeouts = uwsgi_init_rb_timer();
|
||||
|
||||
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async);
|
||||
|
||||
for (i = 0; i < uwsgi.async; i++) {
|
||||
uwsgi.async_queue_unused[i] = uwsgi.wsgi_requests[i];
|
||||
}
|
||||
|
||||
uwsgi.async_queue_unused_ptr = uwsgi.async - 1;
|
||||
}
|
||||
|
||||
uwsgi.rb_async_timeouts = uwsgi_init_rb_timer();
|
||||
|
||||
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async);
|
||||
|
||||
for (i = 0; i < uwsgi.async; i++) {
|
||||
uwsgi.async_queue_unused[i] = uwsgi.wsgi_requests[i];
|
||||
}
|
||||
|
||||
uwsgi.async_queue_unused_ptr = uwsgi.async - 1;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2361,6 +2443,7 @@ void uwsgi_ignition() {
|
||||
#else
|
||||
if (uwsgi.threads > 1) {
|
||||
#endif
|
||||
|
||||
if (pthread_key_create(&uwsgi.tur_key, NULL)) {
|
||||
uwsgi_error("pthread_key_create()");
|
||||
exit(1);
|
||||
@@ -2393,6 +2476,8 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
char *p;
|
||||
struct uwsgi_static_map *usm, *old_usm;
|
||||
struct uwsgi_config_template *uct, *old_uct;
|
||||
struct uwsgi_cron *uc, *old_uc;
|
||||
int zerg_fd;
|
||||
|
||||
switch (i) {
|
||||
|
||||
@@ -2473,6 +2558,7 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
return 1;
|
||||
#ifdef UWSGI_THREADING
|
||||
case LONG_ARGS_THREADS:
|
||||
uwsgi.has_threads = 1;
|
||||
uwsgi.threads = atoi(optarg);
|
||||
return 1;
|
||||
#endif
|
||||
@@ -2487,6 +2573,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_LOGTO:
|
||||
logto(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_LOGTO2:
|
||||
uwsgi.logto2 = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_EMPEROR:
|
||||
uwsgi.emperor_dir = optarg;
|
||||
return 1;
|
||||
@@ -2650,6 +2739,12 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uct->filename = optarg;
|
||||
uct->next = NULL;
|
||||
|
||||
return 1;
|
||||
case LONG_ARGS_VASSALS_START_HOOK:
|
||||
uwsgi.vassals_start_hook = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_VASSALS_STOP_HOOK:
|
||||
uwsgi.vassals_stop_hook = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_VASSALS_INHERIT:
|
||||
uct = uwsgi.vassals_templates;
|
||||
@@ -2671,6 +2766,32 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uct->filename = optarg;
|
||||
uct->next = NULL;
|
||||
|
||||
return 1;
|
||||
case LONG_ARGS_CRON:
|
||||
uwsgi.master_process = 1;
|
||||
uc = uwsgi.crons;
|
||||
if (!uc) {
|
||||
uc = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uwsgi.crons = uc;
|
||||
}
|
||||
else {
|
||||
old_uc = uc;
|
||||
while(uc->next) {
|
||||
uc = uc->next;
|
||||
old_uc = uc;
|
||||
}
|
||||
|
||||
old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron));
|
||||
uc = old_uc->next;
|
||||
}
|
||||
|
||||
memset(uc, 0, sizeof(struct uwsgi_cron));
|
||||
|
||||
if (sscanf(optarg, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) {
|
||||
uwsgi_log("invalid cron syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
uc->command = optarg+i;
|
||||
return 1;
|
||||
case LONG_ARGS_STATIC_MAP:
|
||||
usm = uwsgi.static_maps;
|
||||
@@ -2889,6 +3010,23 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
case 's':
|
||||
uwsgi_new_socket(generate_socket_name(optarg));
|
||||
return 1;
|
||||
case LONG_ARGS_ZERG:
|
||||
zerg_fd = uwsgi_connect(optarg, 30, 0);
|
||||
if (zerg_fd < 0) {
|
||||
uwsgi_log("--- unable to connect to zerg server ---\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.zerg = uwsgi_attach_fd(zerg_fd, 8, "uwsgi-zerg", 11);
|
||||
if (uwsgi.zerg == NULL) {
|
||||
uwsgi_log("--- invalid data received from zerg-server ---\n");
|
||||
exit(1);
|
||||
}
|
||||
close(zerg_fd);
|
||||
return 1;
|
||||
case LONG_ARGS_ZERG_SERVER:
|
||||
uwsgi.zerg_server = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_SHARED_SOCKET:
|
||||
uwsgi_new_shared_socket(generate_socket_name(optarg));
|
||||
return 1;
|
||||
@@ -3046,79 +3184,24 @@ void manage_opt(int i, char *optarg) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_cluster_simple_add_node(char *nodename, int workers, int type) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_cluster_node *ucn;
|
||||
char *tcp_port;
|
||||
|
||||
if (strlen(nodename) > 100) {
|
||||
uwsgi_log("invalid cluster node name %s\n", nodename);
|
||||
return;
|
||||
}
|
||||
|
||||
tcp_port = strchr(nodename, ':');
|
||||
if (tcp_port == NULL) {
|
||||
fprintf(stdout, "invalid cluster node name %s\n", nodename);
|
||||
return;
|
||||
}
|
||||
|
||||
// first check for already present node
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
if (ucn->name[0] != 0) {
|
||||
if (!strcmp(ucn->name, nodename)) {
|
||||
ucn->status = UWSGI_NODE_OK;
|
||||
ucn->last_seen = time(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
|
||||
ucn = &uwsgi.shared->nodes[i];
|
||||
|
||||
if (ucn->name[0] == 0) {
|
||||
memcpy(ucn->name, nodename, strlen(nodename) + 1);
|
||||
ucn->workers = workers;
|
||||
ucn->ucn_addr.sin_family = AF_INET;
|
||||
ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1));
|
||||
tcp_port[0] = 0;
|
||||
if (nodename[0] == 0) {
|
||||
ucn->ucn_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%s\n", nodename);
|
||||
ucn->ucn_addr.sin_addr.s_addr = inet_addr(nodename);
|
||||
}
|
||||
|
||||
ucn->type = type;
|
||||
// here memory can be freed, as it is allocated by uwsgi_concat2n
|
||||
if (type == CLUSTER_NODE_DYNAMIC) {
|
||||
free(nodename);
|
||||
}
|
||||
else {
|
||||
tcp_port[0] = ':';
|
||||
}
|
||||
ucn->last_seen = time(NULL);
|
||||
uwsgi_log("[uWSGI cluster] added node %s\n", ucn->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_log("unable to add node %s\n", nodename);
|
||||
}
|
||||
|
||||
void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_cluster_node *ucn;
|
||||
char *tcp_port;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding node\n");
|
||||
#endif
|
||||
|
||||
tcp_port = strchr(nucn->name, ':');
|
||||
#ifndef UWSGI_ZEROMQ
|
||||
if (tcp_port == NULL) {
|
||||
#else
|
||||
char *zmq_dash = strchr(nucn->name, '-');
|
||||
if (tcp_port == NULL && zmq_dash == NULL) {
|
||||
#endif
|
||||
|
||||
fprintf(stdout, "invalid cluster node name %s\n", nucn->name);
|
||||
return;
|
||||
}
|
||||
@@ -3145,19 +3228,23 @@ void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) {
|
||||
memcpy(ucn->nodename, nucn->nodename, strlen(nucn->nodename) + 1);
|
||||
ucn->workers = nucn->workers;
|
||||
ucn->ucn_addr.sin_family = AF_INET;
|
||||
ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1));
|
||||
tcp_port[0] = 0;
|
||||
if (tcp_port) {
|
||||
ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1));
|
||||
tcp_port[0] = 0;
|
||||
}
|
||||
if (nucn->name[0] == 0) {
|
||||
ucn->ucn_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s\n", nucn->name);
|
||||
#endif
|
||||
ucn->ucn_addr.sin_addr.s_addr = inet_addr(nucn->name);
|
||||
}
|
||||
|
||||
ucn->type = type;
|
||||
// here memory can be freed, as it is allocated by uwsgi_concat2n
|
||||
if (type != CLUSTER_NODE_DYNAMIC) {
|
||||
if (type != CLUSTER_NODE_DYNAMIC && tcp_port) {
|
||||
tcp_port[0] = ':';
|
||||
}
|
||||
ucn->last_seen = time(NULL);
|
||||
@@ -3292,7 +3379,9 @@ void manage_string_opt(char *key, uint16_t keylen, char *val, uint16_t vallen, v
|
||||
char *key2 = uwsgi_concat2n(key, keylen, "", 0);
|
||||
char *val2 = uwsgi_concat2n(val, vallen, "", 0);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s = %s\n", key2, val2);
|
||||
#endif
|
||||
add_exported_option(key2, val2, 0);
|
||||
}
|
||||
|
||||
@@ -3309,6 +3398,8 @@ int uwsgi_cluster_add_me() {
|
||||
char numproc[6];
|
||||
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
char uuid_zmq_str[37];
|
||||
uuid_t uuid_zmq;
|
||||
if (!uwsgi.sockets && !uwsgi.zeromq) {
|
||||
#else
|
||||
if (!uwsgi.sockets) {
|
||||
@@ -3324,6 +3415,13 @@ int uwsgi_cluster_add_me() {
|
||||
if (uwsgi.sockets) {
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uwsgi.sockets->name) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
else if (uwsgi.zeromq) {
|
||||
uuid_generate(uuid_zmq);
|
||||
uuid_unparse(uuid_zmq, uuid_zmq_str);
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uuid_zmq_str) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
}
|
||||
@@ -3344,7 +3442,7 @@ int uwsgi_cluster_add_me() {
|
||||
ptrbuf += strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
if (uwsgi.sockets->name) {
|
||||
if (uwsgi.sockets && uwsgi.sockets->name) {
|
||||
ustrlen = strlen(key2);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
@@ -3357,6 +3455,21 @@ int uwsgi_cluster_add_me() {
|
||||
memcpy(ptrbuf, uwsgi.sockets->name, strlen(uwsgi.sockets->name));
|
||||
ptrbuf += strlen(uwsgi.sockets->name);
|
||||
}
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
else if (uwsgi.zeromq) {
|
||||
ustrlen = strlen(key2);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, key2, strlen(key2));
|
||||
ptrbuf += strlen(key2);
|
||||
|
||||
ustrlen = strlen(uuid_zmq_str);
|
||||
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
|
||||
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
|
||||
memcpy(ptrbuf, uuid_zmq_str, strlen(uuid_zmq_str));
|
||||
ptrbuf += strlen(uuid_zmq_str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ustrlen = strlen(key3);
|
||||
@@ -3388,7 +3501,9 @@ int uwsgi_cluster_add_me() {
|
||||
|
||||
free(buf);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("add_me() successfull\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3400,6 +3515,7 @@ int uwsgi_cluster_join(char *name) {
|
||||
int broadcast = 0;
|
||||
|
||||
|
||||
|
||||
if (name[0] == ':') {
|
||||
fd = bind_to_udp(name, 0, 1);
|
||||
broadcast = 1;
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
#define UWSGI_DECLARE_EMBEDDED_PLUGINS
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
#define inline
|
||||
#endif
|
||||
|
||||
#define UDEP(pname) extern struct uwsgi_plugin pname##_plugin;
|
||||
|
||||
#define ULEP(pname)\
|
||||
@@ -291,7 +296,7 @@ struct uwsgi_daemon {
|
||||
time_t last_spawn;
|
||||
int status;
|
||||
int registered;
|
||||
int pipe[2];
|
||||
//int pipe[2];
|
||||
};
|
||||
|
||||
struct uwsgi_queue_item {
|
||||
@@ -437,6 +442,12 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_LOG_SOCKET 17108
|
||||
#define LONG_ARGS_ADD_HEADER 17109
|
||||
#define LONG_ARGS_IDLE 17120
|
||||
#define LONG_ARGS_VASSALS_START_HOOK 17121
|
||||
#define LONG_ARGS_VASSALS_STOP_HOOK 17122
|
||||
#define LONG_ARGS_CRON 17123
|
||||
#define LONG_ARGS_ZERG 17124
|
||||
#define LONG_ARGS_ZERG_SERVER 17125
|
||||
#define LONG_ARGS_LOGTO2 17126
|
||||
|
||||
|
||||
#define UWSGI_OK 0
|
||||
@@ -516,6 +527,8 @@ struct uwsgi_socket {
|
||||
int arg;
|
||||
void *ctx;
|
||||
|
||||
int auto_port;
|
||||
|
||||
char *proto_name;
|
||||
|
||||
int (*proto)(struct wsgi_request *);
|
||||
@@ -553,6 +566,7 @@ struct uwsgi_plugin {
|
||||
void (*after_request) (struct wsgi_request *);
|
||||
void (*init_apps) (void);
|
||||
void (*fixup) (void);
|
||||
void (*master_fixup) (int);
|
||||
int (*mount_app) (char *, char *);
|
||||
int (*manage_udp) (char *, int, char *, int);
|
||||
int (*manage_xml) (char *, char *);
|
||||
@@ -668,14 +682,6 @@ struct wsgi_request {
|
||||
//iovec
|
||||
struct iovec *hvec;
|
||||
|
||||
struct msghdr msg;
|
||||
union {
|
||||
struct cmsghdr cmsg;
|
||||
#ifndef __NetBSD__
|
||||
char control [CMSG_SPACE (sizeof (int))];
|
||||
#endif
|
||||
} msg_control;
|
||||
|
||||
struct timeval start_of_request;
|
||||
struct timeval end_of_request;
|
||||
|
||||
@@ -803,6 +809,14 @@ struct wsgi_request {
|
||||
int sigwait;
|
||||
uint8_t signal_received;
|
||||
|
||||
struct msghdr msg;
|
||||
union {
|
||||
struct cmsghdr cmsg;
|
||||
// should be enough...
|
||||
char control [64];
|
||||
} msg_control;
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct uwsgi_fmon {
|
||||
@@ -840,6 +854,8 @@ struct uwsgi_server {
|
||||
int apps_cnt;
|
||||
int default_app;
|
||||
|
||||
char *logto2;
|
||||
|
||||
int autoload;
|
||||
|
||||
int snapshot;
|
||||
@@ -855,6 +871,8 @@ struct uwsgi_server {
|
||||
time_t current_time;
|
||||
uint64_t master_cycles;
|
||||
|
||||
int reuse_port;
|
||||
|
||||
int lazy;
|
||||
int cheap;
|
||||
int idle;
|
||||
@@ -872,6 +890,9 @@ struct uwsgi_server {
|
||||
char *emperor_amqp_username;
|
||||
char *emperor_amqp_password;
|
||||
|
||||
char *vassals_start_hook;
|
||||
char *vassals_stop_hook;
|
||||
|
||||
struct uwsgi_string_list *additional_headers;
|
||||
|
||||
time_t master_mercy;
|
||||
@@ -892,6 +913,10 @@ struct uwsgi_server {
|
||||
|
||||
char *remap_modifier;
|
||||
|
||||
int *zerg;
|
||||
char *zerg_server;
|
||||
int zerg_server_fd;
|
||||
|
||||
char *chroot;
|
||||
gid_t gid;
|
||||
uid_t uid;
|
||||
@@ -962,6 +987,8 @@ struct uwsgi_server {
|
||||
char *touch_reload;
|
||||
time_t last_touch_reload_mtime;
|
||||
|
||||
int propagate_touch;
|
||||
|
||||
int grunt;
|
||||
|
||||
char *binary_path;
|
||||
@@ -1009,8 +1036,6 @@ struct uwsgi_server {
|
||||
|
||||
int harakiri_verbose;
|
||||
|
||||
int main_queue;
|
||||
|
||||
int numproc;
|
||||
int async;
|
||||
int async_running;
|
||||
@@ -1138,6 +1163,8 @@ struct uwsgi_server {
|
||||
|
||||
struct uwsgi_string_list *map_socket;
|
||||
|
||||
struct uwsgi_cron *crons;
|
||||
|
||||
time_t respawn_delta;
|
||||
|
||||
char *mounts[MAX_APPS];
|
||||
@@ -1307,6 +1334,10 @@ struct uwsgi_cron {
|
||||
|
||||
time_t last_job;
|
||||
uint8_t sig;
|
||||
|
||||
char *command;
|
||||
|
||||
struct uwsgi_cron *next;
|
||||
};
|
||||
|
||||
struct uwsgi_shared {
|
||||
@@ -1420,6 +1451,8 @@ struct uwsgi_worker {
|
||||
|
||||
uint64_t exceptions;
|
||||
|
||||
int destroy;
|
||||
|
||||
};
|
||||
|
||||
char *uwsgi_get_cwd(void);
|
||||
@@ -1483,7 +1516,7 @@ uint64_t uwsgi_swap64(uint64_t);
|
||||
ssize_t send_udp_message(uint8_t, char *, char *, uint16_t);
|
||||
#endif
|
||||
|
||||
int uwsgi_parse_response(struct pollfd *, int, struct uwsgi_header *, char *, int (*)(struct wsgi_request *));
|
||||
int uwsgi_parse_packet(struct wsgi_request *, int);
|
||||
int uwsgi_parse_vars(struct wsgi_request *);
|
||||
|
||||
int uwsgi_enqueue_message(char *, int, uint8_t, uint8_t, char *, int, int);
|
||||
@@ -1491,7 +1524,6 @@ int uwsgi_enqueue_message(char *, int, uint8_t, uint8_t, char *, int
|
||||
void manage_opt(int, char *);
|
||||
|
||||
void uwsgi_cluster_add_node(struct uwsgi_cluster_node *, int);
|
||||
void uwsgi_cluster_simple_add_node(char *, int, int);
|
||||
int uwsgi_ping_node(int, struct wsgi_request *);
|
||||
|
||||
struct http_status_codes {
|
||||
@@ -1511,11 +1543,7 @@ struct wsgi_request *find_wsgi_req_by_id(int);
|
||||
void async_add_fd_write(struct wsgi_request *, int, int);
|
||||
void async_add_fd_read(struct wsgi_request *, int, int);
|
||||
|
||||
#ifdef __clang__
|
||||
struct wsgi_request *next_wsgi_req(struct wsgi_request *);
|
||||
#else
|
||||
inline struct wsgi_request *next_wsgi_req(struct wsgi_request *);
|
||||
#endif
|
||||
|
||||
|
||||
void async_add_timeout(struct wsgi_request*, int);
|
||||
@@ -1535,7 +1563,7 @@ void uwsgi_close_request(struct wsgi_request *);
|
||||
void wsgi_req_setup(struct wsgi_request *, int, struct uwsgi_socket *);
|
||||
int wsgi_req_recv(struct wsgi_request *);
|
||||
int wsgi_req_async_recv(struct wsgi_request *);
|
||||
int wsgi_req_accept(struct wsgi_request *);
|
||||
int wsgi_req_accept(int, struct wsgi_request *);
|
||||
int wsgi_req_simple_accept(struct wsgi_request *, int);
|
||||
|
||||
#define current_wsgi_req() (*uwsgi.current_wsgi_req)()
|
||||
@@ -1566,7 +1594,7 @@ void uwsgi_json_config(char *, char*[]);
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SQLITE3
|
||||
void uwsgi_sqlite3_config(char *);
|
||||
void uwsgi_sqlite3_config(char *, char *[]);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1576,13 +1604,8 @@ void uwsgi_ldap_schema_dump_ldif(void);
|
||||
void uwsgi_ldap_config(void);
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
int uwsgi_strncmp(char *, int, char *, int);
|
||||
int uwsgi_startswith(char *, char *, int);
|
||||
#else
|
||||
inline int uwsgi_strncmp(char *, int, char *, int);
|
||||
inline int uwsgi_startswith(char *, char *, int);
|
||||
#endif
|
||||
|
||||
|
||||
char *uwsgi_concat(int,...);
|
||||
@@ -1808,6 +1831,9 @@ struct uwsgi_dict {
|
||||
struct uwsgi_subscriber_name {
|
||||
uint16_t len;
|
||||
char name[128];
|
||||
|
||||
uint8_t modifier1;
|
||||
uint8_t modifier2;
|
||||
};
|
||||
|
||||
struct uwsgi_subscriber {
|
||||
@@ -1827,10 +1853,13 @@ struct uwsgi_subscribe_req {
|
||||
|
||||
char *auth;
|
||||
uint16_t auth_len;
|
||||
|
||||
uint8_t modifier1;
|
||||
uint8_t modifier2;
|
||||
};
|
||||
|
||||
struct uwsgi_dict *uwsgi_dict_create(uint64_t, uint64_t);
|
||||
void uwsgi_add_subscriber(struct uwsgi_dict *, char *, uint16_t, char *, uint64_t);
|
||||
void uwsgi_add_subscriber(struct uwsgi_dict *, struct uwsgi_subscribe_req *);
|
||||
char *uwsgi_dict_get(struct uwsgi_dict *, char *, uint16_t, uint64_t *);
|
||||
int uwsgi_dict_set(struct uwsgi_dict *, char *, uint16_t, char *, uint64_t);
|
||||
|
||||
@@ -2003,3 +2032,15 @@ void uwsgi_set_cgroup(void);
|
||||
|
||||
void uwsgi_add_sockets_to_queue(int);
|
||||
void uwsgi_del_sockets_from_queue(int);
|
||||
|
||||
int uwsgi_run_command_and_wait(char *, ...);
|
||||
|
||||
void uwsgi_manage_signal_cron(time_t);
|
||||
int uwsgi_run_command(char *);
|
||||
|
||||
void uwsgi_manage_command_cron(time_t);
|
||||
|
||||
int *uwsgi_attach_fd(int, int, char *, size_t);
|
||||
|
||||
int uwsgi_count_sockets(struct uwsgi_socket *);
|
||||
int uwsgi_file_exists(char *);
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
from uwsgicc import app
|
||||
|
||||
import uwsgi
|
||||
|
||||
def hello_world(name):
|
||||
return "Hello World %s" % name
|
||||
|
||||
uwsgi.register_rpc("hello", hello_world)
|
||||
|
||||
uwsgi.set_warning_message("uWSGI is running the Control Center")
|
||||
|
||||
application = app
|
||||
|
||||
@@ -152,7 +152,7 @@ $(document).ready(function() {
|
||||
});
|
||||
|
||||
$('#rpc_form').submit(function() {
|
||||
$.post('{{url_for('rpc')}}', { node: '192.168.173.100:3031', func: 'hello', args: ''}, function(data) {
|
||||
$.post('{{url_for('rpc')}}', { node: $('[name=node]').val(), func: $('[name=func]').val(), args: $('[name=args]').val()}, function(data) {
|
||||
$('#dialog-modal').html(data);
|
||||
$('#dialog-modal').attr('title', 'RPC "hello" returned:');
|
||||
$('#dialog-modal').dialog({
|
||||
@@ -174,7 +174,7 @@ $(document).ready(function() {
|
||||
<a name="top"></a>
|
||||
<h1>uWSGI <span class="small">{{uwsgi.version}}</span> Control Center</h1>
|
||||
<div class="anchor">
|
||||
<a href="#information">information</a> | <a href="#options">options</a> | <a href="#logs">logs</a> | <a href="#workers">workers</a> | <a href="#rpc">rpc</a> {% if uwsgi.cluster() %}| <a href="#cluster">cluster</a>{% endif %}
|
||||
<a href="#information">information</a> | <a href="#options">options</a> | <a href="#logs">logs</a> | <a href="#signals">signals</a> | <a href="#workers">workers</a> | <a href="#rpc">rpc</a> {% if uwsgi.cluster() %}| <a href="#cluster">cluster</a>{% endif %}
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages() %}
|
||||
@@ -239,6 +239,21 @@ $(document).ready(function() {
|
||||
|
||||
</div>
|
||||
|
||||
<a name="signals"></a>
|
||||
<h3>Signals</h3>
|
||||
<div class="info">
|
||||
<form action="{{url_for('sig')}}" method="POST">
|
||||
<input type="text" size="3" name="signum" />
|
||||
<input type="submit" value="send uwsgi signal" />
|
||||
</form>
|
||||
|
||||
<div class="anchor">
|
||||
<a href="#top">back to top</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<a name="workers"></a>
|
||||
<h3>Workers</h3>
|
||||
<div class="info">
|
||||
|
||||
+10
-2
@@ -23,16 +23,24 @@ def log():
|
||||
flash("log message written")
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route("/sig", methods=['POST'])
|
||||
def sig():
|
||||
try:
|
||||
uwsgi.signal(int(request.form['signum']))
|
||||
flash("uwsgi signal sent")
|
||||
except:
|
||||
flash("unable to send signal")
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route("/rpc", methods=['POST'])
|
||||
def rpc():
|
||||
node = str(request.form['node'])
|
||||
if node == '':
|
||||
node = None
|
||||
|
||||
fargs = str(request.form['args'])
|
||||
|
||||
args = fargs.split()
|
||||
|
||||
|
||||
if len(args) > 0:
|
||||
ret = uwsgi.rpc(str(node), str(request.form['func']), *map(str, args))
|
||||
else:
|
||||
|
||||
+27
-4
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '0.9.8'
|
||||
uwsgi_version = '0.9.8.1'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -63,8 +63,26 @@ def add_o(x):
|
||||
return x
|
||||
|
||||
|
||||
def compile(file, objfile, cflags):
|
||||
cmdline = "%s -c %s -o %s %s" % (GCC, cflags, objfile, file)
|
||||
def compile(cflags, objfile, srcfile):
|
||||
source_stat = os.stat(srcfile)
|
||||
header_stat = os.stat('uwsgi.h')
|
||||
try:
|
||||
if os.environ.get('UWSGI_FORCE_REBUILD', None):
|
||||
raise
|
||||
object_stat = os.stat(objfile)
|
||||
if object_stat[8] <= source_stat[8]:
|
||||
raise
|
||||
if object_stat[8] <= header_stat[8]:
|
||||
raise
|
||||
for profile in os.listdir('buildconf'):
|
||||
profile_stat = os.stat('buildconf/%s' % profile)
|
||||
if object_stat[8] <= profile_stat[8]:
|
||||
raise
|
||||
print("%s is up to date" % objfile)
|
||||
return
|
||||
except:
|
||||
pass
|
||||
cmdline = "%s -c %s -o %s %s" % (GCC, cflags, objfile, srcfile)
|
||||
print(cmdline)
|
||||
ret = os.system(cmdline)
|
||||
if ret != 0:
|
||||
@@ -659,7 +677,6 @@ if __name__ == "__main__":
|
||||
pass
|
||||
if not '/' in bconf:
|
||||
bconf = 'buildconf/%s' % bconf
|
||||
|
||||
uc = uConf(bconf)
|
||||
gcc_list, cflags, ldflags, libs = uc.get_gcll()
|
||||
try:
|
||||
@@ -667,6 +684,12 @@ if __name__ == "__main__":
|
||||
except:
|
||||
name = None
|
||||
build_plugin(sys.argv[2], uc, cflags, ldflags, libs, name)
|
||||
elif cmd == '--clean':
|
||||
os.system("rm *.o")
|
||||
os.system("rm proto/*.o")
|
||||
os.system("rm lib/*.o")
|
||||
os.system("rm plugins/*/*.o")
|
||||
|
||||
else:
|
||||
print("unknown uwsgiconfig command")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import uwsgi
|
||||
|
||||
if uwsgi.masterpid() == 0:
|
||||
raise Exception("you have to enable the uWSGI master process to use this module")
|
||||
|
||||
if uwsgi.opt.get('lazy'):
|
||||
raise Exception("uWSGI lazy mode is not supporte by this module")
|
||||
|
||||
class rpc(object):
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_rpc(self.name, f)
|
||||
return f
|
||||
|
||||
class signal(object):
|
||||
|
||||
def __init__(self, num):
|
||||
self.num = num
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
return f
|
||||
|
||||
class timer(object):
|
||||
|
||||
def __init__(self, num, secs):
|
||||
self.num = num
|
||||
self.secs = secs
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.add_timer(self.num, self.secs)
|
||||
return f
|
||||
|
||||
class rbtimer(object):
|
||||
|
||||
def __init__(self, num, secs):
|
||||
self.num = num
|
||||
self.secs = secs
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.add_rb_timer(self.num, self.secs)
|
||||
return f
|
||||
|
||||
class filemon(object):
|
||||
|
||||
def __init__(self, num, fsobj):
|
||||
self.num = num
|
||||
self.fsobj = fsobj
|
||||
|
||||
def __call__(self, f):
|
||||
uwsgi.register_signal(self.num, "", f)
|
||||
uwsgi.add_file_monitor(self.num, self.fsobj)
|
||||
return f
|
||||
@@ -135,7 +135,10 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
yaml_parser_set_input_string(&parser, (const unsigned char *)yaml, (size_t) len-1);
|
||||
|
||||
while(parsing) {
|
||||
yaml_parser_scan(&parser, &token);
|
||||
if (!yaml_parser_scan(&parser, &token)) {
|
||||
uwsgi_log("error parsing YAML file: %s (%c)\n", parser.problem, yaml[parser.problem_offset]);
|
||||
exit(1);
|
||||
}
|
||||
switch(token.type) {
|
||||
case YAML_STREAM_END_TOKEN:
|
||||
parsing = 0;
|
||||
|
||||
Reference in New Issue
Block a user