mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9746759c68 | ||
|
|
170ee2b98a | ||
|
|
938fb777dd | ||
|
|
33e1aafcd1 | ||
|
|
597ee90041 | ||
|
|
e87e54ea28 | ||
|
|
5c64c1ac3f | ||
|
|
c611cbc2ca | ||
|
|
9d051f4171 | ||
|
|
6aee788678 | ||
|
|
425a45caa7 | ||
|
|
0571601e02 | ||
|
|
c1992c8c7a | ||
|
|
bd913870c7 | ||
|
|
7a479dd47f | ||
|
|
7ae77aa58d | ||
|
|
97a4260d44 | ||
|
|
b90d711764 | ||
|
|
22de5b523e | ||
|
|
5798b824c0 | ||
|
|
4cbf6cfc33 | ||
|
|
8b55460156 | ||
|
|
a61d48a451 | ||
|
|
b9f4d57d67 | ||
|
|
92cd36d14d |
@@ -13,3 +13,7 @@ ef31fc61ac48018c464f28ebfdf865b96bf83f18 0.9.6.2
|
||||
ff4111eb8f55b958ec91c70163e10f3372a9b94d 0.9.7-rc1
|
||||
eb8aff2926230bb114fb90f67203440a2c534bf1 0.9.7-rc2
|
||||
311eef929ec8fd0a5dc8c16531afb7bb42d36d01 0.9.7-rc3
|
||||
4b50c04e414f1d9ab8b0b5910aba83d09ac21abb 0.9.7
|
||||
d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
|
||||
d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
|
||||
0000000000000000000000000000000000000000 0.9.7.1
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
*** march 2011 ***
|
||||
|
||||
* 0.9.7.1 [20110326]
|
||||
|
||||
- fixed python stackless support
|
||||
- added persistence for queue
|
||||
- forbid daemonizing in vassal mode
|
||||
- modifier1 30 is available again
|
||||
- allow python modules to be mapped/aliased via http
|
||||
- added --pidfile2 and --logfile-chown
|
||||
- added UWSGI_CACHE_GET dynamic variable
|
||||
- 304/If-Modified-Since support for --check-static
|
||||
- option --check-cache for integrated caching
|
||||
- option --map-socket to assign specific workers to socket
|
||||
- fixed unix fd passing on older OSX versions
|
||||
- fixed post-buffering without pep3333-input
|
||||
- fixed python threading without uwsgi cores
|
||||
- support for Linux network namespace
|
||||
- build with sys.abiflags if necessary
|
||||
|
||||
|
||||
* 0.9.7 [20110317]
|
||||
|
||||
- fixed psgi compilation on GNU systems
|
||||
- improved --pep3333-input
|
||||
- better error reporting on failed open/fopen
|
||||
- fixed uGreen
|
||||
- added greenlet support
|
||||
- various solaris fixes
|
||||
- new help system
|
||||
- updated async support
|
||||
- fixed uwsgi.cache_get in python
|
||||
|
||||
* 0.9.7-rc3 [20110312]
|
||||
|
||||
- added support for persistent cache (--cache-store <filename>)
|
||||
|
||||
@@ -320,6 +320,7 @@ void *async_loop(void *arg1) {
|
||||
uwsgi.wsgi_req = current_request->wsgi_req;
|
||||
|
||||
uwsgi.schedule_to_req();
|
||||
uwsgi.wsgi_req->switches++;
|
||||
|
||||
next_async_request = current_request->next;
|
||||
// request ended ?
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[uwsgi]
|
||||
inherit = default
|
||||
plugin_dir = /usr/lib/uwsgi
|
||||
embedded_plugins = null
|
||||
@@ -337,6 +337,12 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.queue_store && uwsgi.queue_filesize) {
|
||||
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
//uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc);
|
||||
|
||||
@@ -950,6 +956,12 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((master_cycles % uwsgi.queue_store_sync) == 0)) {
|
||||
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1040,7 +1052,9 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log( "DAMN ! process %d died :( trying respawn ...\n", diedpid);
|
||||
if (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
uwsgi_log( "DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int)diedpid);
|
||||
}
|
||||
gettimeofday(&last_respawn, NULL);
|
||||
if (last_respawn.tv_sec == uwsgi.respawn_delta) {
|
||||
uwsgi_log( "worker respawning too fast !!! i have to sleep a bit...\n");
|
||||
@@ -1075,28 +1089,9 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "Respawned uWSGI worker (new pid: %d)\n", pid);
|
||||
//close(uwsgi.workers[uwsgi.mywid].pipe[1]);
|
||||
//event_queue_add_fd_read(uwsgi.master_queue, uwsgi.workers[uwsgi.mywid].pipe[0]);
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mywid <= 0 && diedpid != uwsgi.shared->spooler_pid) {
|
||||
#else
|
||||
if (uwsgi.mywid <= 0) {
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_PROXY
|
||||
// TODO if no gateway span the error !!!
|
||||
if (diedpid != uwsgi.shared->proxy_pid) {
|
||||
#endif
|
||||
uwsgi_log( "warning the died pid was not in the workers list. Probably you hit a BUG of uWSGI\n");
|
||||
#ifdef UWSGI_PROXY
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log( "Respawned uWSGI worker %d (new pid: %d)\n", uwsgi.mywid, (int) pid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
[uwsgi]
|
||||
|
||||
; socket 0
|
||||
socket = :3033
|
||||
; socket 1
|
||||
socket = :3034
|
||||
vacuum = true
|
||||
; socket 2
|
||||
socket = pippo1.sock
|
||||
; socket 3
|
||||
socket = pippo2.sock
|
||||
; socket 4
|
||||
socket = 127.0.0.1:1717
|
||||
|
||||
map-socket = 0:1,2,3,4
|
||||
map-socket = 1:4
|
||||
map-socket = 2:10
|
||||
map-socket = 3:5,6,9
|
||||
map-socket = 4:7,8,9
|
||||
|
||||
|
||||
vacuum = true
|
||||
memory-report = true
|
||||
master = true
|
||||
processes = 10
|
||||
mount = /app1=werkzeug.testapp:test_app
|
||||
mount = /app2=config:/Users/roberta/uwsgi/my.ini
|
||||
mount = /app3=pinaxsite/deploy/pinax.wsgi
|
||||
;mount = /app1=werkzeug.testapp:test_app
|
||||
;mount = /app2=config:/Users/roberta/uwsgi/my.ini
|
||||
;mount = /app3=pinaxsite/deploy/pinax.wsgi
|
||||
|
||||
@@ -879,6 +879,11 @@ int http_init() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_help_item http_help[] = {
|
||||
{ "http-to <addr>", "forward http requests to uwsgi instance bound at <addr>"},
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
int http_opt(int i, char *optarg) {
|
||||
|
||||
@@ -931,6 +936,7 @@ struct uwsgi_plugin http_plugin = {
|
||||
|
||||
.options = http_options,
|
||||
.manage_opt = http_opt,
|
||||
.help = http_help,
|
||||
.init = http_init,
|
||||
};
|
||||
|
||||
|
||||
@@ -149,6 +149,14 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
wi->interpreter = up.main_thread;
|
||||
}
|
||||
|
||||
if (wsgi_req->touch_reload_len) {
|
||||
struct stat trst;
|
||||
char *touch_reload = uwsgi_strncopy(wsgi_req->touch_reload, wsgi_req->touch_reload_len);
|
||||
if (!stat(touch_reload, &trst)) {
|
||||
wi->touch_reload = touch_reload;
|
||||
wi->touch_reload_mtime = trst.st_mtime;
|
||||
}
|
||||
}
|
||||
|
||||
wi->callable = up.loaders[loader](arg1);
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ struct uwsgi_help_item uwsgi_python_help[] = {
|
||||
{"module <module>" ,"name of python config module"},
|
||||
{"optimize <n>", "set python optimization level to <n>"},
|
||||
{"home <path>", "set python home/virtualenv"},
|
||||
{"pyhome <path>", "set python home/virtualenv"},
|
||||
{"virtualenv <path>", "set python home/virtualenv"},
|
||||
{"venv <path>", "set python home/virtualenv"},
|
||||
{"callable <callable>", "set the callable (default 'application')"},
|
||||
{"paste <config:/egg:>", "load applications using paste.deploy.loadapp()"},
|
||||
{"pythonpath <dir>", "add <dir> to PYTHONPATH"},
|
||||
@@ -127,6 +130,9 @@ int uwsgi_python_init() {
|
||||
|
||||
uwsgi_log("Python main interpreter initialized at %p\n", up.main_thread);
|
||||
|
||||
// add the hacky modifier1 30
|
||||
uwsgi.p[30]->request = uwsgi.p[0]->request;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
@@ -179,36 +185,52 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
char *real_filename = filename;
|
||||
|
||||
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_log("failed to open python file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(filename, "http://", 7)) {
|
||||
|
||||
if (fstat(fileno(pyfile), &pystat)) {
|
||||
uwsgi_error("fstat()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (S_ISDIR(pystat.st_mode)) {
|
||||
is_a_package = 1;
|
||||
fclose(pyfile);
|
||||
real_filename = uwsgi_concat2(filename, "/__init__.py");
|
||||
pyfile = fopen(real_filename, "r");
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_error_open(real_filename);
|
||||
uwsgi_log("failed to open python file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
py_file_node = PyParser_SimpleParseFile(pyfile, real_filename, Py_file_input);
|
||||
if (!py_file_node) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("failed to parse file %s\n", real_filename);
|
||||
exit(1);
|
||||
}
|
||||
if (fstat(fileno(pyfile), &pystat)) {
|
||||
uwsgi_error("fstat()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(pyfile);
|
||||
if (S_ISDIR(pystat.st_mode)) {
|
||||
is_a_package = 1;
|
||||
fclose(pyfile);
|
||||
real_filename = uwsgi_concat2(filename, "/__init__.py");
|
||||
pyfile = fopen(real_filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_error_open(real_filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
py_file_node = PyParser_SimpleParseFile(pyfile, real_filename, Py_file_input);
|
||||
if (!py_file_node) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("failed to parse file %s\n", real_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(pyfile);
|
||||
}
|
||||
else {
|
||||
int pycontent_size = 0;
|
||||
char *pycontent = uwsgi_open_and_read(filename, &pycontent_size, 1, NULL);
|
||||
|
||||
if (pycontent) {
|
||||
py_file_node = PyParser_SimpleParseString(pycontent, Py_file_input);
|
||||
if (!py_file_node) {
|
||||
PyErr_Print();
|
||||
uwsgi_log("failed to parse url %s\n", real_filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
py_compiled_node = (PyObject *) PyNode_Compile(py_file_node, real_filename);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ extern struct uwsgi_python up;
|
||||
|
||||
int manage_python_response(struct wsgi_request *wsgi_req) {
|
||||
// use standard WSGI response parse
|
||||
wsgi_req->switches++;
|
||||
return uwsgi_response_subhandler_wsgi(wsgi_req);
|
||||
}
|
||||
|
||||
|
||||
@@ -2528,7 +2528,6 @@ PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
if (uwsgi.queue_size) {
|
||||
uwsgi_log("locking queue\n");
|
||||
uwsgi_wlock(uwsgi.queue_lock);
|
||||
if (uwsgi_queue_push(message, msglen)) {
|
||||
Py_INCREF(Py_True);
|
||||
@@ -2539,7 +2538,6 @@ PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
|
||||
res = Py_None;
|
||||
}
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
uwsgi_log("unlocked queue\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2611,6 +2609,56 @@ PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
|
||||
|
||||
long num = 0;
|
||||
uint64_t size = 0;
|
||||
char *message;
|
||||
PyObject *res, *zero;
|
||||
uint64_t base;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l:queue_last", &num)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi.queue_size) {
|
||||
res = PyList_New(0);
|
||||
uwsgi_rlock(uwsgi.queue_lock);
|
||||
if (uwsgi.shared->queue_pos > 0) {
|
||||
base = uwsgi.shared->queue_pos-1;
|
||||
}
|
||||
else {
|
||||
base = uwsgi.queue_size-1;
|
||||
}
|
||||
if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
|
||||
while(num) {
|
||||
message = uwsgi_queue_get(base, &size);
|
||||
if (message && size) {
|
||||
zero = PyString_FromStringAndSize(message, size);
|
||||
PyList_Append(res, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
else {
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
return res;
|
||||
}
|
||||
if (base > 0) {
|
||||
base--;
|
||||
}
|
||||
else {
|
||||
base = uwsgi.queue_size-1;
|
||||
}
|
||||
num--;
|
||||
}
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
|
||||
char *key;
|
||||
@@ -2676,6 +2724,7 @@ static PyMethodDef uwsgi_cache_methods[] = {
|
||||
|
||||
static PyMethodDef uwsgi_queue_methods[] = {
|
||||
{"queue_get", py_uwsgi_queue_get, METH_VARARGS, ""},
|
||||
{"queue_last", py_uwsgi_queue_last, METH_VARARGS, ""},
|
||||
{"queue_push", py_uwsgi_queue_push, METH_VARARGS, ""},
|
||||
{"queue_pull", py_uwsgi_queue_pull, METH_VARARGS, ""},
|
||||
{"queue_slot", py_uwsgi_queue_slot, METH_VARARGS, ""},
|
||||
|
||||
@@ -20,10 +20,12 @@ else:
|
||||
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
|
||||
|
||||
|
||||
version = sys.version_info
|
||||
uver = "%d.%d" % (version[0], version[1])
|
||||
|
||||
LIBS.append('-lpython' + uver)
|
||||
version = sysconfig.get_config_var('VERSION')
|
||||
try:
|
||||
version = version + sys.abiflags
|
||||
except:
|
||||
pass
|
||||
LIBS.append('-lpython' + version)
|
||||
|
||||
#if str(PYLIB_PATH) != '':
|
||||
# libs.insert(0,'-L' + PYLIB_PATH)
|
||||
|
||||
@@ -262,7 +262,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
uwsgi_log("Invalid WSGI request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -429,6 +428,9 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wsgi_req->async_post = fdopen(wsgi_req->poll.fd, "r");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// read to disk if post_cl > post_buffering
|
||||
@@ -472,11 +474,15 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
while (wi->response_subhandler(wsgi_req) != UWSGI_OK) {
|
||||
wsgi_req->switches++;
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi.async > 1) {
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
wsgi_req->switches++;
|
||||
#ifdef UWSGI_ASYNC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[2].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[2].iov_len;
|
||||
wsgi_req->status = atoi(wsgi_req->hvec[2].iov_base);
|
||||
wsgi_req->status = uwsgi_str3_num(wsgi_req->hvec[2].iov_base);
|
||||
wsgi_req->hvec[3].iov_base = nl;
|
||||
wsgi_req->hvec[3].iov_len = NL_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[3].iov_len;
|
||||
@@ -87,7 +87,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[1].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[1].iov_len;
|
||||
wsgi_req->status = atoi(wsgi_req->hvec[1].iov_base);
|
||||
wsgi_req->status = uwsgi_str3_num(wsgi_req->hvec[1].iov_base);
|
||||
wsgi_req->hvec[2].iov_base = nl;
|
||||
wsgi_req->hvec[2].iov_len = NL_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[2].iov_len;
|
||||
|
||||
@@ -94,14 +94,12 @@ VALUE protected_fiber_loop() {
|
||||
if (!wsgi_req) goto cycle;
|
||||
uwsgi_log("request passed to fiber core %d\n", wsgi_req->async_id);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
uwsgi.wsgi_req->switches++;
|
||||
rb_fiber_resume(fiber_list[wsgi_req->async_id], 0, NULL);
|
||||
}
|
||||
else {
|
||||
wsgi_req = find_wsgi_req_by_fd((int)uwsgi.async_events[i].ASYNC_FD, -1);
|
||||
if (wsgi_req) {
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
uwsgi.wsgi_req->switches++;
|
||||
rb_fiber_resume(fiber_list[wsgi_req->async_id], 0, NULL);
|
||||
}
|
||||
else {
|
||||
@@ -116,7 +114,6 @@ cycle:
|
||||
|
||||
//uwsgi_log("resuming fiber %d %p\n", current, fiber_list[current]);
|
||||
uwsgi.wsgi_req = uwsgi.wsgi_requests[current];
|
||||
uwsgi.wsgi_req->switches++;
|
||||
if (uwsgi.wsgi_req->async_status != UWSGI_ACCEPTING) {
|
||||
uwsgi_log("passing control to fiber %d\n", current);
|
||||
rb_fiber_resume(fiber_list[current], 0, NULL);
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "../python/uwsgi_python.h"
|
||||
#include <stackless_api.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct ustackless {
|
||||
int enabled;
|
||||
PyObject *callable;
|
||||
PyTaskletObject **sl;
|
||||
} usl;
|
||||
|
||||
struct option stackless_options[] = {
|
||||
{"stackless", no_argument, &usl.enabled, 1},
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
PyObject *py_uwsgi_stackless_request(PyObject * self, PyObject *args) {
|
||||
|
||||
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req);
|
||||
uwsgi.wsgi_req->suspended = 0;
|
||||
|
||||
Py_DECREF(usl.sl[uwsgi.wsgi_req->async_id]);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_stackless_request_method[] = {{"uwsgi_stackless_request", py_uwsgi_stackless_request, METH_VARARGS, ""}};
|
||||
|
||||
inline static void stackless_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
if (!uwsgi.wsgi_req->suspended) {
|
||||
usl.sl[id] = PyTasklet_New(NULL, usl.callable);
|
||||
PyObject *args = PyTuple_New(0);
|
||||
PyTasklet_Setup(usl.sl[id], args, NULL);
|
||||
Py_DECREF(args);
|
||||
uwsgi.wsgi_req->suspended = 1;
|
||||
}
|
||||
|
||||
PyTasklet_Run(usl.sl[id]);
|
||||
|
||||
if (uwsgi.wsgi_req->suspended) {
|
||||
uwsgi.wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline static void stackless_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyStackless_Schedule(Py_None, 1);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
}
|
||||
|
||||
|
||||
int stackless_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stackless_init_apps(void) {
|
||||
|
||||
if (!usl.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
usl.sl = uwsgi_malloc( sizeof(PyTaskletObject *) * uwsgi.async );
|
||||
usl.callable = PyCFunction_New(uwsgi_stackless_request_method, NULL);
|
||||
uwsgi_log("enabled stackless engine\n");
|
||||
uwsgi.schedule_to_main = stackless_schedule_to_main;
|
||||
uwsgi.schedule_to_req = stackless_schedule_to_req;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_plugin stackless_plugin = {
|
||||
|
||||
.name = "stackless",
|
||||
.init = stackless_init,
|
||||
.init_apps = stackless_init_apps,
|
||||
.options = stackless_options,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
from distutils import sysconfig
|
||||
|
||||
NAME='stackless'
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['stackless']
|
||||
+177
-9
@@ -16,6 +16,112 @@ static size_t get_content_length(char *buf, uint16_t size) {
|
||||
return val;
|
||||
}
|
||||
|
||||
void set_http_date(time_t t, char *dst) {
|
||||
|
||||
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static char *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr",
|
||||
"May", "Jun", "Jul", "Aug",
|
||||
"Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
struct tm *hdtm = gmtime(&t);
|
||||
snprintf(dst, 49, "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\r\n",
|
||||
week[hdtm->tm_wday], hdtm->tm_mday,
|
||||
months[hdtm->tm_mon], hdtm->tm_year+1900,
|
||||
hdtm->tm_hour, hdtm->tm_min, hdtm->tm_sec);
|
||||
}
|
||||
|
||||
// only RFC 1123 is supported
|
||||
time_t parse_http_date(char *date, uint16_t len) {
|
||||
|
||||
struct tm hdtm;
|
||||
|
||||
if (len != 29 && date[3] != ',') return 0;
|
||||
|
||||
hdtm.tm_mday = uwsgi_str2_num(date+5);
|
||||
|
||||
switch(date[8]) {
|
||||
case 'J':
|
||||
if (date[9] == 'a') {
|
||||
hdtm.tm_mon = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (date[9] == 'u') {
|
||||
if (date[10] == 'n') {
|
||||
hdtm.tm_mon = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
if (date[10] == 'l') {
|
||||
hdtm.tm_mon = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case 'F':
|
||||
hdtm.tm_mon = 1;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (date[9] != 'a') return 0;
|
||||
|
||||
if (date[10] == 'r') {
|
||||
hdtm.tm_mon = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (date[10] == 'y') {
|
||||
hdtm.tm_mon = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case 'A':
|
||||
if (date[10] == 'r') {
|
||||
hdtm.tm_mon = 3;
|
||||
break;
|
||||
}
|
||||
if (date[10] == 'g') {
|
||||
hdtm.tm_mon = 7;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case 'S':
|
||||
hdtm.tm_mon = 8;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
hdtm.tm_mon = 9;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
hdtm.tm_mon = 10;
|
||||
|
||||
case 'D':
|
||||
hdtm.tm_mon = 11;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdtm.tm_year = uwsgi_str4_num(date+12)-1900;
|
||||
|
||||
hdtm.tm_hour = uwsgi_str2_num(date+17);
|
||||
hdtm.tm_min = uwsgi_str2_num(date+20);
|
||||
hdtm.tm_sec = uwsgi_str2_num(date+23);
|
||||
|
||||
return timegm(&hdtm);
|
||||
|
||||
}
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
ssize_t send_udp_message(uint8_t modifier1, char *host, char *message, uint16_t message_size) {
|
||||
|
||||
@@ -346,21 +452,27 @@ int uwsgi_parse_response(struct pollfd *upoll, int timeout, struct uwsgi_header
|
||||
return 0;
|
||||
}
|
||||
|
||||
// older OSX versions make mess with CMSG_FIRSTHDR
|
||||
#ifdef __APPLE__
|
||||
if (!msg.msg_controllen) return 1;
|
||||
#endif
|
||||
|
||||
cmsg = CMSG_FIRSTHDR (&msg);
|
||||
while(cmsg != NULL) {
|
||||
if (cmsg->cmsg_len != CMSG_LEN (sizeof (int)) ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS) continue;
|
||||
if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
|
||||
cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type && SCM_RIGHTS) {
|
||||
|
||||
// upgrade connection to the new socket
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("upgrading fd %d to ", upoll->fd);
|
||||
uwsgi_log("upgrading fd %d to ", upoll->fd);
|
||||
#endif
|
||||
close(upoll->fd);
|
||||
memcpy(&upoll->fd, CMSG_DATA(cmsg), sizeof(int));
|
||||
close(upoll->fd);
|
||||
memcpy(&upoll->fd, CMSG_DATA(cmsg), sizeof(int));
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%d\n", upoll->fd);
|
||||
uwsgi_log("%d\n", upoll->fd);
|
||||
#endif
|
||||
}
|
||||
cmsg = CMSG_NXTHDR (&msg, cmsg);
|
||||
}
|
||||
|
||||
@@ -516,6 +628,18 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->chdir = ptrbuf;
|
||||
wsgi_req->chdir_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("UWSGI_FILE", 10, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->file = ptrbuf;
|
||||
wsgi_req->file_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("UWSGI_TOUCH_RELOAD", 18, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->touch_reload = ptrbuf;
|
||||
wsgi_req->touch_reload_len = strsize;
|
||||
}
|
||||
else if (uwsgi.cache_max_items > 0 && !uwsgi_strncmp("UWSGI_CACHE_GET", 15, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->cache_get = ptrbuf;
|
||||
wsgi_req->cache_get_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("UWSGI_SETENV", 12, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
char *env_value = memchr(ptrbuf, '=', strsize);
|
||||
if (env_value) {
|
||||
@@ -545,6 +669,10 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->https = ptrbuf;
|
||||
wsgi_req->https_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("HTTP_IF_MODIFIED_SINCE", 22, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->if_modified_since = ptrbuf;
|
||||
wsgi_req->if_modified_since_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("CONTENT_LENGTH", 14, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->post_cl = get_content_length(ptrbuf, strsize);
|
||||
}
|
||||
@@ -570,19 +698,44 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
ptrbuf += strsize;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("Invalid uwsgi request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("Invalid uwsgi request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("Invalid uwsgi request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// check if data are available in the local cache
|
||||
if (wsgi_req->cache_get_len > 0) {
|
||||
uint64_t cache_value_size;
|
||||
char *cache_value = uwsgi_cache_get(wsgi_req->cache_get, wsgi_req->cache_get_len, &cache_value_size);
|
||||
if (cache_value && cache_value_size > 0) {
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, cache_value, cache_value_size);
|
||||
wsgi_req->status = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.check_cache && wsgi_req->uri_len && wsgi_req->method_len == 3 &&
|
||||
wsgi_req->method[0] == 'G' && wsgi_req->method[1] == 'E' && wsgi_req->method[2] == 'T') {
|
||||
|
||||
uint64_t cache_value_size;
|
||||
char *cache_value = uwsgi_cache_get(wsgi_req->uri, wsgi_req->uri_len, &cache_value_size);
|
||||
if (cache_value && cache_value_size > 0) {
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, cache_value, cache_value_size);
|
||||
wsgi_req->status = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.manage_script_name) {
|
||||
if (uwsgi.apps_cnt > 0 && wsgi_req->path_info_len > 1) {
|
||||
@@ -626,6 +779,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
|
||||
// check i fa file name uwsgi.check_static+env['PATH_INFO'] exists
|
||||
if (uwsgi.check_static && wsgi_req->path_info_len > 1) {
|
||||
struct stat st;
|
||||
char *filename = uwsgi_concat2n(uwsgi.check_static, uwsgi.check_static_len, wsgi_req->path_info, wsgi_req->path_info_len);
|
||||
@@ -633,13 +787,27 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("checking for %s\n", filename);
|
||||
#endif
|
||||
if (!stat(filename, &st)) {
|
||||
if (wsgi_req->if_modified_since_len) {
|
||||
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
|
||||
if (st.st_mtime <= ims) {
|
||||
wsgi_req->status = 304;
|
||||
wsgi_req->headers_size = write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, " 304 Not Modified\r\n\r\n", 21);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
|
||||
char http_last_modified[49];
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("file %s found\n", filename);
|
||||
#endif
|
||||
// no need to set content-type/content-length, they will be fixed by the http server/router
|
||||
wsgi_req->sendfile_fd = open(filename, O_RDONLY);
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->response_size += write(wsgi_req->poll.fd, " 200 OK\r\n\r\n", 11);
|
||||
wsgi_req->headers_size = write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, " 200 OK\r\n", 9);
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, http_last_modified, 48);
|
||||
wsgi_req->header_cnt = 1;
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
wsgi_req->status = 200;
|
||||
free(filename);
|
||||
|
||||
@@ -19,6 +19,25 @@ char *uwsgi_queue_get(uint64_t index, uint64_t *size) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_queue_fix() {
|
||||
|
||||
uint64_t i;
|
||||
char *value;
|
||||
uint64_t size;
|
||||
|
||||
for(i=0;i< uwsgi.queue_size;i++) {
|
||||
// valid record ?
|
||||
value = uwsgi_queue_get(i, &size);
|
||||
if (value && size) {
|
||||
uwsgi.shared->queue_pos++;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_queue_pop(uint64_t *size) {
|
||||
|
||||
struct uwsgi_queue_item *uqi;
|
||||
@@ -70,6 +89,8 @@ int uwsgi_queue_push(char *message, uint64_t size) {
|
||||
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
|
||||
return 0;
|
||||
|
||||
if (!size) return 0;
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.shared->queue_pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
|
||||
@@ -8,25 +8,38 @@ from setuptools.dist import Distribution
|
||||
from setuptools.command.install import install
|
||||
from setuptools.command.build_ext import build_ext
|
||||
|
||||
|
||||
def patch_bin_path(cmd, conf):
|
||||
|
||||
bin_name = conf.get('bin_name')
|
||||
|
||||
try:
|
||||
if not os.path.exists(cmd.install_scripts):
|
||||
os.makedirs(cmd.install_scripts)
|
||||
if not os.path.isabs(bin_name):
|
||||
print('Patching "bin_name" to properly install_scripts dir')
|
||||
conf.set('bin_name', os.path.join(cmd.install_scripts, conf.get('bin_name')))
|
||||
except:
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
|
||||
|
||||
class uWSGIBuilder(build_ext):
|
||||
|
||||
def run(self):
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
bin_name = conf.get('bin_name')
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
|
||||
|
||||
class uWSGIInstall(install):
|
||||
|
||||
def run(self):
|
||||
# hack, hack and still hack. We need to find a solution for 0.9.6
|
||||
# hack, hack and still hack. We need to find a solution...
|
||||
if self.record:
|
||||
record_file = open(self.record,'w')
|
||||
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
bin_name = conf.get('bin_name')
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
|
||||
class uWSGIDistribution(Distribution):
|
||||
@@ -38,7 +51,7 @@ class uWSGIDistribution(Distribution):
|
||||
|
||||
|
||||
setup(name='uWSGI',
|
||||
version='0.9.7-dev',
|
||||
version='0.9.7.1',
|
||||
description='The uWSGI server',
|
||||
author='Unbit',
|
||||
author_email='info@unbit.it',
|
||||
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
#ifdef UWSGI_STACKLESS
|
||||
|
||||
#include "uwsgi.h"
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
#include <stackless_api.h>
|
||||
#endif
|
||||
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct wsgi_request* find_request_by_tasklet(PyTaskletObject *tasklet) {
|
||||
|
||||
int i;
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
if (uwsgi.stackless_table[i]->tasklet == tasklet) {
|
||||
return uwsgi.stackless_table[i]->wsgi_req;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_stackless_worker(PyObject * self, PyObject * args) {
|
||||
|
||||
PyThreadState *ts = PyThreadState_GET();
|
||||
struct wsgi_request *wsgi_req = find_request_by_tasklet(ts->st.current);
|
||||
PyObject *zero;
|
||||
|
||||
int async_id = wsgi_req->async_id;
|
||||
|
||||
//uwsgi_log("i am the tasklet worker\n");
|
||||
|
||||
for(;;) {
|
||||
|
||||
// wait for request
|
||||
zero = PyChannel_Receive(uwsgi.workers_channel);
|
||||
|
||||
wsgi_req_setup(wsgi_req, async_id);
|
||||
|
||||
if (wsgi_req_accept(uwsgi.serverfd, wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wsgi_req_recv(wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uwsgi_close_request(&uwsgi, wsgi_req);
|
||||
}
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_stackless_worker[] = { {"uwsgi_stackless_worker", py_uwsgi_stackless_worker, METH_VARARGS, ""} };
|
||||
|
||||
void stackless_init(struct uwsgi_server *uwsgi) {
|
||||
int i;
|
||||
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests;
|
||||
|
||||
PyObject *tasklet_worker = PyCFunction_New(uwsgi_stackless_worker, NULL);
|
||||
|
||||
uwsgi->workers_channel = PyChannel_New(NULL);
|
||||
|
||||
uwsgi->stackless_table = malloc( sizeof(struct stackless_req*) * uwsgi->async);
|
||||
if (!uwsgi->stackless_table) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
uwsgi->stackless_table[i] = malloc(sizeof(struct stackless_req));
|
||||
if (!uwsgi->stackless_table[i]) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
memset(uwsgi->stackless_table[i], 0, sizeof(struct stackless_req));
|
||||
}
|
||||
|
||||
uwsgi_log("initializing %d tasklet...", uwsgi->async);
|
||||
|
||||
// creating uwsgi->async tasklets
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
wsgi_req->tasklet = PyTasklet_New(NULL, tasklet_worker);
|
||||
uwsgi->stackless_table[i]->tasklet = wsgi_req->tasklet;
|
||||
uwsgi->stackless_table[i]->wsgi_req = wsgi_req;
|
||||
// useless for now, it will be used for I/O or other messaging
|
||||
uwsgi->stackless_table[i]->channel = NULL;
|
||||
wsgi_req->async_id = i;
|
||||
|
||||
PyTasklet_Setup(wsgi_req->tasklet, PyTuple_New(0), NULL);
|
||||
//PyTasklet_Run(wsgi_req->tasklet);
|
||||
wsgi_req = next_wsgi_req(uwsgi, wsgi_req);
|
||||
}
|
||||
|
||||
uwsgi_log("done\n");
|
||||
}
|
||||
|
||||
void stackless_loop(struct uwsgi_server *uwsgi) {
|
||||
|
||||
int i;
|
||||
PyTaskletObject *int_tasklet;
|
||||
|
||||
// tasklets main loop
|
||||
for(;;) {
|
||||
//uwsgi->async_running = -1;
|
||||
//if (PyStackless_GetRunCount() > 0) {
|
||||
uwsgi->async_running = 0;
|
||||
//}
|
||||
uwsgi->async_nevents = async_wait(uwsgi->async_queue, uwsgi->async_events, uwsgi->async, uwsgi->async_running, 0);
|
||||
|
||||
if (uwsgi->async_nevents < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i=0; i<uwsgi->async_nevents;i++) {
|
||||
|
||||
if (uwsgi->async_events[i].ASYNC_FD == uwsgi->serverfd) {
|
||||
//pass the connection to the first available tasklet
|
||||
uwsgi_log("sending new connection...\n");
|
||||
PyChannel_Send(uwsgi->workers_channel, Py_True);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
if (PyStackless_GetRunCount() > 0) {
|
||||
PyStackless_Schedule(Py_None, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
PyStackless_RunWatchdogEx( 10, PY_WATCHDOG_TOTALTIMEOUT);
|
||||
|
||||
//int_tasklet = (PyTaskletObject *) PyStackless_RunWatchdog( 1000 );
|
||||
/*
|
||||
uwsgi_log("done watchdog %p\n", int_tasklet);
|
||||
if (!PyTasklet_IsCurrent(int_tasklet)) {
|
||||
uwsgi_log("re-insert: %d\n", 1);// PyTasklet_Insert(int_tasklet));
|
||||
}
|
||||
uwsgi_log("recycle\n");
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,5 @@
|
||||
import sys
|
||||
import uwsgi
|
||||
|
||||
content_type = 'image/png'
|
||||
filename = 'logo_uWSGI.png'
|
||||
|
||||
@@ -70,6 +70,12 @@ void daemonize(char *logfile) {
|
||||
pid_t pid;
|
||||
int fdin;
|
||||
|
||||
// do not daemonize under emperor
|
||||
if (uwsgi.has_emperor) {
|
||||
logto(logfile);
|
||||
return;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
@@ -338,6 +344,13 @@ void uwsgi_as_root() {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.logfile_chown) {
|
||||
if (fchown(2, uwsgi.uid, uwsgi.gid)) {
|
||||
uwsgi_error("fchown()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (uwsgi.gid) {
|
||||
if (!uwsgi.master_as_root) uwsgi_log("setgid() to %d\n", uwsgi.gid);
|
||||
if (setgid(uwsgi.gid)) {
|
||||
@@ -941,6 +954,7 @@ char *uwsgi_strncopy(char *s, int len) {
|
||||
int uwsgi_get_app_id(char *script_name, int script_name_len, int modifier1) {
|
||||
|
||||
int i;
|
||||
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);
|
||||
@@ -948,6 +962,15 @@ int uwsgi_get_app_id(char *script_name, int script_name_len, int modifier1) {
|
||||
continue;
|
||||
}
|
||||
if (!uwsgi_strncmp(uwsgi.apps[i].mountpoint, uwsgi.apps[i].mountpoint_len, script_name, script_name_len)) {
|
||||
if (uwsgi.apps[i].touch_reload) {
|
||||
if (!stat(uwsgi.apps[i].touch_reload, &st)) {
|
||||
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 (modifier1 == -1) return i;
|
||||
if (modifier1 == uwsgi.apps[i].modifier1) return i;
|
||||
}
|
||||
@@ -1349,7 +1372,7 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
if (add_zero) {
|
||||
*size = *size + 1;
|
||||
buffer = realloc(buffer, *size);
|
||||
buffer[*size] = 0;
|
||||
buffer[*size-1] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1666,3 +1689,37 @@ int uwsgi_list_has_str(char *list, char *str) {
|
||||
free(list2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_str2_num(char *str) {
|
||||
|
||||
int num = 0;
|
||||
|
||||
num = 10 * (str[0] - 48);
|
||||
num += str[1] - 48;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int uwsgi_str3_num(char *str) {
|
||||
|
||||
int num = 0;
|
||||
|
||||
num = 100 * (str[0] - 48);
|
||||
num += 10 * (str[1] - 48);
|
||||
num += str[2] - 48;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_str4_num(char *str) {
|
||||
|
||||
int num = 0;
|
||||
|
||||
num = 1000 * (str[0] - 48);
|
||||
num += 100 * (str[1] - 48);
|
||||
num += 10 * (str[2] - 48);
|
||||
num += str[3] - 48;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ static struct option long_base_options[] = {
|
||||
{"cgi-mode", no_argument, 0, 'c'},
|
||||
{"abstract-socket", no_argument, 0, 'a'},
|
||||
{"chmod-socket", optional_argument, 0, 'C'},
|
||||
{"map-socket", required_argument, 0, LONG_ARGS_MAP_SOCKET},
|
||||
{"chmod", optional_argument, 0, 'C'},
|
||||
#ifdef UWSGI_THREADING
|
||||
{"enable-threads", no_argument, 0, 'T'},
|
||||
#endif
|
||||
@@ -70,12 +72,15 @@ static struct option long_base_options[] = {
|
||||
{"cache-store-sync", required_argument, 0, LONG_ARGS_CACHE_STORE_SYNC},
|
||||
{"queue", required_argument, 0, LONG_ARGS_QUEUE},
|
||||
{"queue-blocksize", required_argument, 0, LONG_ARGS_QUEUE_BLOCKSIZE},
|
||||
{"queue-store", required_argument, 0, LONG_ARGS_QUEUE_STORE},
|
||||
{"queue-store-sync", required_argument, 0, LONG_ARGS_QUEUE_STORE_SYNC},
|
||||
#ifdef UWSGI_SPOOLER
|
||||
{"spooler", required_argument, 0, 'Q'},
|
||||
#endif
|
||||
{"disable-logging", no_argument, 0, 'L'},
|
||||
|
||||
{"pidfile", required_argument, 0, LONG_ARGS_PIDFILE},
|
||||
{"pidfile2", required_argument, 0, LONG_ARGS_PIDFILE2},
|
||||
{"chroot", required_argument, 0, LONG_ARGS_CHROOT},
|
||||
{"gid", required_argument, 0, LONG_ARGS_GID},
|
||||
{"uid", required_argument, 0, LONG_ARGS_UID},
|
||||
@@ -125,6 +130,7 @@ static struct option long_base_options[] = {
|
||||
{"async", required_argument, 0, LONG_ARGS_ASYNC},
|
||||
#endif
|
||||
{"logto", required_argument, 0, LONG_ARGS_LOGTO},
|
||||
{"logfile-chown", no_argument, &uwsgi.logfile_chown, 1},
|
||||
{"log-syslog", optional_argument, 0, LONG_ARGS_LOG_SYSLOG},
|
||||
{"log-master", no_argument, 0, LONG_ARGS_LOG_MASTER},
|
||||
{"logdate", optional_argument, 0, LONG_ARGS_LOG_DATE},
|
||||
@@ -147,6 +153,7 @@ static struct option long_base_options[] = {
|
||||
{"routing", no_argument, &uwsgi.routing, 1},
|
||||
#endif
|
||||
{"check-static", required_argument, 0, LONG_ARGS_CHECK_STATIC},
|
||||
{"check-cache", no_argument, &uwsgi.check_cache, 1},
|
||||
{"close-on-exec", no_argument, &uwsgi.close_on_exec, 1},
|
||||
{"mode", required_argument, 0, LONG_ARGS_MODE},
|
||||
{"env", required_argument, 0, LONG_ARGS_ENV},
|
||||
@@ -411,6 +418,13 @@ static void vacuum(void)
|
||||
uwsgi_log("VACUUM: pidfile removed.\n");
|
||||
}
|
||||
}
|
||||
if (uwsgi.pidfile2) {
|
||||
if (unlink(uwsgi.pidfile2)) {
|
||||
uwsgi_error("unlink()");
|
||||
} else {
|
||||
uwsgi_log("VACUUM: pidfile2 removed.\n");
|
||||
}
|
||||
}
|
||||
if (uwsgi.chdir) {
|
||||
if (chdir(uwsgi.chdir)) {
|
||||
uwsgi_error("chdir()");
|
||||
@@ -823,9 +837,10 @@ int main(int argc, char *argv[], char *envp[])
|
||||
if (uwsgi.dump_options) {
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
while(lopt->name) {
|
||||
uwsgi_log("--%s\n", lopt->name);
|
||||
fprintf(stdout, "%s\n", lopt->name);
|
||||
lopt++;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (uwsgi.show_config) {
|
||||
@@ -898,7 +913,7 @@ options_parsed:
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("***\n*** You are running a DEBUG version of uWSGI, plese disable DEBUG in uwsgiconfig.py and recompile it ***\n***\n");
|
||||
uwsgi_log("***\n*** You are running a DEBUG version of uWSGI, please disable debug in your build profile and recompile it ***\n***\n");
|
||||
#endif
|
||||
|
||||
uwsgi_log("compiled with version: %s on %s\n", __VERSION__, UWSGI_BUILD_DATE);
|
||||
@@ -941,7 +956,9 @@ options_parsed:
|
||||
int waitpid_status;
|
||||
uwsgi_log("*** jailing uWSGI in %s ***\n", uwsgi.ns);
|
||||
int clone_flags = SIGCHLD|CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
|
||||
//clone_flags |= CLONE_NEWNET;
|
||||
if (uwsgi.ns_net) {
|
||||
clone_flags |= CLONE_NEWNET;
|
||||
}
|
||||
pid_t pid = clone(uwsgi_start, stack+PTHREAD_STACK_MIN, clone_flags, (void *)argv);
|
||||
if (pid == -1) {
|
||||
uwsgi_error("clone()");
|
||||
@@ -1089,6 +1106,19 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
|
||||
uwsgi_log("writing pidfile2 to %s\n", uwsgi.pidfile2);
|
||||
FILE *pidfile2 = fopen(uwsgi.pidfile2, "w");
|
||||
if (!pidfile2) {
|
||||
uwsgi_error_open(uwsgi.pidfile2);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(pidfile2, "%d\n", (int) getpid()) < 0) {
|
||||
uwsgi_log("could not write pidfile2.\n");
|
||||
}
|
||||
fclose(pidfile2);
|
||||
}
|
||||
|
||||
if (!uwsgi.no_initial_output) {
|
||||
if (!uwsgi.master_process) {
|
||||
uwsgi_log(" *** WARNING: you are running uWSGI without its master process manager ***\n");
|
||||
@@ -1307,15 +1337,50 @@ int uwsgi_start(void *v_argv) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.queue = mmap(NULL, uwsgi.queue_blocksize * uwsgi.queue_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
|
||||
uwsgi.shared->queue_pos = 0;
|
||||
uwsgi.shared->queue_pull_pos = 0;
|
||||
|
||||
if (uwsgi.queue_store) {
|
||||
uwsgi.queue_filesize = uwsgi.queue_blocksize * uwsgi.queue_size;
|
||||
int queue_fd;
|
||||
struct stat qst;
|
||||
|
||||
if (stat(uwsgi.queue_store, &qst)) {
|
||||
uwsgi_log("creating a new queue store file: %s\n", uwsgi.queue_store);
|
||||
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR );
|
||||
if (queue_fd >= 0) {
|
||||
// fill the queue store
|
||||
if (ftruncate(queue_fd, uwsgi.queue_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((size_t)qst.st_size != uwsgi.queue_filesize || !S_ISREG(qst.st_mode)) {
|
||||
uwsgi_log("invalid queue store file. Please remove it or fix queue blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR );
|
||||
uwsgi_log("recovered queue from backing store file: %s\n", uwsgi.queue_store);
|
||||
}
|
||||
|
||||
if (queue_fd < 0) {
|
||||
uwsgi_error_open(uwsgi.queue_store);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.queue = mmap(NULL, uwsgi.queue_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, queue_fd, 0);
|
||||
uwsgi_queue_fix();
|
||||
}
|
||||
else {
|
||||
uwsgi.queue = mmap(NULL, uwsgi.queue_blocksize * uwsgi.queue_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
}
|
||||
if (!uwsgi.queue) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.shared->queue_pos = 0;
|
||||
uwsgi.shared->queue_pull_pos = 0;
|
||||
|
||||
uwsgi.queue_lock = uwsgi_mmap_shared_rwlock();
|
||||
uwsgi_rwlock_init(uwsgi.queue_lock);
|
||||
|
||||
@@ -1638,7 +1703,8 @@ int uwsgi_start(void *v_argv) {
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.sockets_cnt) {
|
||||
if (uwsgi.has_threads) {
|
||||
uwsgi.current_wsgi_req = threaded_current_wsgi_req;
|
||||
if (uwsgi.threads > 1)
|
||||
uwsgi.current_wsgi_req = threaded_current_wsgi_req;
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->enable_threads)
|
||||
uwsgi.p[i]->enable_threads();
|
||||
@@ -1690,6 +1756,22 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
memset(uwsgi.workers, 0, sizeof(struct uwsgi_worker) * uwsgi.numproc + 1);
|
||||
|
||||
for(i=0;i<MAX_SOCKETS;i++) {
|
||||
if (!uwsgi.map_socket[i]) continue;
|
||||
char *p = strtok(uwsgi.map_socket[i], ",");
|
||||
while (p != NULL) {
|
||||
int w = atoi(p);
|
||||
if (w < 1 || w > uwsgi.numproc) {
|
||||
uwsgi_log("invalid worker num: %d\n", w);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.workers[w].sockets_mask[i] = 1;
|
||||
uwsgi_log("mapped socket %d (%s) to worker %d\n", i, uwsgi.sockets[i].name, w);
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uwsgi.mypid = getpid();
|
||||
masterpid = uwsgi.mypid;
|
||||
|
||||
@@ -1894,6 +1976,31 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
//from now on the process is a real worker
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.sockets_cnt;i++) {
|
||||
if (uwsgi.workers[uwsgi.mywid].sockets_mask[i]) {
|
||||
// disable the socket for this worker
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("switching off socket %d (%d) on worker %d\n", i, uwsgi.sockets[i].fd, uwsgi.mywid);
|
||||
#endif
|
||||
int fd = uwsgi.sockets[i].fd;
|
||||
close(fd);
|
||||
fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != uwsgi.sockets[i].fd) {
|
||||
if (dup2(fd, uwsgi.sockets[i].fd)) {
|
||||
uwsgi_error("dup2()");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
uwsgi.sockets_poll[i].fd = -1;
|
||||
uwsgi.sockets_poll[i].events = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.cpu_affinity) {
|
||||
#ifdef __linux__
|
||||
cpu_set_t cpuset;
|
||||
@@ -2219,6 +2326,9 @@ end:
|
||||
case LONG_ARGS_PIDFILE:
|
||||
uwsgi.pidfile = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PIDFILE2:
|
||||
uwsgi.pidfile2 = optarg;
|
||||
return 1;
|
||||
#ifdef UWSGI_UDP
|
||||
case LONG_ARGS_UDP:
|
||||
uwsgi.udp_socket = optarg;
|
||||
@@ -2301,6 +2411,9 @@ end:
|
||||
case LONG_ARGS_LINUX_NS:
|
||||
uwsgi.ns = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_LINUX_NS_NET:
|
||||
uwsgi.ns_net = optarg;
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_LIMIT_AS:
|
||||
uwsgi.rl.rlim_cur = (atoi(optarg)) * 1024 * 1024;
|
||||
@@ -2334,6 +2447,21 @@ end:
|
||||
uwsgi.ini = optarg;
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_MAP_SOCKET:
|
||||
p = strchr(optarg, ':');
|
||||
if (!p) {
|
||||
uwsgi_log("invalid map-socket syntax, must be socketnum:workerN[,workerN...]\n");
|
||||
exit(1);
|
||||
}
|
||||
p[0] = 0;
|
||||
int sn = atoi(optarg);
|
||||
if (sn < 0 || sn >= MAX_SOCKETS) {
|
||||
uwsgi_log("invalid socket number in map-socket\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.map_socket[sn] = p+1;
|
||||
p[0] = ':';
|
||||
return 1;
|
||||
case LONG_ARGS_CHECK_INTERVAL:
|
||||
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = atoi(optarg);
|
||||
return 1;
|
||||
@@ -2350,6 +2478,13 @@ end:
|
||||
case LONG_ARGS_CACHE_BLOCKSIZE:
|
||||
uwsgi.cache_blocksize = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_QUEUE_STORE:
|
||||
uwsgi.queue_store = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_QUEUE_STORE_SYNC:
|
||||
uwsgi.queue_store_sync = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_QUEUE:
|
||||
uwsgi.queue_size = atoi(optarg);
|
||||
return 1;
|
||||
@@ -2995,11 +3130,14 @@ struct uwsgi_help_item main_help[] = {
|
||||
{"disable-logging", "disable request logging (only errors or server messages will be logged)"},
|
||||
{"xmlconfig <path>", "path of xml config file"},
|
||||
{"harakiri <sec>", "set harakiri timeout to <sec> seconds"},
|
||||
{"harakiri-verbose", "report additional info during harakiri"},
|
||||
{"processes <n>", "spawn <n> uwsgi worker processes"},
|
||||
{"workers <n>", "spawn <n> uwsgi worker processes"},
|
||||
{"max-vars <n>", "set maximum number of vars/headers to <n>"},
|
||||
{"sharedarea <n>", "create a shared memory area of <n> pages"},
|
||||
{"cgi-mode", "set cgi mode"},
|
||||
{"chmod-socket[=NNN]", "chmod socket to 666 or NNN"},
|
||||
{"chmod[=NNN]", "chmod socket to 666 or NNN"},
|
||||
{"memory-report", "enable memory usage report"},
|
||||
{"single-interpreter", "single interpreter mode"},
|
||||
{"abstract-socket", "set socket in the abstract namespace (Linux only)"},
|
||||
@@ -3027,7 +3165,7 @@ struct uwsgi_help_item main_help[] = {
|
||||
{"no-orphans", "automatically kill workers on master's dead"},
|
||||
{"udp <ip:port>", "bind master process to udp socket on ip:port"},
|
||||
{"multicast <group>", "set multicast group"},
|
||||
{"snmp", "enable SNMP support in the UDP server"},
|
||||
{"snmp[=<addr>]", "enable SNMP support in the UDP server or bind it to <addr>"},
|
||||
{"snmp-community <value>", "set SNMP community code to <value>"},
|
||||
{"erlang <name|address>", "enable the Erlang server with node name <name@address>"},
|
||||
{"erlang-cookie <cookie>", "set the erlang cookie to <cookie>"},
|
||||
@@ -3037,6 +3175,7 @@ struct uwsgi_help_item main_help[] = {
|
||||
{"proxy-node <socket>", "add the node <socket> to the proxy"},
|
||||
{"proxy-max-connections <n>", "set the max number of concurrent connections mnaged by the proxy"},
|
||||
{"async <n>", "enable async mode with n core"},
|
||||
{"threads <n>", "spawn <n> threads core"},
|
||||
{"logto <logfile|addr>", "log to file/udp"},
|
||||
{"logdate", "add timestamp to loglines"},
|
||||
{"log-zero", "log requests with 0 response size"},
|
||||
@@ -3056,6 +3195,7 @@ struct uwsgi_help_item main_help[] = {
|
||||
{"ugreen-stacksize <n>", "set uGreen stacksize to <n>"},
|
||||
{"no-site", "do not import site.py on startup"},
|
||||
{"vhost", "enable virtual hosting"},
|
||||
{"vhost-host", "use the Host header as the key for virtual hosting"},
|
||||
{"mount MOUNTPOINT=app", "add a new app under MOUNTPOINT"},
|
||||
{"routing", "enable uWSGI advanced routing"},
|
||||
{"http <addr>", "start embedded HTTP server on <addr>"},
|
||||
@@ -3070,6 +3210,7 @@ struct uwsgi_help_item main_help[] = {
|
||||
{"cgroup <group>", "run the server in <group> cgroup (Linux only)"},
|
||||
{"cgroup-opt KEY=VAL", "set cgroup option (Linux only)"},
|
||||
{"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>"},
|
||||
|
||||
{ 0, 0 },
|
||||
@@ -3148,6 +3289,7 @@ void uwsgi_help(void) {
|
||||
|
||||
tmp_option = uwsgi_concat2(uhi->key, "");
|
||||
space = strchr(tmp_option, ' ');
|
||||
if (!space) space = strstr(tmp_option, "[=");
|
||||
if (space) space[0] = 0;
|
||||
|
||||
if (!strcmp(tmp_option, lopt->name)) {
|
||||
@@ -3167,6 +3309,7 @@ void uwsgi_help(void) {
|
||||
if (uhi->key == 0) break;
|
||||
tmp_option = uwsgi_concat2(uhi->key, "");
|
||||
space = strchr(tmp_option, ' ');
|
||||
if (!space) space = strstr(tmp_option, "[=");
|
||||
if (space) space[0] = 0;
|
||||
|
||||
if (!strcmp(tmp_option, lopt->name)) {
|
||||
@@ -3190,6 +3333,7 @@ void uwsgi_help(void) {
|
||||
if (uhi->key == 0) break;
|
||||
tmp_option = uwsgi_concat2(uhi->key, "");
|
||||
space = strchr(tmp_option, ' ');
|
||||
if (!space) space = strstr(tmp_option, "[=");
|
||||
if (space) space[0] = 0;
|
||||
|
||||
if (!strcmp(tmp_option, lopt->name)) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/* indent -i8 -br -brs -brf -l0 -npsl -nip -npcs -npsl -di1 */
|
||||
|
||||
#define UWSGI_VERSION "0.9.7-dev"
|
||||
#define UWSGI_VERSION "0.9.7.1"
|
||||
|
||||
#define UMAX16 65536
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#define ushared uwsgi.shared
|
||||
|
||||
#define MAX_SOCKETS 8
|
||||
#define MAX_APPS 64
|
||||
#define MAX_GENERIC_PLUGINS 64
|
||||
#define MAX_RPC 64
|
||||
@@ -374,6 +375,10 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_CPU_AFFINITY 17083
|
||||
#define LONG_ARGS_CACHE_STORE 17084
|
||||
#define LONG_ARGS_CACHE_STORE_SYNC 17085
|
||||
#define LONG_ARGS_QUEUE_STORE 17086
|
||||
#define LONG_ARGS_QUEUE_STORE_SYNC 17087
|
||||
#define LONG_ARGS_PIDFILE2 17088
|
||||
#define LONG_ARGS_MAP_SOCKET 17089
|
||||
|
||||
|
||||
#define UWSGI_OK 0
|
||||
@@ -539,6 +544,9 @@ struct uwsgi_app {
|
||||
int requests;
|
||||
char *chdir;
|
||||
|
||||
char *touch_reload;
|
||||
time_t touch_reload_mtime;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -641,6 +649,15 @@ struct wsgi_request {
|
||||
char *chdir;
|
||||
uint16_t chdir_len;
|
||||
|
||||
char *touch_reload;
|
||||
uint16_t touch_reload_len;
|
||||
|
||||
char *cache_get;
|
||||
uint16_t cache_get_len;
|
||||
|
||||
char *if_modified_since;
|
||||
uint16_t if_modified_since_len;
|
||||
|
||||
int fd_closed;
|
||||
|
||||
int sendfile_fd;
|
||||
@@ -785,6 +802,7 @@ struct uwsgi_server {
|
||||
size_t check_static_len;
|
||||
|
||||
char *logfile;
|
||||
int logfile_chown;
|
||||
|
||||
int vhost;
|
||||
int vhost_host;
|
||||
@@ -855,6 +873,7 @@ struct uwsgi_server {
|
||||
int page_size;
|
||||
|
||||
char *pidfile;
|
||||
char *pidfile2;
|
||||
|
||||
int harakiri_verbose;
|
||||
|
||||
@@ -943,13 +962,16 @@ struct uwsgi_server {
|
||||
char *cgroup_opt[64];
|
||||
int cgroup_opt_cnt;
|
||||
char *ns;
|
||||
char *ns_net;
|
||||
#endif
|
||||
|
||||
int sockets_cnt;
|
||||
struct uwsgi_socket sockets[8];
|
||||
struct uwsgi_socket sockets[MAX_SOCKETS];
|
||||
// leave a slot for no-orphan mode
|
||||
struct pollfd sockets_poll[9];
|
||||
|
||||
char *map_socket[MAX_SOCKETS];
|
||||
|
||||
time_t respawn_delta;
|
||||
|
||||
char *mounts[MAX_APPS];
|
||||
@@ -989,6 +1011,8 @@ struct uwsgi_server {
|
||||
int cluster_nodes;
|
||||
int cluster_fd;
|
||||
struct sockaddr_in mc_cluster_addr;
|
||||
|
||||
int check_cache;
|
||||
|
||||
uint32_t cache_max_items;
|
||||
uint64_t *cache_hashtable;
|
||||
@@ -1003,6 +1027,9 @@ struct uwsgi_server {
|
||||
uint64_t queue_size;
|
||||
uint64_t queue_blocksize;
|
||||
void *queue;
|
||||
char *queue_store;
|
||||
size_t queue_filesize;
|
||||
int queue_store_sync;
|
||||
|
||||
void *cache_lock;
|
||||
void *queue_lock;
|
||||
@@ -1207,6 +1234,8 @@ struct uwsgi_worker {
|
||||
|
||||
uint64_t exceptions;
|
||||
|
||||
char sockets_mask[MAX_SOCKETS];
|
||||
|
||||
};
|
||||
|
||||
char *uwsgi_get_cwd(void);
|
||||
@@ -1651,3 +1680,9 @@ inline int event_queue_read(void);
|
||||
inline int event_queue_write(void);
|
||||
|
||||
void uwsgi_help(void);
|
||||
|
||||
void uwsgi_queue_fix(void);
|
||||
|
||||
int uwsgi_str2_num(char *);
|
||||
int uwsgi_str3_num(char *);
|
||||
int uwsgi_str4_num(char *);
|
||||
|
||||
@@ -234,6 +234,9 @@ class uConf(object):
|
||||
self.libs.remove('-lpthread')
|
||||
self.libs.append('-lroot')
|
||||
|
||||
if uwsgi_os == 'Darwin':
|
||||
self.cflags.append('-mmacosx-version-min=10.5')
|
||||
|
||||
# set locking subsystem
|
||||
locking_mode = self.get('locking','auto')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user