mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
920d5d7416 | ||
|
|
dcb654d7fb | ||
|
|
a563da1223 | ||
|
|
1e26cda615 | ||
|
|
97133b27ce | ||
|
|
b428bd3b87 | ||
|
|
05136e74b4 | ||
|
|
9f28a8bdf1 | ||
|
|
d9361f1fee | ||
|
|
835230b1a4 | ||
|
|
f88f51c553 | ||
|
|
1996305eb1 | ||
|
|
c7ad50e950 | ||
|
|
0ec0c29d67 | ||
|
|
75af117e8a | ||
|
|
2b04cefe4e | ||
|
|
0e41c4111a | ||
|
|
5f5d382c64 | ||
|
|
3e867fe401 | ||
|
|
153142b8b0 | ||
|
|
5562c0c047 | ||
|
|
f4a1f800ba | ||
|
|
bdbc5e5605 | ||
|
|
4104f825ff | ||
|
|
efa01ea404 | ||
|
|
982559ae66 | ||
|
|
60002e8de8 |
@@ -30,3 +30,4 @@ fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
|
||||
f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
|
||||
6945ee03c7ea95eb19217ef1e1fb17d9ae26adbc 0.9.9-beta1
|
||||
fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
|
||||
6aa667612019fcff8e68af9469f73aff6fa378a8 0.9.9-rc2
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
*** august 2011 ***
|
||||
|
||||
* 0.9.9 [20110829]
|
||||
|
||||
- various spooler improvements
|
||||
- upload progress optimizations and fixes
|
||||
- new emperor mode: Tyrant
|
||||
- allows multiple --ini options
|
||||
- better binary path detection
|
||||
- gevent loop engine support
|
||||
- resolve domain names in socket logging
|
||||
- snmp fixes and reintroduction of the snmp-api
|
||||
- fixed grunt mode
|
||||
- you can specify build profile via env var UWSGI_PROFILE
|
||||
- reintroduction of string-based multiapp
|
||||
- new option --emperor-throttle
|
||||
- improved queue and sharedarea subsystems
|
||||
- uWSGI can now be built as a shared library
|
||||
- new api attribute: uwsgi.magic_table
|
||||
- improved apache2 module
|
||||
- new option --pyshell
|
||||
- allow threads in gateways
|
||||
- fastrouter improvements
|
||||
- the application list is now shared and exported to the api
|
||||
- allows setting the thread stack size
|
||||
- UWSGI_APPID for better multiapp hosting
|
||||
- better reloading in lazy mode
|
||||
- native pump support
|
||||
- various rack fixes
|
||||
- support for attaching binary data in the executable
|
||||
- new option --set
|
||||
- extreme-optimized http protocol parser
|
||||
- WSGI handler optimizations
|
||||
|
||||
*** july 2011 ***
|
||||
|
||||
* 0.9.8.3 [20110723]
|
||||
|
||||
@@ -12,4 +12,6 @@ env LOGTO=/tmp/uwsgi.log
|
||||
env BINPATH=/home/foo/uwsgi/uwsgi
|
||||
|
||||
# --no-orphans avoid workers without master
|
||||
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -m simple_app --logto $LOGTO -M -p 4
|
||||
# --die-on-term could be a good idea
|
||||
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -w simple_app --logto $LOGTO -M -p 4
|
||||
|
||||
|
||||
+21
-10
@@ -10,8 +10,8 @@ import time
|
||||
|
||||
# register rpc function helloworld
|
||||
@rpc("helloworld")
|
||||
def hello_world():
|
||||
return "Hello World"
|
||||
def hello2():
|
||||
return "[RPC] Hello World"
|
||||
|
||||
# register signal 1
|
||||
@signal(1)
|
||||
@@ -45,6 +45,7 @@ def tmpmodified(num):
|
||||
def a_long_task(args):
|
||||
for i in xrange(1,10):
|
||||
print("%s = %d" % ( str(args), i))
|
||||
print(uwsgi.call('helloworld'))
|
||||
time.sleep(1)
|
||||
|
||||
# continuosly spool a long running task
|
||||
@@ -52,10 +53,12 @@ def a_long_task(args):
|
||||
def an_infinite_task(args):
|
||||
for i in xrange(1,4):
|
||||
print("infinite: %d %s" % (i, str(args)))
|
||||
print(uwsgi.call('helloworld'))
|
||||
uwsgi.signal(100)
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
# spool a task after 60 seconds
|
||||
# spool a task after 5 seconds
|
||||
@spool
|
||||
def delayed_task(args):
|
||||
print("*** I am a delayed spool job. It is %s [%s]***" % (time.asctime(), str(args)))
|
||||
@@ -89,7 +92,10 @@ def a_running_thread_with_args(who):
|
||||
def a_post_fork_thread():
|
||||
while True:
|
||||
time.sleep(3)
|
||||
print("Hello from a thread in worker %d" % uwsgi.worker_id())
|
||||
if uwsgi.i_am_the_spooler():
|
||||
print("Hello from a thread in the spooler")
|
||||
else:
|
||||
print("Hello from a thread in worker %d" % uwsgi.worker_id())
|
||||
|
||||
@postfork
|
||||
def fork_happened():
|
||||
@@ -97,24 +103,29 @@ def fork_happened():
|
||||
|
||||
@postfork
|
||||
def fork_happened2():
|
||||
print("waiting for a signal...")
|
||||
uwsgi.signal_wait()
|
||||
print("signal received: %d" % uwsgi.signal_received())
|
||||
if uwsgi.i_am_the_spooler():
|
||||
return
|
||||
print("worker %d is waiting for signal 100..." % uwsgi.worker_id())
|
||||
uwsgi.signal_wait(100)
|
||||
print("worker %d received signal %d" % (uwsgi.worker_id(), uwsgi.signal_received()))
|
||||
print("fork() has been called [2] wid: %d" % uwsgi.worker_id())
|
||||
|
||||
@postfork
|
||||
@lock
|
||||
def locked_func():
|
||||
print("starting locked function on worker %d" % uwsgi.worker_id())
|
||||
for i in xrange(1, 100):
|
||||
time.sleep(0.2)
|
||||
for i in xrange(1, 5):
|
||||
time.sleep(1)
|
||||
print("[locked %d] waiting..." % uwsgi.worker_id())
|
||||
print("done with locked function on worker %d" % uwsgi.worker_id())
|
||||
|
||||
print(uwsgi.call('helloworld'))
|
||||
spool_filename = a_long_task.spool({'foo':'bar'}, hello='world')
|
||||
print("spool filename = %s" % spool_filename)
|
||||
an_infinite_task.spool(foo='bar', priority=3)
|
||||
delayed_task.spool(foo2='bar2', at=time.time()+60)
|
||||
when = int(time.time())+5
|
||||
print("scheduling a delayed task at %d" % when)
|
||||
delayed_task.spool(foo2='bar2', at=when)
|
||||
a_running_thread()
|
||||
a_running_thread_with_args("uWSGI")
|
||||
uwsgi_source_file = open('uwsgi.c','r')
|
||||
|
||||
@@ -14,10 +14,11 @@ def index(request):
|
||||
w['load'] = (100 * (w['running_time']/1000))/total_load
|
||||
w['last_spawn_str'] = time.ctime(w['last_spawn'])
|
||||
|
||||
spooler_jobs = uwsgi.spooler_jobs()
|
||||
jobs = []
|
||||
for j in spooler_jobs:
|
||||
jobs.append({'file': j, 'env': uwsgi.parsefile(j)})
|
||||
if 'spooler' in uwsgi.opt:
|
||||
spooler_jobs = uwsgi.spooler_jobs()
|
||||
for j in spooler_jobs:
|
||||
jobs.append({'file': j, 'env': uwsgi.parsefile(j)})
|
||||
|
||||
return render_to_response('uwsgi.html', {'masterpid': uwsgi.masterpid(),
|
||||
'started_on': time.ctime(uwsgi.started_on),
|
||||
|
||||
@@ -32,6 +32,9 @@ struct uwsgi_instance {
|
||||
int loyal;
|
||||
|
||||
int zerg;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
|
||||
@@ -169,7 +172,7 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
|
||||
uwsgi_log("reload the uwsgi instance %s\n", c_ui->name);
|
||||
}
|
||||
|
||||
void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
void emperor_add(char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid) {
|
||||
|
||||
struct uwsgi_instance *c_ui = ui;
|
||||
struct uwsgi_instance *n_ui = NULL;
|
||||
@@ -183,6 +186,13 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
|
||||
usleep(uwsgi.emperor_throttle*1000);
|
||||
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (uid == 0 || gid == 0) {
|
||||
uwsgi_log("[emperor-tyrant] invalid permissions for file %s\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (c_ui->ui_next) {
|
||||
c_ui = c_ui->ui_next;
|
||||
}
|
||||
@@ -209,6 +219,8 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
|
||||
memcpy(n_ui->name, name, strlen(name));
|
||||
n_ui->born = born;
|
||||
n_ui->uid = uid;
|
||||
n_ui->gid = gid;
|
||||
n_ui->last_mod = born;
|
||||
// start without loyalty
|
||||
n_ui->last_loyal = born;
|
||||
@@ -253,6 +265,24 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
|
||||
}
|
||||
else {
|
||||
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) uid, (int) gid, name);
|
||||
if (setgid(gid)) {
|
||||
uwsgi_error("setgid()");
|
||||
exit(1);
|
||||
}
|
||||
if (setgroups(0, NULL)) {
|
||||
uwsgi_error("setgroups()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setuid(uid)) {
|
||||
uwsgi_error("setuid()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsetenv("UWSGI_RELOADS");
|
||||
unsetenv("NOTIFY_SOCKET");
|
||||
|
||||
@@ -517,7 +547,7 @@ reconnect:
|
||||
}
|
||||
else {
|
||||
if (msgsize > 0) {
|
||||
emperor_add(config_file, time(NULL), config, msgsize);
|
||||
emperor_add(config_file, time(NULL), config, msgsize, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +584,7 @@ reconnect:
|
||||
emperor_respawn(ui_current, time(NULL));
|
||||
}
|
||||
else {
|
||||
emperor_add(config_file, time(NULL), NULL, 0);
|
||||
emperor_add(config_file, time(NULL), NULL, 0, 0, 0);
|
||||
}
|
||||
|
||||
free(config_file);
|
||||
@@ -583,7 +613,7 @@ reconnect:
|
||||
else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
|
||||
uwsgi_log("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
|
||||
char *zerg_name = uwsgi_concat3(ui_current->name,":","zerg");
|
||||
emperor_add(zerg_name, time(NULL), NULL, 0);
|
||||
emperor_add(zerg_name, time(NULL), NULL, 0, ui_current->uid, ui_current->gid);
|
||||
free(zerg_name);
|
||||
}
|
||||
}
|
||||
@@ -620,13 +650,21 @@ reconnect:
|
||||
ui_current = emperor_get(de->d_name);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, sotp the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n");
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(de->d_name, st.st_mtime, NULL, 0);
|
||||
emperor_add(de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -659,13 +697,21 @@ reconnect:
|
||||
ui_current = emperor_get(g.gl_pathv[i]);
|
||||
|
||||
if (ui_current) {
|
||||
// check if uid or gid are changed, in such case, sotp the instance
|
||||
if (uwsgi.emperor_tyrant) {
|
||||
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
|
||||
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n");
|
||||
emperor_stop(ui_current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check if mtime is changed and the uWSGI instance must be reloaded
|
||||
if (st.st_mtime > ui_current->last_mod) {
|
||||
emperor_respawn(ui_current, st.st_mtime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emperor_add(g.gl_pathv[i], st.st_mtime, NULL, 0);
|
||||
emperor_add(g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,7 +775,7 @@ reconnect:
|
||||
}
|
||||
else {
|
||||
// UNSAFE
|
||||
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len);
|
||||
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid);
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -687,13 +687,21 @@ enum
|
||||
|
||||
|
||||
static int timerfd_create (clockid_t __clock_id, int __flags) {
|
||||
#ifdef __amd64__
|
||||
return syscall(283, __clock_id, __flags);
|
||||
#elif defined(__i386__)
|
||||
return syscall(322, __clock_id, __flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int timerfd_settime (int __ufd, int __flags,
|
||||
__const struct itimerspec *__utmr,
|
||||
struct itimerspec *__otmr) {
|
||||
#ifdef __amd64__
|
||||
return syscall(286, __ufd, __flags, __utmr, __otmr);
|
||||
#elif defined(__i386__)
|
||||
return syscall(325, __ufd, __flags, __utmr, __otmr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ void uwsgi_lock(void *lock) {
|
||||
void uwsgi_unlock(void *lock) {
|
||||
|
||||
pthread_mutex_unlock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_rwlock_init(void *lock) {
|
||||
|
||||
@@ -318,6 +318,15 @@ void master_loop(char **argv, char **environ) {
|
||||
#endif
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]);
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding %d to signal poll (spooler)\n", uwsgi.shared->spooler_signal_pipe[0]);
|
||||
#endif
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.log_master) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]);
|
||||
@@ -1016,6 +1025,30 @@ void master_loop(char **argv, char **environ) {
|
||||
//uwsgi.workers[i].pipe[0] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
// check for spooler signal
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) {
|
||||
rlen = read(interesting_fd, &uwsgi_signal, 1);
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("received uwsgi signal %d from the spooler\n", uwsgi_signal);
|
||||
#endif
|
||||
uwsgi_route_signal(uwsgi_signal);
|
||||
}
|
||||
else {
|
||||
uwsgi_log_verbose("lost connection with the spooler\n");
|
||||
close(interesting_fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
uwsgi.current_time = time(NULL);
|
||||
@@ -1230,7 +1263,9 @@ void master_loop(char **argv, char **environ) {
|
||||
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
|
||||
if (diedpid == uwsgi.shared->spooler_pid) {
|
||||
uwsgi_log( "OOOPS the spooler is no more...trying respawn...\n");
|
||||
uwsgi.spooler_respawned++;
|
||||
uwsgi.shared->spooler_pid = spooler_start();
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
+189
-73
@@ -10,34 +10,82 @@ struct option gevent_options[] = {
|
||||
#define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, ugevent.greenlet_switch_args, 0, NULL); Py_DECREF(gswitch)
|
||||
#define GET_CURRENT_GREENLET python_call(ugevent.get_current, ugevent.get_current_args, 0, NULL)
|
||||
#define free_req_queue uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req
|
||||
#define stop_the_watchers ret = PyObject_CallMethod(timer, "stop", NULL);\
|
||||
if (ret) Py_DECREF(ret);\
|
||||
ret = PyObject_CallMethod(watcher, "stop", NULL);\
|
||||
if (ret) Py_DECREF(ret);
|
||||
|
||||
struct uwsgi_gevent {
|
||||
PyObject *greenlet_switch;
|
||||
PyObject *greenlet_switch_args;
|
||||
PyObject *get_current;
|
||||
PyObject *get_current_args;
|
||||
PyObject *hub;
|
||||
PyObject *hub_loop;
|
||||
PyObject *spawn;
|
||||
PyObject *greenlet_args;
|
||||
PyObject *signal_args;
|
||||
} ugevent;
|
||||
|
||||
|
||||
PyObject* gevent_wait_io_and_switch(int fd, PyObject *greenlet_switch) {
|
||||
PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", fd, 1);
|
||||
if (!watcher) {
|
||||
PyErr_Print();
|
||||
return NULL;
|
||||
uint8_t uwsgi_signal;
|
||||
int signal_socket;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:uwsgi_gevent_signal_handler", &signal_socket)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (read(signal_socket, &uwsgi_signal, 1) <= 0) {
|
||||
if (uwsgi.no_orphans) {
|
||||
uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid);
|
||||
end_me(0);
|
||||
}
|
||||
// close the socket to end the mess...from now on the worker is alone (no master)
|
||||
else close(signal_socket);
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
#endif
|
||||
if (uwsgi_signal_handler(uwsgi_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *ret = PyObject_CallMethod(watcher, "start", "O", greenlet_switch);
|
||||
Py_DECREF(ret);
|
||||
|
||||
return watcher;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_gevent_callback(PyObject * self, PyObject * args) {
|
||||
PyObject *py_uwsgi_gevent_signal(PyObject * self, PyObject * args) {
|
||||
|
||||
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.signal_socket));
|
||||
|
||||
// spawn the signal_handler greenlet
|
||||
PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
|
||||
Py_DECREF(new_gl);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
// yes copy&paste no-DRY for me :P
|
||||
PyObject *py_uwsgi_gevent_my_signal(PyObject * self, PyObject * args) {
|
||||
|
||||
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.my_signal_socket));
|
||||
|
||||
// spawn the signal_handler greenlet
|
||||
PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
|
||||
Py_DECREF(new_gl);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {
|
||||
|
||||
|
||||
struct wsgi_request *wsgi_req = find_first_available_wsgi_req();
|
||||
@@ -48,21 +96,30 @@ PyObject *py_uwsgi_gevent_callback(PyObject * self, PyObject * args) {
|
||||
}
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
// fill wsgi_request structure
|
||||
wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets );
|
||||
|
||||
// mark core as used
|
||||
uwsgi.core[wsgi_req->async_id]->in_request = 1;
|
||||
|
||||
gettimeofday(&wsgi_req->start_of_request, NULL);
|
||||
|
||||
// enter harakiri mode
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
|
||||
}
|
||||
|
||||
// accept the connection
|
||||
if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) {
|
||||
uwsgi_close_request(wsgi_req);
|
||||
free_req_queue;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
|
||||
// hack to easily pass wsgi_req pointer to the greenlet
|
||||
PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req));
|
||||
|
||||
// spawn the request greenlet
|
||||
PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL);
|
||||
Py_DECREF(new_gl);
|
||||
|
||||
@@ -71,8 +128,27 @@ clear:
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
|
||||
PyObject *uwsgi_gevent_wait(PyObject *watcher, PyObject *timer, PyObject *current) {
|
||||
|
||||
PyObject *ret;
|
||||
|
||||
// start the io watcher
|
||||
ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher);
|
||||
if (!ret) return NULL;
|
||||
Py_DECREF(ret);
|
||||
|
||||
// start the timeout handler
|
||||
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
|
||||
if (!ret) return NULL;
|
||||
Py_DECREF(ret);
|
||||
|
||||
// pass control to the hub
|
||||
return PyObject_CallMethod(ugevent.hub, "switch", NULL);
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *ret;
|
||||
PyObject *py_wsgi_req = PyTuple_GetItem(args, 0);
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req);
|
||||
int status ;
|
||||
@@ -80,24 +156,47 @@ PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
|
||||
PyObject *current_greenlet = GET_CURRENT_GREENLET;
|
||||
PyObject *greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch");
|
||||
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
|
||||
// create a watcher for request socket
|
||||
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1);
|
||||
if (!watcher) goto clear1;
|
||||
|
||||
// a timer to implement timeoit (thanks Denis)
|
||||
PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (!timer) goto clear0;
|
||||
|
||||
for(;;) {
|
||||
// wait for data in the socket
|
||||
PyObject *ret = uwsgi_gevent_wait(watcher, timer, greenlet_switch);
|
||||
if (!ret) goto clear_and_stop;
|
||||
|
||||
// do not forget to overwrite this pointer each time !!!
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
PyObject *watcher = gevent_wait_io_and_switch(wsgi_req->poll.fd, greenlet_switch);
|
||||
if (!watcher) {
|
||||
goto clear;
|
||||
}
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
status = wsgi_req->socket->proto(wsgi_req);
|
||||
PyObject *ret = PyObject_CallMethod(watcher, "stop", NULL);
|
||||
|
||||
// we can safely decref here as watcher and timer has got a +1 for start() method
|
||||
Py_DECREF(ret);
|
||||
Py_DECREF(watcher);
|
||||
if (status < 0) {
|
||||
goto clear;
|
||||
if (ret == timer) {
|
||||
uwsgi_log( "timeout. skip request.\n");
|
||||
goto clear_and_stop;
|
||||
}
|
||||
else if (status == 0) {
|
||||
break;
|
||||
else if (ret == watcher) {
|
||||
|
||||
status = wsgi_req->socket->proto(wsgi_req);
|
||||
if (status < 0) {
|
||||
goto clear_and_stop;
|
||||
}
|
||||
else if (status == 0) {
|
||||
stop_the_watchers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
uwsgi_log("unrecognized gevent event !!!\n");
|
||||
goto clear_and_stop;
|
||||
}
|
||||
|
||||
stop_the_watchers;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
@@ -106,10 +205,21 @@ PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
|
||||
if (wsgi_req->async_status <= UWSGI_OK) {
|
||||
goto clear;
|
||||
}
|
||||
// switch after each yield
|
||||
GEVENT_SWITCH;
|
||||
}
|
||||
|
||||
goto clear;
|
||||
|
||||
clear_and_stop:
|
||||
|
||||
stop_the_watchers;
|
||||
|
||||
clear:
|
||||
Py_DECREF(timer);
|
||||
clear0:
|
||||
Py_DECREF(watcher);
|
||||
clear1:
|
||||
Py_DECREF(greenlet_switch);
|
||||
Py_DECREF(current_greenlet);
|
||||
uwsgi_close_request(wsgi_req);
|
||||
@@ -124,8 +234,11 @@ clear:
|
||||
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_gevent_callback_method[] = { {"uwsgi_gevent_callback", py_uwsgi_gevent_callback, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_greenlet_method[] = { {"uwsgi_gevent_greenlet", py_uwsgi_gevent_greenlet, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_main_def[] = { {"uwsgi_gevent_main", py_uwsgi_gevent_main, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_request_def[] = { {"uwsgi_gevent_request", py_uwsgi_gevent_request, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_signal_def[] = { {"uwsgi_gevent_signal", py_uwsgi_gevent_signal, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_my_signal_def[] = { {"uwsgi_gevent_my_signal", py_uwsgi_gevent_my_signal, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_gevent_signal_handler_def[] = { {"uwsgi_gevent_signal_handler", py_uwsgi_gevent_signal_handler, METH_VARARGS, ""} };
|
||||
|
||||
|
||||
void gevent_loop() {
|
||||
@@ -139,16 +252,10 @@ void gevent_loop() {
|
||||
|
||||
|
||||
PyObject *gevent_dict = get_uwsgi_pydict("gevent");
|
||||
if (!gevent_dict) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!gevent_dict) uwsgi_pyexit;
|
||||
|
||||
PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
|
||||
if (!gevent_version) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!gevent_version) uwsgi_pyexit;
|
||||
|
||||
if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) {
|
||||
uwsgi_log("uWSGI requires at least gevent 1.x version\n");
|
||||
@@ -156,16 +263,10 @@ void gevent_loop() {
|
||||
}
|
||||
|
||||
ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
|
||||
if (!ugevent.spawn) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!ugevent.spawn) uwsgi_pyexit;
|
||||
|
||||
ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
|
||||
if (!ugevent.greenlet_switch) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!ugevent.greenlet_switch) uwsgi_pyexit;
|
||||
|
||||
ugevent.greenlet_switch_args = PyTuple_New(0);
|
||||
Py_INCREF(ugevent.greenlet_switch_args);
|
||||
@@ -173,52 +274,67 @@ void gevent_loop() {
|
||||
|
||||
PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");
|
||||
|
||||
PyObject *gevent_hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
|
||||
if (!gevent_hub) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
|
||||
if (!ugevent.hub) uwsgi_pyexit;
|
||||
|
||||
ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent");
|
||||
if (!ugevent.get_current) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!ugevent.get_current) uwsgi_pyexit;
|
||||
|
||||
ugevent.get_current_args = PyTuple_New(0);
|
||||
Py_INCREF(ugevent.get_current_args);
|
||||
|
||||
|
||||
ugevent.hub_loop = PyObject_GetAttrString(gevent_hub, "loop");
|
||||
if (!ugevent.hub_loop) {
|
||||
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop");
|
||||
if (!ugevent.hub_loop) uwsgi_pyexit;
|
||||
|
||||
// this is the watcher for server socket
|
||||
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1);
|
||||
if (!watcher) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (!watcher) uwsgi_pyexit;
|
||||
|
||||
// main greenlet waiting for connection
|
||||
PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
|
||||
Py_INCREF(uwsgi_gevent_main);
|
||||
|
||||
PyObject *uwsgi_gevent_callback = PyCFunction_New(uwsgi_gevent_callback_method, NULL);
|
||||
Py_INCREF(uwsgi_gevent_callback);
|
||||
|
||||
PyObject *uwsgi_gevent_greenlet = PyCFunction_New(uwsgi_gevent_greenlet_method, NULL);
|
||||
Py_INCREF(uwsgi_gevent_greenlet);
|
||||
// greenlet to run at each request
|
||||
PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL);
|
||||
Py_INCREF(uwsgi_request_greenlet);
|
||||
|
||||
// pre-fill the greenlet args
|
||||
ugevent.greenlet_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_gevent_greenlet);
|
||||
PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet);
|
||||
|
||||
if (uwsgi.signal_socket > -1) {
|
||||
// and these are the watcher for signal sockets
|
||||
|
||||
PyObject *signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1);
|
||||
if (!signal_watcher) uwsgi_pyexit;
|
||||
|
||||
PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_callback);
|
||||
PyObject *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
|
||||
if (!my_signal_watcher) uwsgi_pyexit;
|
||||
|
||||
if (PyObject_CallMethod(gevent_hub, "switch", NULL)) {
|
||||
PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL);
|
||||
Py_INCREF(uwsgi_greenlet_signal);
|
||||
|
||||
PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL);
|
||||
Py_INCREF(uwsgi_greenlet_my_signal);
|
||||
|
||||
PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL);
|
||||
Py_INCREF(uwsgi_greenlet_signal_handler);
|
||||
|
||||
ugevent.signal_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler);
|
||||
|
||||
// start the two signal watchers
|
||||
if (!PyObject_CallMethod(signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit;
|
||||
if (!PyObject_CallMethod(my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit;
|
||||
|
||||
}
|
||||
|
||||
// start the main greenlet
|
||||
PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_main);
|
||||
|
||||
if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("the gevent Hub is no more :(\n");
|
||||
|
||||
@@ -71,6 +71,7 @@ struct uwsgi_help_item uwsgi_python_help[] = {
|
||||
{"file <file>", "use python file instead of python module for configuration"},
|
||||
{"eval <code>", "evaluate code for app configuration"},
|
||||
{"ini-paste <inifile>", "path of ini config file that contains paste configuration"},
|
||||
{"pyshell", "run a python interactive shell in the uwsgi environment (steals a worker)"},
|
||||
|
||||
|
||||
{ 0, 0},
|
||||
@@ -681,9 +682,11 @@ void init_uwsgi_embedded_module() {
|
||||
init_uwsgi_module_queue(new_uwsgi_module);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp) {
|
||||
init_uwsgi_module_snmp(new_uwsgi_module);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (up.extension) {
|
||||
up.extension();
|
||||
@@ -790,12 +793,12 @@ int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
|
||||
#ifdef UWSGI_INI
|
||||
case LONG_ARGS_INI_PASTE:
|
||||
uwsgi.ini = optarg;
|
||||
if (uwsgi.ini[0] != '/') {
|
||||
up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", uwsgi.ini);
|
||||
uwsgi_string_new_list(&uwsgi.ini,optarg);
|
||||
if (optarg[0] != '/') {
|
||||
up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", optarg);
|
||||
}
|
||||
else {
|
||||
up.paste = uwsgi_concat2("config:", uwsgi.ini);
|
||||
up.paste = uwsgi_concat2("config:", optarg);
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
@@ -852,7 +855,7 @@ char *uwsgi_pythonize(char *orig) {
|
||||
name[i] = '_';
|
||||
}
|
||||
else if (name[i] == '/') {
|
||||
name[i] = '.';
|
||||
name[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,7 +872,6 @@ void uwsgi_python_spooler_init(void) {
|
||||
|
||||
struct uwsgi_string_list *upli = up.spooler_import_list;
|
||||
|
||||
|
||||
UWSGI_GET_GIL
|
||||
|
||||
while(upli) {
|
||||
@@ -1211,6 +1213,7 @@ int uwsgi_python_signal_handler(uint8_t sig, void *handler) {
|
||||
ret = python_call(handler, args, 0, NULL);
|
||||
Py_DECREF(args);
|
||||
if (ret) {
|
||||
Py_DECREF(ret);
|
||||
UWSGI_RELEASE_GIL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -72,8 +72,9 @@ void init_pyargv() {
|
||||
up.py_argv[0] = "uwsgi";
|
||||
#endif
|
||||
|
||||
if (up.argv != NULL && !up.argc) {
|
||||
up.argc++;
|
||||
up.argc = 1;
|
||||
|
||||
if (up.argv != NULL) {
|
||||
#ifdef PYTHREE
|
||||
wchar_t *wcargv = malloc( sizeof( wchar_t ) * (strlen(up.argv)+1));
|
||||
if (!wcargv) {
|
||||
@@ -106,5 +107,16 @@ void init_pyargv() {
|
||||
|
||||
PySys_SetArgv(up.argc, up.py_argv);
|
||||
|
||||
PyObject *sys_dict = get_uwsgi_pydict("sys");
|
||||
if (!sys_dict) {
|
||||
uwsgi_log("unable to load python sys module !!!\n");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef PYTHREE
|
||||
PyDict_SetItemString(sys_dict, "executable", PyUnicode_FromString(uwsgi.binary_path));
|
||||
#else
|
||||
PyDict_SetItemString(sys_dict, "executable", PyString_FromString(uwsgi.binary_path));
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
||||
UWSGI_RELEASE_GIL;
|
||||
|
||||
pfd[0].fd = uwsgi.signal_socket;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = uwsgi.my_signal_socket;
|
||||
@@ -55,6 +58,7 @@ cycle:
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
else {
|
||||
|
||||
if (uwsgi_signal_handler(received_signal)) {
|
||||
uwsgi_log_verbose("error managing signal %d on worker %d\n", received_signal, uwsgi.mywid);
|
||||
}
|
||||
@@ -64,8 +68,11 @@ cycle:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UWSGI_GET_GIL;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
}
|
||||
#endif
|
||||
@@ -961,6 +968,18 @@ PyObject *py_uwsgi_log(PyObject * self, PyObject * args) {
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
|
||||
|
||||
// the spooler cannot lock resources
|
||||
@@ -2684,6 +2703,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""},
|
||||
{"recv_frame", py_uwsgi_recv_frame, METH_VARARGS, ""},
|
||||
{"close", py_uwsgi_close, METH_VARARGS, ""},
|
||||
{"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""},
|
||||
|
||||
{"fcgi", py_uwsgi_fcgi, METH_VARARGS, ""},
|
||||
|
||||
@@ -3217,6 +3237,7 @@ void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
PyObject *py_snmp_counter32(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t oid_num;
|
||||
@@ -3337,6 +3358,7 @@ void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) {
|
||||
|
||||
uwsgi_log( "SNMP python functions initialized.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -264,6 +264,8 @@ void uwsgi_python_reset_random_seed(void);
|
||||
|
||||
char *uwsgi_pythonize(char *);
|
||||
|
||||
#define uwsgi_pyexit {PyErr_Print();exit(1);}
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef PYTHREE
|
||||
int uwsgi_init_symbol_import(void);
|
||||
|
||||
@@ -27,7 +27,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
Py_DECREF(pydictvalue);
|
||||
}
|
||||
|
||||
|
||||
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
|
||||
wsgi_req->uh.modifier1 = 0;
|
||||
pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
|
||||
|
||||
+2
-1
@@ -355,7 +355,7 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
|
||||
exit(1);
|
||||
}
|
||||
else if (rlen == 0) {
|
||||
uwsgi_log( "timeout waiting for header. skip request.\n");
|
||||
uwsgi_log( "timeout. skip request.\n");
|
||||
//close(upoll->fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -766,6 +766,7 @@ next:
|
||||
wsgi_req->var_cnt++;
|
||||
script_name = wsgi_req->var_cnt;
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi_apps_cnt;i++) {
|
||||
//uwsgi_log("app mountpoint = %.*s\n", uwsgi_apps[i].mountpoint_len, uwsgi_apps[i].mountpoint);
|
||||
if (orig_path_info_len >= uwsgi_apps[i].mountpoint_len) {
|
||||
|
||||
@@ -474,7 +474,13 @@ socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *s
|
||||
sin_addr->sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
else {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
|
||||
char *resolved = uwsgi_resolve_ip(socket_name);
|
||||
if (resolved) {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(resolved);
|
||||
}
|
||||
else {
|
||||
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
|
||||
}
|
||||
}
|
||||
|
||||
return sizeof(struct sockaddr_in);
|
||||
|
||||
@@ -17,8 +17,10 @@ pid_t spooler_start() {
|
||||
int i;
|
||||
|
||||
if (uwsgi.master_process) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
|
||||
if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
|
||||
if (uwsgi.shared->spooler_signal_pipe[0] != -1) {close (uwsgi.shared->spooler_signal_pipe[0]); uwsgi.shared->spooler_signal_pipe[0] = -1;}
|
||||
if (!uwsgi.spooler_respawned) {
|
||||
if (uwsgi.shared->spooler_signal_pipe[1] != -1) {close (uwsgi.shared->spooler_signal_pipe[1]); uwsgi.shared->spooler_signal_pipe[1] = -1;}
|
||||
}
|
||||
// setup internal signalling system
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.shared->spooler_signal_pipe)) {
|
||||
uwsgi_error("socketpair()\n");
|
||||
@@ -36,7 +38,9 @@ pid_t spooler_start() {
|
||||
// USR1 will be used to wake up the spooler
|
||||
signal(SIGUSR1, spooler_wakeup);
|
||||
uwsgi.mywid = -1;
|
||||
uwsgi.mypid = pid;
|
||||
uwsgi.mypid = getpid();
|
||||
// avoid race conditions !!!
|
||||
uwsgi.shared->spooler_pid = uwsgi.mypid;
|
||||
uwsgi_close_all_sockets();
|
||||
if (uwsgi.master_process) {
|
||||
close(uwsgi.shared->spooler_signal_pipe[0]);
|
||||
@@ -52,7 +56,9 @@ pid_t spooler_start() {
|
||||
uwsgi.p[i]->post_fork();
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1];
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->spooler_init) {
|
||||
uwsgi.p[i]->spooler_init();
|
||||
@@ -64,6 +70,7 @@ pid_t spooler_start() {
|
||||
uwsgi.gp[i]->spooler_init();
|
||||
}
|
||||
}
|
||||
|
||||
spooler();
|
||||
}
|
||||
else if (pid > 0) {
|
||||
@@ -251,6 +258,8 @@ void spooler() {
|
||||
if (uwsgi.spooler_ordered) {
|
||||
#ifdef __linux__
|
||||
spooler_scandir(uwsgi.spool_dir);
|
||||
#else
|
||||
spooler_readdir(uwsgi.spool_dir);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@@ -362,7 +371,12 @@ void spooler_manage_task(char *dir, char *task) {
|
||||
if (!access(task, R_OK | W_OK)) {
|
||||
uwsgi_log("managing spool request %s ...\n", task);
|
||||
|
||||
#ifdef __sun__
|
||||
// lockf needs write permission
|
||||
spool_fd = open(task, O_RDWR);
|
||||
#else
|
||||
spool_fd = open(task, O_RDONLY);
|
||||
#endif
|
||||
if (spool_fd < 0) {
|
||||
uwsgi_error_open(task);
|
||||
return;
|
||||
|
||||
+24
-1
@@ -1,17 +1,39 @@
|
||||
import gevent
|
||||
import gevent.socket
|
||||
import sys
|
||||
import uwsgi
|
||||
from uwsgidecorators import *
|
||||
|
||||
if 'gettotalrefcount' in sys.__dict__:
|
||||
REFCNT = True
|
||||
else:
|
||||
REFCNT = False
|
||||
|
||||
@signal(17)
|
||||
def hello(signum):
|
||||
print "hello i am signal %d, i am here because the background job is finished" % signum
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
|
||||
@timer(10)
|
||||
def ten_seconds(signum):
|
||||
print "10 seconds elapsed, signal %d raised" % signum
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
|
||||
@filemon('/tmp')
|
||||
def tmp_modified(signum):
|
||||
print "/tmp has been touched, i am the greenlet %s running on worker %d" % (gevent.getcurrent(), uwsgi.worker_id())
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
|
||||
def bg_task():
|
||||
for i in range(1,10):
|
||||
print "background task", i
|
||||
gevent.sleep(2)
|
||||
gevent.sleep(1)
|
||||
|
||||
# task ended raise a signal !!!
|
||||
uwsgi.signal(17)
|
||||
|
||||
def long_task():
|
||||
for i in range(1,10):
|
||||
@@ -43,6 +65,7 @@ def application(e, sr):
|
||||
|
||||
if REFCNT:
|
||||
print sys.gettotalrefcount()
|
||||
yield "%d" % sys.gettotalrefcount()
|
||||
|
||||
# this task will goes on after request end
|
||||
gevent.spawn(bg_task)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import uwsgi
|
||||
|
||||
print(uwsgi.opt)
|
||||
print(uwsgi.magic_table)
|
||||
from werkzeug.testapp import test_app as application
|
||||
+48
-2
@@ -1,5 +1,19 @@
|
||||
import uuid
|
||||
import uwsgi
|
||||
import os
|
||||
|
||||
|
||||
def application(env, start_response):
|
||||
|
||||
if env['PATH_INFO'].startswith('/progress/'):
|
||||
start_response('200 Ok', [('Content-type', 'application/json')])
|
||||
filename = 'foobar/' + env['PATH_INFO'][10:]
|
||||
print filename
|
||||
if os.path.exists(filename):
|
||||
return uwsgi.sendfile(filename)
|
||||
else:
|
||||
return "{ 'state': 'done' }"
|
||||
|
||||
|
||||
if env['REQUEST_METHOD'] == 'POST':
|
||||
start_response('200 Ok', [('Content-type', 'text/plain')])
|
||||
@@ -14,12 +28,44 @@ def application(env, start_response):
|
||||
return body
|
||||
else:
|
||||
start_response('200 Ok', [('Content-type', 'text/html')])
|
||||
x_progress_id = str(uuid.uuid4())
|
||||
return """
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<html>
|
||||
<head>
|
||||
<script src="/static/jquery-1.5.1.min.js" /></script>
|
||||
<script language="Javascript">
|
||||
var interval;
|
||||
function redrawProgressBar() {
|
||||
interval = setInterval(getData, 1000);
|
||||
}
|
||||
|
||||
function getData() {
|
||||
var jsr = $.getJSON("/progress/%s.js",
|
||||
function(data) {
|
||||
if (data) {
|
||||
if (data.state == 'uploading') {
|
||||
$('#progress').html(data.received + '/' + data.size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
alert("fine");
|
||||
clearInterval(interval);
|
||||
}
|
||||
);
|
||||
jsr.error(function() { clearInterval(interval); });
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
upload progress: <div id="progress"> 0%%</div>
|
||||
<form method="POST" enctype="multipart/form-data" action="?X-Progress-ID=%s" onsubmit="redrawProgressBar(); return true;">
|
||||
<textarea name="pluto">
|
||||
</textarea>
|
||||
<input type="file" name="pippo" />
|
||||
<input type="submit" value="invia" />
|
||||
</form>
|
||||
"""
|
||||
</body>
|
||||
</html>
|
||||
""" % (x_progress_id, x_progress_id)
|
||||
|
||||
|
||||
@@ -195,7 +195,13 @@ void logto(char *logfile) {
|
||||
|
||||
udp_addr.sin_family = AF_INET;
|
||||
udp_addr.sin_port = htons(atoi(udp_port + 1));
|
||||
udp_addr.sin_addr.s_addr = inet_addr(logfile);
|
||||
char *resolved = uwsgi_resolve_ip(logfile);
|
||||
if (resolved) {
|
||||
udp_addr.sin_addr.s_addr = inet_addr(resolved);
|
||||
}
|
||||
else {
|
||||
udp_addr.sin_addr.s_addr = inet_addr(logfile);
|
||||
}
|
||||
|
||||
if (connect(fd, (const struct sockaddr *) &udp_addr, sizeof(struct sockaddr_in)) < 0) {
|
||||
uwsgi_error("connect()");
|
||||
@@ -433,10 +439,9 @@ void log_syslog(char *syslog_opts) {
|
||||
|
||||
char *uwsgi_get_cwd() {
|
||||
|
||||
int newsize = 256;
|
||||
char *cwd;
|
||||
size_t newsize = 256;
|
||||
|
||||
cwd = uwsgi_malloc(newsize);
|
||||
char *cwd = uwsgi_malloc(newsize);
|
||||
|
||||
if (getcwd(cwd, newsize) == NULL) {
|
||||
newsize = errno;
|
||||
@@ -1507,18 +1512,18 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
|
||||
}
|
||||
// manage buffered data and upload progress
|
||||
while (post_remains > 0) {
|
||||
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
}
|
||||
|
||||
ret = poll(&wsgi_req->poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] * 1000);
|
||||
ret = uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
|
||||
if (ret < 0) {
|
||||
uwsgi_error("poll()");
|
||||
goto end;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
uwsgi_log("buffering POST data timedout !!!\n");
|
||||
uwsgi_log("buffering POST data timed-out !!!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -1543,7 +1548,7 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
|
||||
goto end;
|
||||
}
|
||||
|
||||
// resue buf for json buffer
|
||||
// reuse buf for json buffer
|
||||
ret = snprintf(buf, len, "{ \"state\" : \"uploading\", \"received\" : %d, \"size\" : %d }\r\n", (int) (wsgi_req->post_cl - post_remains), (int) wsgi_req->post_cl);
|
||||
if (ret < 0) {
|
||||
uwsgi_log("unable to write JSON data in upload progress file %s\n", upload_progress_filename);
|
||||
@@ -2721,14 +2726,15 @@ char *uwsgi_get_binary_path(char *argvzero) {
|
||||
}
|
||||
free(buf);
|
||||
#elif defined(__sun__)
|
||||
// do not free this value !!!
|
||||
char *buf = (char *)getexecname();
|
||||
if (buf) {
|
||||
// return only absolute path
|
||||
if (buf[0] == '/') {
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *newbuf = realpath(buf, NULL);
|
||||
free(buf);
|
||||
if (newbuf) {
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ static struct option long_base_options[] = {
|
||||
{"single-interpreter", no_argument, 0, 'i'},
|
||||
{"master", no_argument, 0, 'M'},
|
||||
{"emperor", required_argument, 0, LONG_ARGS_EMPEROR},
|
||||
{"emperor-tyrant", no_argument, &uwsgi.emperor_tyrant, 1},
|
||||
{"early-emperor", no_argument, &uwsgi.early_emperor, 1},
|
||||
{"emperor-broodlord", required_argument, 0, LONG_ARGS_EMPEROR_BROODLORD},
|
||||
{"emperor-amqp-vhost", required_argument, 0, LONG_ARGS_EMPEROR_AMQP_VHOST},
|
||||
@@ -942,11 +943,13 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
//initialize embedded plugins
|
||||
UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
// now a bit of magic, if the argv[0] basename contains a 'uwsgi_' string,
|
||||
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
|
||||
// try to automatically load a plugin
|
||||
//uwsgi_log("executable name: %s\n", argv[0]);
|
||||
char *p = strrchr(argv[0], '/');
|
||||
if (p == NULL) p = argv[0];
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("executable name: %s\n", uwsgi.binary_path);
|
||||
#endif
|
||||
char *p = strrchr(uwsgi.binary_path, '/');
|
||||
if (p == NULL) p = uwsgi.binary_path;
|
||||
p = strstr(p, "uwsgi_");
|
||||
if (p != NULL) {
|
||||
plugins_requested = strchr(p, '_');
|
||||
@@ -965,6 +968,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
build_options();
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
@@ -972,7 +976,6 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
uwsgi.magic_table['v'] = uwsgi.cwd;
|
||||
uwsgi.magic_table['h'] = uwsgi.hostname;
|
||||
|
||||
@@ -1000,72 +1003,80 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi.option_index = -1;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("optind:%d argc:%d\n", optind,argc);
|
||||
#endif
|
||||
|
||||
if (optind < argc) {
|
||||
char *lazy = argv[optind];
|
||||
if (lazy[0] != '[') {
|
||||
if (0) {
|
||||
}
|
||||
for(i=optind;i<argc;i++) {
|
||||
char *lazy = argv[i];
|
||||
if (lazy[0] != '[') {
|
||||
if (0) {
|
||||
}
|
||||
|
||||
#ifdef UWSGI_XML
|
||||
else if (!strcmp(lazy + strlen(lazy) - 4, ".xml")) {
|
||||
uwsgi.xml_config = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 4, ".xml")) {
|
||||
uwsgi.xml_config = lazy;
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_INI
|
||||
else if (!strcmp(lazy + strlen(lazy) - 4, ".ini")) {
|
||||
uwsgi.ini = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 4, ".ini")) {
|
||||
uwsgi_string_new_list(&uwsgi.ini, lazy);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_YAML
|
||||
else if (!strcmp(lazy + strlen(lazy) - 4, ".yml")) {
|
||||
uwsgi.yaml = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 5, ".yaml")) {
|
||||
uwsgi.yaml = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 4, ".yml")) {
|
||||
uwsgi.yaml = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 5, ".yaml")) {
|
||||
uwsgi.yaml = lazy;
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_JSON
|
||||
else if (!strcmp(lazy + strlen(lazy) - 3, ".js")) {
|
||||
uwsgi.json = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 3, ".js")) {
|
||||
uwsgi.json = lazy;
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_SQLITE3
|
||||
else if (!strcmp(lazy + strlen(lazy) - 3, ".db")) {
|
||||
uwsgi.sqlite3 = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 7, ".sqlite")) {
|
||||
uwsgi.sqlite3 = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 8, ".sqlite3")) {
|
||||
uwsgi.sqlite3 = lazy;
|
||||
}
|
||||
#endif
|
||||
// manage magic mountpoint
|
||||
else if ((lazy[0] == '/' || strchr(lazy, '|')) && strchr(lazy, '=')) {
|
||||
}
|
||||
else {
|
||||
int magic = 0;
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->magic) {
|
||||
if (uwsgi.gp[i]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 3, ".db")) {
|
||||
uwsgi.sqlite3 = lazy;
|
||||
}
|
||||
if (!magic) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->magic) {
|
||||
if (uwsgi.p[i]->magic(NULL, lazy)) {
|
||||
else if (!strcmp(lazy + strlen(lazy) - 7, ".sqlite")) {
|
||||
uwsgi.sqlite3 = lazy;
|
||||
}
|
||||
else if (!strcmp(lazy + strlen(lazy) - 8, ".sqlite3")) {
|
||||
uwsgi.sqlite3 = lazy;
|
||||
}
|
||||
#endif
|
||||
// manage magic mountpoint
|
||||
else if ((lazy[0] == '/' || strchr(lazy, '|')) && strchr(lazy, '=')) {
|
||||
}
|
||||
else {
|
||||
int magic = 0;
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->magic) {
|
||||
if (uwsgi.gp[i]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!magic) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->magic) {
|
||||
if (uwsgi.p[i]->magic(NULL, lazy)) {
|
||||
magic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_string_list *config_file;
|
||||
|
||||
#ifdef UWSGI_XML
|
||||
if (uwsgi.xml_config != NULL) {
|
||||
@@ -1076,8 +1087,12 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
#endif
|
||||
#ifdef UWSGI_INI
|
||||
if (uwsgi.ini != NULL) {
|
||||
config_magic_table_fill(uwsgi.ini, uwsgi.magic_table);
|
||||
uwsgi_ini_config(uwsgi.ini, uwsgi.magic_table);
|
||||
config_file = uwsgi.ini;
|
||||
while(config_file) {
|
||||
config_magic_table_fill(config_file->value, uwsgi.magic_table);
|
||||
uwsgi_ini_config(config_file->value, uwsgi.magic_table);
|
||||
config_file = config_file->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_YAML
|
||||
@@ -1201,6 +1216,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
// ok, the options dictionary is available, lets manage it
|
||||
|
||||
|
||||
uwsgi_configure();
|
||||
|
||||
/* uWSGI IS CONFIGURED !!! */
|
||||
@@ -1445,7 +1461,7 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
if (!uwsgi.no_initial_output) {
|
||||
if (!uwsgi.master_process) {
|
||||
uwsgi_log(" *** WARNING: you are running uWSGI without its master process manager ***\n");
|
||||
uwsgi_log("*** WARNING: you are running uWSGI without its master process manager ***\n");
|
||||
}
|
||||
}
|
||||
#ifndef __OpenBSD__
|
||||
@@ -2582,9 +2598,11 @@ void uwsgi_ignition() {
|
||||
uwsgi_log("unavailable loop engine !!!\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("running %s loop %p\n", uwsgi.loop, u_loop);
|
||||
if (uwsgi.mywid == 1) {
|
||||
uwsgi_log("*** running %s loop engine [addr:%p] ***\n", uwsgi.loop, u_loop);
|
||||
}
|
||||
u_loop();
|
||||
uwsgi_log("done\n");
|
||||
uwsgi_log("your loop engine died. R.I.P.\n");
|
||||
}
|
||||
else {
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
@@ -3094,7 +3112,7 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
#endif
|
||||
#ifdef UWSGI_INI
|
||||
case LONG_ARGS_INI:
|
||||
uwsgi.ini = optarg;
|
||||
uwsgi_string_new_list(&uwsgi.ini, optarg);
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_SOCKET_PROTOCOL:
|
||||
@@ -3473,10 +3491,11 @@ void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) {
|
||||
void build_options() {
|
||||
int i;
|
||||
struct option *lopt, *aopt;
|
||||
int opt_count = count_options(long_base_options);
|
||||
int short_opt_size = strlen(base_short_options);
|
||||
char *so_ptr;
|
||||
|
||||
int opt_count = count_options(long_base_options);
|
||||
size_t short_opt_size = strlen(base_short_options);
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->short_options) {
|
||||
short_opt_size += strlen(uwsgi.p[i]->short_options);
|
||||
@@ -3489,9 +3508,12 @@ void build_options() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (short_options) {
|
||||
free(short_options);
|
||||
}
|
||||
|
||||
|
||||
short_options = uwsgi_malloc(short_opt_size + 1);
|
||||
memcpy(short_options, base_short_options, strlen(base_short_options));
|
||||
so_ptr = short_options + strlen(base_short_options);
|
||||
@@ -3907,6 +3929,20 @@ struct uwsgi_help_item main_help[] = {
|
||||
{"version", "print server version"},
|
||||
{"attach-daemon <command>", "run <command> under the control of master process"},
|
||||
{"daemonize <logfile|addr>", "daemonize and log into <logfile> or udp <addr>"},
|
||||
{"loop <engine>", "use the <engine> loop engine"},
|
||||
{"worker-exec <command>", "execve() <command> after each worker's fork()"},
|
||||
{"autoload", "try to automatically load plugins"},
|
||||
{"lazy", "load applications after each worker's fork()"},
|
||||
{"cheap", "postpone workers startup until the first request"},
|
||||
{"idle <secs>", "destroy workers (the server will go in cheap mode) after <secs> of inactivity"},
|
||||
{"freebind (Linux only)", "allows binding on non-existent network address"},
|
||||
{"xml <file>", "load config from an xml file"},
|
||||
{"protocol <proto>", "set the default communication protocol (uwsgi, http, fastcgi)"},
|
||||
{"reuse-port (BSD only)", "allows multiple instances bining on the same address"},
|
||||
{"set KEY=VALUE", "set a placeholder"},
|
||||
{"reload-mercy <secs>", "brutally kill workers not reloading in <secs>"},
|
||||
{"emperor <dir|glob>", "start the emperor monitoring <dir|glob>"},
|
||||
{"touch-reload <file>", "issue a graceful reload on <file> modifications/touch"},
|
||||
|
||||
{0, 0},
|
||||
|
||||
|
||||
@@ -934,6 +934,7 @@ struct uwsgi_server {
|
||||
|
||||
int has_emperor;
|
||||
int emperor_fd;
|
||||
int emperor_tyrant;
|
||||
int emperor_fd_config;
|
||||
int early_emperor;
|
||||
int emperor_throttle;
|
||||
@@ -1068,6 +1069,7 @@ struct uwsgi_server {
|
||||
#ifdef UWSGI_SPOOLER
|
||||
char *spool_dir;
|
||||
int spooler_ordered;
|
||||
uint64_t spooler_respawned;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
@@ -1172,7 +1174,7 @@ struct uwsgi_server {
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_INI
|
||||
char *ini;
|
||||
struct uwsgi_string_list *ini;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SQLITE3
|
||||
|
||||
+51
-11
@@ -25,6 +25,8 @@ GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
|
||||
if not GCC:
|
||||
GCC = 'gcc'
|
||||
|
||||
CPP = os.environ.get('CPP', 'cpp')
|
||||
|
||||
binary_list = []
|
||||
|
||||
def binarize(name):
|
||||
@@ -57,6 +59,16 @@ def spcall2(cmd):
|
||||
else:
|
||||
return None
|
||||
|
||||
def spcall3(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdin=open('/dev/null'), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
|
||||
if p.wait() == 0:
|
||||
if sys.version_info[0] > 2:
|
||||
return p.stderr.read().rstrip().decode()
|
||||
return p.stderr.read().rstrip()
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def add_o(x):
|
||||
if x == 'uwsgi':
|
||||
@@ -100,7 +112,7 @@ def build_uwsgi(uc):
|
||||
epc = "-DUWSGI_DECLARE_EMBEDDED_PLUGINS=\""
|
||||
eplc = "-DUWSGI_LOAD_EMBEDDED_PLUGINS=\""
|
||||
for p in ep:
|
||||
p = p.rstrip().lstrip()
|
||||
p = p.strip()
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
continue
|
||||
@@ -125,7 +137,7 @@ def build_uwsgi(uc):
|
||||
if len(ep) > 0:
|
||||
print("*** uWSGI compiling embedded plugins ***")
|
||||
for p in ep:
|
||||
p = p.rstrip().lstrip()
|
||||
p = p.strip()
|
||||
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
@@ -160,7 +172,7 @@ def build_uwsgi(uc):
|
||||
print("*** uWSGI building plugins ***")
|
||||
|
||||
for p in plugins:
|
||||
p = p.rstrip().lstrip()
|
||||
p = p.strip()
|
||||
print("*** building plugin: %s ***" % p)
|
||||
build_plugin("plugins/%s" % p, uc, cflags, ldflags, libs)
|
||||
|
||||
@@ -203,15 +215,37 @@ class uConf(object):
|
||||
self.gcc_list.append('proto/uwsgi')
|
||||
self.gcc_list.append('proto/http')
|
||||
self.gcc_list.append('proto/fastcgi')
|
||||
self.include_path = []
|
||||
if uwsgi_os == 'Linux':
|
||||
self.gcc_list.append('lib/linux_ns')
|
||||
self.gcc_list.append('lib/netlink')
|
||||
self.cflags = ['-O2', '-Wall', '-Werror', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] + os.environ.get("CFLAGS", "").split()
|
||||
|
||||
try:
|
||||
gcc_version = str(spcall("%s -dumpversion" % GCC))
|
||||
except:
|
||||
print("*** you need a c compiler to build uWSGI ***")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
add_it = False
|
||||
cpp_include_list = str(spcall3("%s -v" % CPP)).split("\n")
|
||||
for line in cpp_include_list:
|
||||
if line.startswith('#include <...> search starts here:'):
|
||||
add_it = True
|
||||
elif line.startswith('End of search list.'):
|
||||
add_it = False
|
||||
elif add_it:
|
||||
self.include_path.append(line.strip().split()[0])
|
||||
|
||||
if not self.include_path:
|
||||
raise
|
||||
except:
|
||||
self.include_path = ['/usr/include', '/usr/local/include']
|
||||
|
||||
|
||||
print("detected include path: %s" % self.include_path)
|
||||
|
||||
gcc_major = int(gcc_version.split('.')[0])
|
||||
gcc_minor = int(gcc_version.split('.')[1])
|
||||
if (sys.version_info[0] == 2) or (gcc_major < 4) or (gcc_major == 4 and gcc_minor < 3):
|
||||
@@ -266,6 +300,12 @@ class uConf(object):
|
||||
print("%s needs %s support." % (what, d))
|
||||
sys.exit(1)
|
||||
|
||||
def has_include(self, what):
|
||||
for include in self.include_path:
|
||||
if os.path.exists("%s/%s" %(include, what)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_gcll(self):
|
||||
|
||||
global uwsgi_version
|
||||
@@ -273,7 +313,7 @@ class uConf(object):
|
||||
self.cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
|
||||
kvm_list = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly']
|
||||
|
||||
if os.path.exists('/usr/include/ifaddrs.h') or os.path.exists('/usr/local/include/ifaddrs.h'):
|
||||
if self.has_include('ifaddrs.h'):
|
||||
self.cflags.append('-DUWSGI_HAS_IFADDRS')
|
||||
|
||||
if uwsgi_os == 'SunOS':
|
||||
@@ -369,7 +409,7 @@ class uConf(object):
|
||||
|
||||
if timer_mode == 'timerfd':
|
||||
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_TIMERFD')
|
||||
if not os.path.exists('/usr/include/sys/timerfd.h') and not os.path.exists('/usr/local/include/sys/timerfd.h'):
|
||||
if not self.has_include('sys/timerfd.h'):
|
||||
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_TIMERFD_NOINC')
|
||||
elif timer_mode == 'kqueue':
|
||||
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_KQUEUE')
|
||||
@@ -445,7 +485,7 @@ class uConf(object):
|
||||
has_json = False
|
||||
has_uuid = False
|
||||
|
||||
if os.path.exists('/usr/include/uuid/uuid.h') or os.path.exists('/usr/local/include/uuid/uuid.h'):
|
||||
if self.has_include('uuid/uuid.h'):
|
||||
has_uuid = True
|
||||
self.cflags.append("-DUWSGI_UUID")
|
||||
if os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
|
||||
@@ -550,7 +590,7 @@ class uConf(object):
|
||||
self.cflags.append("-DUWSGI_LIBYAML")
|
||||
self.libs.append('-lyaml')
|
||||
if self.get('yaml_implementation') == 'auto':
|
||||
if os.path.exists('/usr/include/yaml.h') or os.path.exists('/usr/local/include/yaml.h'):
|
||||
if self.has_include('yaml.h'):
|
||||
self.cflags.append("-DUWSGI_LIBYAML")
|
||||
self.libs.append('-lyaml')
|
||||
|
||||
@@ -563,7 +603,7 @@ class uConf(object):
|
||||
self.gcc_list.append('json')
|
||||
self.libs.append(spcall("pkg-config --libs jansson"))
|
||||
has_json = True
|
||||
elif os.path.exists('/usr/include/jansson.h') or os.path.exists('/usr/local/include/jansson.h'):
|
||||
elif self.has_include('jansson.h'):
|
||||
self.cflags.append("-DUWSGI_JSON")
|
||||
self.gcc_list.append('json')
|
||||
self.libs.append('-ljansson')
|
||||
@@ -576,7 +616,7 @@ class uConf(object):
|
||||
|
||||
if self.get('ldap'):
|
||||
if self.get('ldap') == 'auto':
|
||||
if os.path.exists('/usr/include/ldap.h'):
|
||||
if self.has_include('ldap.h'):
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
@@ -587,7 +627,7 @@ class uConf(object):
|
||||
|
||||
if has_uuid and self.get('zeromq'):
|
||||
if self.get('zeromq') == 'auto':
|
||||
if os.path.exists('/usr/include/zmq.h') or os.path.exists('/usr/local/include/zmq.h'):
|
||||
if self.has_include('zmq.h'):
|
||||
self.cflags.append("-DUWSGI_ZEROMQ")
|
||||
self.gcc_list.append('proto/zeromq')
|
||||
self.libs.append('-lzmq')
|
||||
@@ -635,7 +675,7 @@ class uConf(object):
|
||||
|
||||
if self.get('sqlite3'):
|
||||
if self.get('sqlite3') == 'auto':
|
||||
if os.path.exists('/usr/include/sqlite3.h') or os.path.exists('/usr/local/include/sqlite3.h'):
|
||||
if self.has_include('sqlite3.h'):
|
||||
self.cflags.append("-DUWSGI_SQLITE3")
|
||||
self.libs.append('-lsqlite3')
|
||||
self.gcc_list.append('sqlite3')
|
||||
|
||||
@@ -153,6 +153,9 @@ class lock(object):
|
||||
self.f = f
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
# ensure the spooler will not call it
|
||||
if uwsgi.i_am_the_spooler():
|
||||
return
|
||||
uwsgi.lock()
|
||||
try:
|
||||
return self.f(*args, **kwargs)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[uwsgi]
|
||||
socket = :3031
|
||||
socket = /tmp/uwsgi_welcome.socket
|
||||
vacuum = true
|
||||
module = welcome
|
||||
master = true
|
||||
processes = 4
|
||||
mount = /werkzeug=tests/werkzeug.py
|
||||
manage-script-name = true
|
||||
Reference in New Issue
Block a user