mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 13:41:28 +00:00
trying to understand why multirheading is flaky on pypy
This commit is contained in:
+39
-21
@@ -26,7 +26,7 @@ void (*pypy_init_threads)(void);
|
||||
|
||||
// the hooks you can override with pypy
|
||||
void (*uwsgi_pypy_hook_loader)(char *);
|
||||
void (*uwsgi_pypy_hook_request)(void *);
|
||||
void (*uwsgi_pypy_hook_request)(int);
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
struct uwsgi_plugin pypy_plugin;
|
||||
@@ -43,43 +43,51 @@ int uwsgi_pypy_helper_register_signal(int signum, char *kind, void *handler) {
|
||||
return uwsgi_register_signal(signum, kind, handler, pypy_plugin.modifier1);
|
||||
}
|
||||
|
||||
int uwsgi_pypy_helper_vars(void *r) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
int uwsgi_pypy_helper_register_rpc(char *name, int argc, void *func) {
|
||||
return uwsgi_register_rpc(name, &pypy_plugin, argc, func);
|
||||
}
|
||||
|
||||
int uwsgi_pypy_helper_vars(int core) {
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
return wsgi_req->var_cnt;
|
||||
}
|
||||
|
||||
char *uwsgi_pypy_helper_key(void *r, int pos) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
char *uwsgi_pypy_helper_key(int core, int pos) {
|
||||
uwsgi_log("[key] core = %d pos = %d\n", core, pos);
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
return wsgi_req->hvec[pos].iov_base;
|
||||
}
|
||||
|
||||
int uwsgi_pypy_helper_keylen(void *r, int pos) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
int uwsgi_pypy_helper_keylen(int core, int pos) {
|
||||
uwsgi_log("[keylen] core = %d pos = %d\n", core, pos);
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
return wsgi_req->hvec[pos].iov_len;
|
||||
}
|
||||
|
||||
char *uwsgi_pypy_helper_val(void *r, int pos) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
char *uwsgi_pypy_helper_val(int core, int pos) {
|
||||
uwsgi_log("[val] core = %d pos = %d\n", core, pos);
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
return wsgi_req->hvec[pos+1].iov_base;
|
||||
}
|
||||
|
||||
int uwsgi_pypy_helper_vallen(void *r, int pos) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
int uwsgi_pypy_helper_vallen(int core, int pos) {
|
||||
uwsgi_log("[vallen] core = %d pos = %d\n", core, pos);
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
return wsgi_req->hvec[pos+1].iov_len;
|
||||
}
|
||||
|
||||
void uwsgi_pypy_helper_status(void *r, char *status, int status_len) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
void uwsgi_pypy_helper_status(int core, char *status, int status_len) {
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
uwsgi_response_prepare_headers(wsgi_req, status, status_len);
|
||||
}
|
||||
|
||||
void uwsgi_pypy_helper_header(void *r, char *k, int kl, char *v, int vl) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
void uwsgi_pypy_helper_header(int core, char *k, int kl, char *v, int vl) {
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
uwsgi_response_add_header(wsgi_req, k, kl, v, vl);
|
||||
}
|
||||
|
||||
void uwsgi_pypy_helper_write(void *r, char *body, int len) {
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) r;
|
||||
void uwsgi_pypy_helper_write(int core, char *body, int len) {
|
||||
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core].req;
|
||||
uwsgi_response_write_body_do(wsgi_req, body, len);
|
||||
}
|
||||
|
||||
@@ -172,7 +180,7 @@ static int uwsgi_pypy_request(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
if (uwsgi_pypy_hook_request) {
|
||||
uwsgi_pypy_hook_request(wsgi_req);
|
||||
uwsgi_pypy_hook_request(wsgi_req->async_id);
|
||||
}
|
||||
return UWSGI_OK;
|
||||
}
|
||||
@@ -205,14 +213,12 @@ static struct uwsgi_option uwsgi_pypy_options[] = {
|
||||
static void uwsgi_pypy_enable_threads() {
|
||||
if (pypy_init_threads) {
|
||||
pypy_init_threads();
|
||||
uwsgi_log("THREADS ENABLED !!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void uwsgi_pypy_init_thread() {
|
||||
uwsgi_log("initializing thread...\n");
|
||||
if (pypy_thread_attach) {
|
||||
//pypy_thread_attach();
|
||||
pypy_thread_attach();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +228,17 @@ static int uwsgi_pypy_signal_handler(uint8_t sig, void *handler) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
||||
int iargvs[UMAX8];
|
||||
int i;
|
||||
int (*pypy_func)(int, char **, int*, char *) = (int (*)(int, char **, int*, char *)) func;
|
||||
// we convert 16bit to int
|
||||
for(i=0;i<argc;i++) {
|
||||
iargvs[i] = (int) argvs[i];
|
||||
}
|
||||
return pypy_func(argc, argv, iargvs, buffer);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin pypy_plugin = {
|
||||
.name = "pypy",
|
||||
.modifier1 = 0,
|
||||
@@ -233,4 +250,5 @@ struct uwsgi_plugin pypy_plugin = {
|
||||
.init_thread = uwsgi_pypy_init_thread,
|
||||
.signal_handler = uwsgi_pypy_signal_handler,
|
||||
.enable_threads = uwsgi_pypy_enable_threads,
|
||||
.rpc = uwsgi_python_rpc,
|
||||
};
|
||||
|
||||
+48
-19
@@ -1,28 +1,31 @@
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, '.')
|
||||
|
||||
import cffi
|
||||
|
||||
# this is a list holding object we do not want to be freed (like callback and handlers)
|
||||
uwsgi_gc = []
|
||||
|
||||
defines = '''
|
||||
void (*uwsgi_pypy_hook_loader)(char *);
|
||||
void (*uwsgi_pypy_hook_request)(void *);
|
||||
void (*uwsgi_pypy_hook_request)(int);
|
||||
|
||||
char *uwsgi_pypy_helper_key(void *, int);
|
||||
int uwsgi_pypy_helper_keylen(void *, int);
|
||||
char *uwsgi_pypy_helper_key(int, int);
|
||||
int uwsgi_pypy_helper_keylen(int, int);
|
||||
|
||||
char *uwsgi_pypy_helper_val(void *, int);
|
||||
int uwsgi_pypy_helper_vallen(void *, int);
|
||||
char *uwsgi_pypy_helper_val(int, int);
|
||||
int uwsgi_pypy_helper_vallen(int, int);
|
||||
|
||||
int uwsgi_pypy_helper_vars(void *);
|
||||
int uwsgi_pypy_helper_vars(int);
|
||||
|
||||
void uwsgi_pypy_helper_status(void *, char *, int);
|
||||
void uwsgi_pypy_helper_header(void *, char *, int, char *, int);
|
||||
void uwsgi_pypy_helper_status(int, char *, int);
|
||||
void uwsgi_pypy_helper_header(int, char *, int, char *, int);
|
||||
|
||||
void uwsgi_pypy_helper_write(void *, char *, int);
|
||||
void uwsgi_pypy_helper_write(int, char *, int);
|
||||
|
||||
char *uwsgi_pypy_helper_version();
|
||||
int uwsgi_pypy_helper_register_signal(int, char *, void *);
|
||||
int uwsgi_pypy_helper_register_rpc(char *, int, void *);
|
||||
void uwsgi_pypy_helper_signal(int);
|
||||
'''
|
||||
|
||||
@@ -42,39 +45,42 @@ def uwsgi_pypy_loader(module):
|
||||
mod = __import__(m)
|
||||
wsgi_application = getattr(mod, c)
|
||||
|
||||
@ffi.callback("void(void *)")
|
||||
def uwsgi_pypy_wsgi_handler(wsgi_req):
|
||||
@ffi.callback("void(int)")
|
||||
def uwsgi_pypy_wsgi_handler(core):
|
||||
global wsgi_application
|
||||
|
||||
def writer(data):
|
||||
lib.uwsgi_pypy_helper_write(wsgi_req, ffi.new("char[]", data), len(data))
|
||||
lib.uwsgi_pypy_helper_write(core, ffi.new("char[]", data), len(data))
|
||||
|
||||
def start_response(status, headers, exc_info=None):
|
||||
lib.uwsgi_pypy_helper_status(wsgi_req, ffi.new("char[]", status), len(status))
|
||||
lib.uwsgi_pypy_helper_status(core, ffi.new("char[]", status), len(status))
|
||||
for hh in headers:
|
||||
lib.uwsgi_pypy_helper_header(wsgi_req, ffi.new("char[]", hh[0]), len(hh[0]), ffi.new("char[]", hh[1]), len(hh[1]))
|
||||
lib.uwsgi_pypy_helper_header(core, ffi.new("char[]", hh[0]), len(hh[0]), ffi.new("char[]", hh[1]), len(hh[1]))
|
||||
return writer
|
||||
|
||||
class WSGIinput():
|
||||
pass
|
||||
|
||||
environ = {}
|
||||
n = lib.uwsgi_pypy_helper_vars(wsgi_req)
|
||||
n = lib.uwsgi_pypy_helper_vars(core)
|
||||
print "[n] core = %d vars = %d" % (core, n)
|
||||
for i in range(0, n, 2):
|
||||
key = ffi.string( lib.uwsgi_pypy_helper_key(wsgi_req, i), lib.uwsgi_pypy_helper_keylen(wsgi_req, i) )
|
||||
value = ffi.string( lib.uwsgi_pypy_helper_val(wsgi_req, i), lib.uwsgi_pypy_helper_vallen(wsgi_req, i) )
|
||||
key = ffi.string( lib.uwsgi_pypy_helper_key(core, i), lib.uwsgi_pypy_helper_keylen(core, i) )
|
||||
value = ffi.string( lib.uwsgi_pypy_helper_val(core, i), lib.uwsgi_pypy_helper_vallen(core, i) )
|
||||
environ[key] = value
|
||||
|
||||
environ['wsgi.version'] = (1, 0)
|
||||
scheme = 'http'
|
||||
if 'HTTPS' in environ:
|
||||
if environ['HTTPS'] in ('on', 'ON', 'On', '1', 'true', 'TRUE'):
|
||||
if environ['HTTPS'] in ('on', 'ON', 'On', '1', 'true', 'TRUE', 'True'):
|
||||
scheme = 'https'
|
||||
environ['wsgi.url_scheme'] = environ.get('UWSGI_SCHEME', scheme)
|
||||
environ['wsgi.input'] = WSGIinput
|
||||
environ['wsgi.errors'] = sys.stderr
|
||||
environ['wsgi.run_once'] = False
|
||||
|
||||
environ['uwsgi.core'] = core
|
||||
|
||||
response = wsgi_application(environ, start_response)
|
||||
if type(response) == 'str':
|
||||
writer(response)
|
||||
@@ -95,12 +101,35 @@ sys.modules['uwsgi'] = uwsgi
|
||||
uwsgi.version = ffi.string( lib.uwsgi_pypy_helper_version() )
|
||||
|
||||
def uwsgi_pypy_uwsgi_register_signal(signum, kind, handler):
|
||||
global uwsgi_gc
|
||||
uwsgi_gc.append(handler)
|
||||
if lib.uwsgi_pypy_helper_register_signal(signum, ffi.new("char[]", kind), ffi.callback('void(int)', handler)) < 0:
|
||||
raise Exception("unable to register signal %d" % signum)
|
||||
uwsgi.register_signal = uwsgi_pypy_uwsgi_register_signal
|
||||
|
||||
class uwsgi_pypy_RPC():
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
def __call__(self, argc, argv, argvs, buf):
|
||||
pargs = []
|
||||
for i in range(0, argc):
|
||||
pargs.append(ffi.string(argv[i],argvs[i]))
|
||||
response = self.func(*pargs)
|
||||
if len(response) > 0 and len(response) <= 65535:
|
||||
dst = ffi.buffer(buf, 65536)
|
||||
dst[:len(response)] = response
|
||||
return len(response)
|
||||
|
||||
def uwsgi_pypy_uwsgi_register_rpc(name, func, argc=0):
|
||||
global uwsgi_gc
|
||||
uwsgi_gc.append(func)
|
||||
if lib.uwsgi_pypy_helper_register_rpc(ffi.new("char[]", name), argc, ffi.callback("int(int, char*[], int[], char*)", uwsgi_pypy_RPC(func))) < 0:
|
||||
raise Exception("unable to register rpc func %s" % name)
|
||||
uwsgi.register_rpc = uwsgi_pypy_uwsgi_register_rpc
|
||||
|
||||
def uwsgi_pypy_uwsgi_signal(signum):
|
||||
lib.uwsgi_pypy_helper_signal(signum)
|
||||
uwsgi.signal = uwsgi_pypy_uwsgi_signal
|
||||
|
||||
|
||||
print "Initialized PyPy with Python",sys.version
|
||||
|
||||
Reference in New Issue
Block a user