From 1989099cc5dd341b3671fe2fe0455380959d23eb Mon Sep 17 00:00:00 2001 From: "roberto@debian32" Date: Wed, 31 Aug 2011 13:18:32 +0200 Subject: [PATCH] preliminary pypy support --- plugins/python/gil.c | 7 +++++++ plugins/python/profiler.c | 2 ++ plugins/python/pyloader.c | 15 ++++++++++++++- plugins/python/python_plugin.c | 31 ++++++++++++++++++++++++++++++- plugins/python/pyutils.c | 2 ++ plugins/python/symimporter.c | 2 +- plugins/python/uwsgi_pymodule.c | 16 +++++++++++----- plugins/python/uwsgi_python.h | 4 ++++ plugins/python/uwsgiplugin.py | 4 ++++ plugins/python/wsgi_subhandler.c | 13 ++++++++++++- pyuwsgi_run.py | 5 +++-- 11 files changed, 90 insertions(+), 11 deletions(-) diff --git a/plugins/python/gil.c b/plugins/python/gil.c index 02ec6986..15da4c69 100644 --- a/plugins/python/gil.c +++ b/plugins/python/gil.c @@ -3,6 +3,11 @@ extern struct uwsgi_server uwsgi; extern struct uwsgi_python up; +#ifdef UWSGI_PYPY +void gil_real_get() {} +void gil_real_release() {} +#else + void gil_real_get() { //uwsgi_log("LOCK %d\n", uwsgi.mywid); #ifndef PYTHREE @@ -26,5 +31,7 @@ void gil_real_release() { #endif } +#endif + void gil_fake_get() {} void gil_fake_release() {} diff --git a/plugins/python/profiler.c b/plugins/python/profiler.c index abd7f79b..c374ca6a 100644 --- a/plugins/python/profiler.c +++ b/plugins/python/profiler.c @@ -15,6 +15,7 @@ int PyFrame_GetLineNumber(PyFrameObject *frame) { int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) { +#ifndef UWSGI_PYPY switch(what) { case PyTrace_CALL: uwsgi_log("[uWSGI Python profiler] CALL: %s (line %d) -> %s %d args, stacksize %d\n", @@ -29,6 +30,7 @@ int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, Py PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize); break; } +#endif return 0; } diff --git a/plugins/python/pyloader.c b/plugins/python/pyloader.c index 321033b4..e02ddf52 100644 --- a/plugins/python/pyloader.c +++ b/plugins/python/pyloader.c @@ -160,6 +160,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre } } +#ifdef UWSGI_MINTERPRETERS if (interpreter == NULL && id) { wi->interpreter = Py_NewInterpreter(); @@ -184,10 +185,11 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre wi->interpreter = up.main_thread; } -#ifdef UWSGI_MINTERPRETERS if (wsgi_req->pyhome_len) { set_dyn_pyhome(wsgi_req->pyhome, wsgi_req->pyhome_len); } +#else + wi->interpreter = up.main_thread; #endif if (wsgi_req->touch_reload_len) { @@ -424,6 +426,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre doh: free(mountpoint); PyErr_Print(); +#ifdef UWSGI_MINTERPRETERS if (interpreter == NULL && id) { Py_EndInterpreter(wi->interpreter); if (uwsgi.threads > 1) { @@ -433,6 +436,7 @@ doh: PyThreadState_Swap(up.main_thread); } } +#endif return -1; } @@ -477,7 +481,9 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) { PyObject *tmp_callable; PyObject *applications; +#ifndef UWSGI_PYPY PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); +#endif char *module = (char *) arg1; @@ -500,8 +506,10 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) { return NULL; } +#ifndef UWSGI_PYPY applications = PyDict_GetItemString(uwsgi_dict, "applications"); if (applications && PyDict_Check(applications)) return applications; +#endif applications = PyDict_GetItemString(wsgi_dict, "applications"); @@ -672,6 +680,8 @@ PyObject *uwsgi_paste_loader(void *arg1) { PyObject *uwsgi_eval_loader(void *arg1) { +#ifndef UWSGI_PYPY + char *code = (char *) arg1; PyObject *wsgi_eval_module, *wsgi_eval_callable = NULL; @@ -727,6 +737,9 @@ PyObject *uwsgi_eval_loader(void *arg1) { } return wsgi_eval_callable; +#else + return NULL; +#endif } diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index a45984fc..f1bc0b19 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -47,7 +47,9 @@ struct option uwsgi_python_options[] = { {"ignore-script-name", no_argument, &up.ignore_script_name, 1}, {"pep3333-input", no_argument, &up.pep3333_input, 1}, {"reload-os-env", no_argument, &up.reload_os_env, 1}, +#ifndef UWSGI_PYPY {"no-site", no_argument, &Py_NoSiteFlag, 1}, +#endif {"pyshell", no_argument, 0, LONG_ARGS_PYSHELL}, {0, 0, 0, 0}, @@ -100,9 +102,14 @@ PyMethodDef uwsgi_write_method[] = { {"uwsgi_write", py_uwsgi_write, METH_VARARG int uwsgi_python_init() { +#ifndef UWSGI_PYPY char *pyversion = strchr(Py_GetVersion(), '\n'); uwsgi_log("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1); +#else + uwsgi_log("PyPy version: %s\n", PYPY_VERSION); +#endif +#ifndef UWSGI_PYPY if (up.home != NULL) { #ifdef PYTHREE wchar_t *wpyhome; @@ -135,6 +142,8 @@ int uwsgi_python_init() { Py_OptimizeFlag = up.optimize; +#endif + up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL); up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL); @@ -156,6 +165,7 @@ int uwsgi_python_init() { void uwsgi_python_reset_random_seed() { +#ifndef UWSGI_PYPY PyObject *random_module, *random_dict, *random_seed; // reinitialize the random seed (thanks Jonas Borgström) @@ -175,6 +185,7 @@ void uwsgi_python_reset_random_seed() { } } } +#endif } void uwsgi_python_post_fork() { @@ -189,6 +200,7 @@ void uwsgi_python_post_fork() { uwsgi_python_reset_random_seed(); +#ifndef UWSGI_PYPY #ifdef UWSGI_EMBEDDED // call the post_fork_hook PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); @@ -200,6 +212,7 @@ void uwsgi_python_post_fork() { } PyErr_Clear(); #endif +#endif UWSGI_RELEASE_GIL @@ -207,6 +220,7 @@ UWSGI_RELEASE_GIL PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) { +#ifndef UWSGI_PYPY FILE *pyfile; struct _node *py_file_node = NULL; PyObject *py_compiled_node, *py_file_module; @@ -292,6 +306,9 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) { } return py_file_module; +#else + return NULL; +#endif } @@ -859,7 +876,9 @@ void uwsgi_python_init_apps() { if (uwsgi.async > 1) { up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async); +#ifndef UWSGI_PYPY up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async); +#endif } init_pyargv(); @@ -869,7 +888,7 @@ void uwsgi_python_init_apps() { #endif #ifdef __linux__ -#ifndef PYTHREE +#if !defined(PYTHREE) && !defined(UWSGI_PYPY) uwsgi_init_symbol_import(); #endif #endif @@ -974,9 +993,11 @@ void uwsgi_python_init_apps() { } if (uwsgi.profiler) { +#ifndef UWSGI_PYPY if (!strcmp(uwsgi.profiler, "pycall")) { PyEval_SetProfile(uwsgi_python_profiler_call, NULL); } +#endif } } @@ -1091,6 +1112,7 @@ int uwsgi_python_xml(char *node, char *content) { return 0; } +#ifndef UWSGI_PYPY void uwsgi_python_suspend(struct wsgi_request *wsgi_req) { PyThreadState *tstate = PyThreadState_GET(); @@ -1105,6 +1127,7 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) { } } +#endif char *uwsgi_python_code_string(char *id, char *code, char *function, char *key, uint16_t keylen) { @@ -1293,6 +1316,7 @@ int uwsgi_python_spooler(char *filename, char *buf, uint16_t len, char *body, si return -1; } +#ifndef UWSGI_PYPY void uwsgi_python_resume(struct wsgi_request *wsgi_req) { PyThreadState *tstate = PyThreadState_GET(); @@ -1307,6 +1331,7 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) { } } +#endif void uwsgi_python_fixup() { // set hacky modifier 30 @@ -1316,12 +1341,14 @@ void uwsgi_python_fixup() { void uwsgi_python_hijack(void) { // the pyshell will be execute only in the first worker +#ifndef UWSGI_PYPY if (up.pyshell && uwsgi.mywid == 1) { UWSGI_GET_GIL; PyImport_ImportModule("readline"); PyRun_InteractiveLoop(stdin, "uwsgi"); exit(0); } +#endif } struct uwsgi_plugin python_plugin = { @@ -1349,8 +1376,10 @@ struct uwsgi_plugin python_plugin = { .magic = uwsgi_python_magic, +#ifndef UWSGI_PYPY .suspend = uwsgi_python_suspend, .resume = uwsgi_python_resume, +#endif .hijack_worker = uwsgi_python_hijack, .spooler_init = uwsgi_python_spooler_init, diff --git a/plugins/python/pyutils.c b/plugins/python/pyutils.c index b59370d2..b1b05160 100644 --- a/plugins/python/pyutils.c +++ b/plugins/python/pyutils.c @@ -105,7 +105,9 @@ void init_pyargv() { } } +#ifndef UWSGI_PYPY PySys_SetArgv(up.argc, up.py_argv); +#endif PyObject *sys_dict = get_uwsgi_pydict("sys"); if (!sys_dict) { diff --git a/plugins/python/symimporter.c b/plugins/python/symimporter.c index 2ced4aca..2e1361c8 100644 --- a/plugins/python/symimporter.c +++ b/plugins/python/symimporter.c @@ -1,6 +1,6 @@ #include "uwsgi_python.h" -#ifndef PYTHREE +#if !defined(PYTHREE) && !defined(UWSGI_PYPY) extern struct uwsgi_server uwsgi; extern struct uwsgi_python up; diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index b1e26dd9..8698c219 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1499,7 +1499,6 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) { PyObject *arg_modifier1, *arg_modifier2, *arg_timeout; - PyObject *marshalled; PyObject *retobject; @@ -1568,6 +1567,8 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) { } +#ifndef UWSGI_PYPY + PyObject *marshalled; switch (PyInt_AsLong(arg_modifier1)) { case UWSGI_MODIFIER_MESSAGE_MARSHAL: marshalled = PyMarshal_WriteObjectToString(arg_message, 1); @@ -1582,6 +1583,7 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) { } break; } +#endif } @@ -1909,7 +1911,7 @@ PyObject *py_uwsgi_async_connect(PyObject * self, PyObject * args) { PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) { - PyObject *pyobj = NULL, *marshalled = NULL; + PyObject *pyobj = NULL; int uwsgi_fd; int modifier1 = 0; @@ -1938,8 +1940,9 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) { esize = PyString_Size(pyobj); UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0); } +#ifndef UWSGI_PYPY else { - marshalled = PyMarshal_WriteObjectToString(pyobj, 1); + PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1); if (!marshalled) { PyErr_Print(); goto clear; @@ -1949,6 +1952,7 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) { esize = PyString_Size(marshalled); UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0); } +#endif UWSGI_GET_GIL clear: @@ -2049,7 +2053,7 @@ PyObject *py_uwsgi_fcgi(PyObject * self, PyObject * args) { PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) { - PyObject *destination = NULL, *pyobj = NULL, *marshalled = NULL; + PyObject *destination = NULL, *pyobj = NULL; int modifier1 = 0; int modifier2 = 0; @@ -2094,8 +2098,9 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) { esize = PyString_Size(pyobj); UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout); } +#ifndef UWSGI_PYPY else { - marshalled = PyMarshal_WriteObjectToString(pyobj, 1); + PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1); if (!marshalled) { PyErr_Print(); goto clear; @@ -2105,6 +2110,7 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) { esize = PyString_Size(marshalled); UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout); } +#endif UWSGI_GET_GIL diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index b5236838..36b8ab50 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -264,6 +264,10 @@ void uwsgi_python_reset_random_seed(void); char *uwsgi_pythonize(char *); +#ifdef UWSGI_PYPY +#undef UWSGI_MINTERPRETERS +#endif + #define uwsgi_pyexit {PyErr_Print();exit(1);} #ifdef __linux__ diff --git a/plugins/python/uwsgiplugin.py b/plugins/python/uwsgiplugin.py index 3a8832f4..ffcdfa89 100644 --- a/plugins/python/uwsgiplugin.py +++ b/plugins/python/uwsgiplugin.py @@ -6,6 +6,10 @@ NAME='python' GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter'] CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ] + +if 'pypy_version_info' in sys.__dict__: + CFLAGS.append('-DUWSGI_PYPY') + LDFLAGS = [] if not 'UWSGI_PYTHON_NOLIB' in os.environ: diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index dec1277e..a3533f93 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -43,6 +43,8 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ } } + +#ifndef UWSGI_PYPY // if async_post is mapped as a file, directly use it as wsgi.input if (wsgi_req->async_post) { #ifdef PYTHREE @@ -61,7 +63,9 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ } + PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input); +#endif #ifdef UWSGI_SENDFILE PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile); @@ -77,12 +81,16 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version); - zero = PyFile_FromFile(stderr, "wsgi_input", "w", NULL); +#ifndef UWSGI_PYPY + zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero); Py_DECREF(zero); +#endif PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False); + + if (uwsgi.threads > 1) { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_True); } @@ -116,10 +124,13 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ wsgi_req->async_app = wi->callable; + // export .env only in non-threaded mode +#ifndef UWSGI_PYPY if (uwsgi.threads < 2) { PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ); } +#endif PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version); diff --git a/pyuwsgi_run.py b/pyuwsgi_run.py index 68437b76..0bedd8e9 100644 --- a/pyuwsgi_run.py +++ b/pyuwsgi_run.py @@ -10,9 +10,10 @@ uwsgi_args = [] uwsgi_args.append('--socket') uwsgi_args.append(':3031') -uwsgi_args.append('--master') +#uwsgi_args.append('--master') uwsgi_args.append('--module') -uwsgi_args.append('welcome') +#uwsgi_args.append('welcome') +uwsgi_args.append('hello') #pyuwsgi.run('welcome.ini') pyuwsgi.run(uwsgi_args)