Ejemplo n.º 1
0
PyObject *uwsgi_uwsgi_loader(void *arg1) {

	PyObject *wsgi_dict;

	char *quick_callable;

	PyObject *tmp_callable;
	PyObject *applications;
	PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");

	char *module = (char *) arg1;

	quick_callable = get_uwsgi_pymodule(module);
	if (quick_callable == NULL) {
		if (up.callable) {
			quick_callable = up.callable;
		}
		else {
			quick_callable = "application";
		}
		wsgi_dict = get_uwsgi_pydict(module);
	}
	else {
		wsgi_dict = get_uwsgi_pydict(module);
		module[strlen(module)] = ':';
	}

	if (!wsgi_dict) {
		return NULL;
	}

	applications = PyDict_GetItemString(uwsgi_dict, "applications");
	if (applications && PyDict_Check(applications)) return applications;

	applications = PyDict_GetItemString(wsgi_dict, "applications");
	if (applications && PyDict_Check(applications)) return applications;

	// quick callable -> thanks gunicorn for the idea
	// we have extended the concept a bit...
	if (quick_callable[strlen(quick_callable) -2 ] == '(' && quick_callable[strlen(quick_callable) -1] ==')') {
		quick_callable[strlen(quick_callable) -2 ] = 0;
		tmp_callable = PyDict_GetItemString(wsgi_dict, quick_callable);
		quick_callable[strlen(quick_callable)] = '(';
		if (tmp_callable) {
			return python_call(tmp_callable, PyTuple_New(0), 0, NULL);
		}
	}

	return PyDict_GetItemString(wsgi_dict, quick_callable);

}
Ejemplo n.º 2
0
void uwsgi_python_post_fork() {

#ifdef UWSGI_SPOOLER
	if (uwsgi.i_am_a_spooler) {
		UWSGI_GET_GIL
	}	
#endif

	uwsgi_python_reset_random_seed();

#ifdef UWSGI_EMBEDDED
	// call the post_fork_hook
	PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
	if (uwsgi_dict) {
		PyObject *pfh = PyDict_GetItemString(uwsgi_dict, "post_fork_hook");
		if (pfh) {
			python_call(pfh, PyTuple_New(0), 0, NULL);
		}
	}
	PyErr_Clear();
#endif

	if (uwsgi.mywid > 0) {
#ifdef UWSGI_THREADING
		if (up.auto_reload) {
			// spawn the reloader thread
			pthread_t par_tid;
			pthread_create(&par_tid, NULL, uwsgi_python_autoreloader_thread, NULL);
		}
#endif
	}

UWSGI_RELEASE_GIL

}
Ejemplo n.º 3
0
static void monkey_patch() {
	PyObject *gevent_monkey_dict = get_uwsgi_pydict("gevent.monkey");
        if (!gevent_monkey_dict) uwsgi_pyexit;
        PyObject *gevent_monkey_patch_all = PyDict_GetItemString(gevent_monkey_dict, "patch_all");
        if (!gevent_monkey_patch_all) uwsgi_pyexit;
        PyObject *ret = python_call(gevent_monkey_patch_all, PyTuple_New(0), 0, NULL);
        if (!ret) uwsgi_pyexit;
}
Ejemplo n.º 4
0
void uwsgi_python_atexit() {

	if (uwsgi.mywid == -1) goto realstuff;

	// if hijacked do not run atexit hooks
	if (uwsgi.workers[uwsgi.mywid].hijacked)
		return;

	// if busy do not run atexit hooks
	if (uwsgi.workers[uwsgi.mywid].busy)
		return;

#ifdef UWSGI_ASYNC
	// managing atexit in async mode is a real pain...skip it for now
	if (uwsgi.async > 1)
		return;
#endif

realstuff:

	// this time we use this higher level function
	// as this code can be executed in a signal handler

	if (!Py_IsInitialized()) {
		return;
	}

	if (uwsgi.has_threads)
		PyGILState_Ensure();
	// no need to worry about freeing memory
#ifdef UWSGI_EMBEDDED
	PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
	if (uwsgi_dict) {
		PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit");
		if (ae) {
			python_call(ae, PyTuple_New(0), 0, NULL);
		}
	}
#endif

	// this part is a 1:1 copy of mod_wsgi 3.x
        // it is required to fix some atexit bug with python 3
	// and to shutdown useless threads complaints
	PyObject *module = PyImport_ImportModule("atexit");
	Py_XDECREF(module);

	if (uwsgi.has_threads) {
		if (!PyImport_AddModule("dummy_threading"))
			PyErr_Clear();
	}

	Py_Finalize();
}
Ejemplo n.º 5
0
void set_dyn_pyhome(char *home, uint16_t pyhome_len) {


	char venv_version[15];
	PyObject *site_module;

	PyObject *pysys_dict = get_uwsgi_pydict("sys");

	PyObject *pypath = PyDict_GetItemString(pysys_dict, "path");
	if (!pypath) {
		PyErr_Print();
		exit(1);
	}

        // simulate a pythonhome directive
        if (uwsgi.wsgi_req->home_len > 0) {

                PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->home, uwsgi.wsgi_req->home_len);

#ifdef UWSGI_DEBUG
                uwsgi_debug("setting dynamic virtualenv to %.*s\n", uwsgi.wsgi_req->home_len, uwsgi.wsgi_req->home);
#endif

                PyDict_SetItemString(pysys_dict, "prefix", venv_path);
                PyDict_SetItemString(pysys_dict, "exec_prefix", venv_path);

                venv_version[14] = 0;
                if (snprintf(venv_version, 15, "/lib/python%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION) == -1) {
                        return;
                }

                // check here
                PyString_Concat(&venv_path, PyString_FromString(venv_version));

                if (PyList_Insert(pypath, 0, venv_path)) {
                        PyErr_Print();
                }

                site_module = PyImport_ImportModule("site");
                if (site_module) {
                        PyImport_ReloadModule(site_module);
                }

        }
}
Ejemplo n.º 6
0
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) {

	uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        uwsgi.workers[uwsgi.mywid].manage_next_request = 0;

	uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL);
	PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL);

	uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	int i,count = uwsgi_count_sockets(uwsgi.sockets);
	for(i=0;i<count;i++) {
		PyObject_CallMethod(ugevent.watchers[i], "stop", NULL);
	}
	uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);

	int running_cores = 0;
	for(i=0;i<uwsgi.async;i++) {
		if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) {
			struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req;
			uwsgi_log_verbose("worker %d (pid: %d) core %d is managing \"%.*s %.*s\" for %.*s\n", uwsgi.mywid, uwsgi.mypid, i, 
				wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri,
				wsgi_req->remote_addr_len, wsgi_req->remote_addr);
			running_cores++;
		}
	}

	if (running_cores > 0) {
		uwsgi_log_verbose("waiting for %d running requests on worker %d (pid: %d)...\n", running_cores, uwsgi.mywid, uwsgi.mypid);
	} else {
            // no need to worry about freeing memory
            PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
            if (uwsgi_dict) {
              PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit");
              if (ae) {
                python_call(ae, PyTuple_New(0), 0, NULL);
              }
            }
        }

	Py_INCREF(Py_None);
	return Py_None;
}
Ejemplo n.º 7
0
void uwsgi_python_init_apps() {

	struct http_status_codes *http_sc;

#ifndef UWSGI_PYPY
	// prepare for stack suspend/resume
	if (uwsgi.async > 1) {
		up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
        	up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
	}
#endif

        // setup app loaders
#ifdef UWSGI_MINTERPRETERS
        up.loaders[LOADER_DYN] = uwsgi_dyn_loader;
#endif
        up.loaders[LOADER_UWSGI] = uwsgi_uwsgi_loader;
        up.loaders[LOADER_FILE] = uwsgi_file_loader;
        up.loaders[LOADER_PASTE] = uwsgi_paste_loader;
        up.loaders[LOADER_EVAL] = uwsgi_eval_loader;
        up.loaders[LOADER_MOUNT] = uwsgi_mount_loader;
        up.loaders[LOADER_CALLABLE] = uwsgi_callable_loader;
        up.loaders[LOADER_STRING_CALLABLE] = uwsgi_string_callable_loader;


	struct uwsgi_string_list *upli = up.import_list;
	while(upli) {
		if (strchr(upli->value, '/') || uwsgi_endswith(upli->value, ".py")) {
			uwsgi_pyimport_by_filename(uwsgi_pythonize(upli->value), upli->value);
		}
		else {
			if (PyImport_ImportModule(upli->value) == NULL) {
				PyErr_Print();
			}
		}
		upli = upli->next;
	}

	struct uwsgi_string_list *uppa = up.post_pymodule_alias;
	PyObject *modules = PyImport_GetModuleDict();
	PyObject *tmp_module;
	while(uppa) {
                // split key=value
                char *value = strchr(uppa->value, '=');
                if (!value) {
                        uwsgi_log("invalid pymodule-alias syntax\n");
			goto next;
                }
                value[0] = 0;
                if (!strchr(value + 1, '/')) {
                        // this is a standard pymodule
                        tmp_module = PyImport_ImportModule(value + 1);
                        if (!tmp_module) {
                                PyErr_Print();
                                exit(1);
                        }

                        PyDict_SetItemString(modules, uppa->value, tmp_module);
                }
                else {
                        // this is a filepath that need to be mapped
                        tmp_module = uwsgi_pyimport_by_filename(uppa->value, value + 1);
                        if (!tmp_module) {
                                PyErr_Print();
                                exit(1);
                        }
                }
                uwsgi_log("mapped virtual pymodule \"%s\" to real pymodule \"%s\"\n", uppa->value, value + 1);
                // reset original value
                value[0] = '=';

next:
		uppa = uppa->next;
        }


	if (up.wsgi_config != NULL) {
		init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
	}

	if (up.file_config != NULL) {
		init_uwsgi_app(LOADER_FILE, up.file_config, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
	}
	if (up.paste != NULL) {
		init_uwsgi_app(LOADER_PASTE, up.paste, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
	}
	if (up.eval != NULL) {
		init_uwsgi_app(LOADER_EVAL, up.eval, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
	}
	if (up.web3 != NULL) {
		init_uwsgi_app(LOADER_UWSGI, up.web3, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WEB3);
	}
	if (up.pump != NULL) {
		init_uwsgi_app(LOADER_UWSGI, up.pump, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_PUMP);
		// filling http status codes
        	for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
                	http_sc->message_size = (int) strlen(http_sc->message);
        	}
	}
	if (up.wsgi_lite != NULL) {
		init_uwsgi_app(LOADER_UWSGI, up.wsgi_lite, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI_LITE);
	}

#ifndef UWSGI_PYPY
	if (uwsgi.profiler) {
		if (!strcmp(uwsgi.profiler, "pycall")) {
			PyEval_SetProfile(uwsgi_python_profiler_call, NULL);
		}
		else if (!strcmp(uwsgi.profiler, "pyline")) {
			PyEval_SetTrace(uwsgi_python_tracer, NULL);
		}
	}
#endif

	PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
        if (uwsgi_dict) {
                up.after_req_hook = PyDict_GetItemString(uwsgi_dict, "after_req_hook");
                if (up.after_req_hook) {
			Py_INCREF(up.after_req_hook);
			up.after_req_hook_args = PyTuple_New(0);
			Py_INCREF(up.after_req_hook_args);
		}
	}

}
Ejemplo n.º 8
0
int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter, int app_type) {

	PyObject *app_list = NULL, *applications = NULL;


	if (uwsgi_apps_cnt >= uwsgi.max_apps) {
		uwsgi_log("ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps);
		return -1;
	}


	int id = uwsgi_apps_cnt;

	int multiapp = 0;

	int i;

	struct uwsgi_app *wi;

	time_t now = uwsgi_now();

	if (uwsgi_get_app_id(NULL, wsgi_req->appid, wsgi_req->appid_len, -1) != -1) {
		uwsgi_log( "mountpoint %.*s already configured. skip.\n", wsgi_req->appid_len, wsgi_req->appid);
		return -1;
	}

	wi = &uwsgi_apps[id];

	memset(wi, 0, sizeof(struct uwsgi_app));
	wi->mountpoint_len = wsgi_req->appid_len < 0xff ? wsgi_req->appid_len : (0xff-1);
	strncpy(wi->mountpoint, wsgi_req->appid, wi->mountpoint_len);

	// dynamic chdir ?
	if (wsgi_req->chdir_len > 0) {
		strncpy(wi->chdir, wsgi_req->chdir, wsgi_req->chdir_len < 0xff ? wsgi_req->chdir_len : (0xff-1));
#ifdef UWSGI_DEBUG
		uwsgi_debug("chdir to %s\n", wi->chdir);
#endif
		if (chdir(wi->chdir)) {
			uwsgi_error("chdir()");
		}
	}

	// Initialize a new environment for the new interpreter

	// reload "os" environ to allow dynamic setenv()
	if (up.reload_os_env) {

                char **e, *p;
                PyObject *k, *env_value;

        	PyObject *os_module = PyImport_ImportModule("os");
        	if (os_module) {
                	PyObject *os_module_dict = PyModule_GetDict(os_module);
                	PyObject *py_environ = PyDict_GetItemString(os_module_dict, "environ");
			if (py_environ) {
                		for (e = environ; *e != NULL; e++) {
                        		p = strchr(*e, '=');
                        		if (p == NULL) continue;

					k = PyString_FromStringAndSize(*e, (int)(p-*e));
					if (k == NULL) {
                                		PyErr_Print();
                                		continue;
					}

                        		env_value = PyString_FromString(p+1);
                        		if (env_value == NULL) {
                                		PyErr_Print();
						Py_DECREF(k);
                                		continue;
                        		}
	
#ifdef UWSGI_DEBUG
					uwsgi_log("%s = %s\n", PyString_AsString(k), PyString_AsString(env_value));
#endif

                        		if (PyObject_SetItem(py_environ, k, env_value)) {
                                		PyErr_Print();
                        		}

                        		Py_DECREF(k);
                        		Py_DECREF(env_value);

                	}

		}
        	}
	}

	if (interpreter == NULL && id) {

		wi->interpreter = Py_NewInterpreter();
		if (!wi->interpreter) {
			uwsgi_log( "unable to initialize the new python interpreter\n");
			exit(1);
		}
		PyThreadState_Swap(wi->interpreter);
		init_pyargv();

		// we need to inizialize an embedded module for every interpreter
		init_uwsgi_embedded_module();
		init_uwsgi_vars();

	}
	else if (interpreter) {
		wi->interpreter = interpreter;
	}
	else {
		wi->interpreter = up.main_thread;
	}

	if (wsgi_req->home_len) {
		set_dyn_pyhome(wsgi_req->home, wsgi_req->home_len);
	}

	if (wsgi_req->touch_reload_len > 0 && wsgi_req->touch_reload_len < 0xff) {
		struct stat trst;
		strncpy(wi->touch_reload, wsgi_req->touch_reload, wsgi_req->touch_reload_len);
		if (!stat(wi->touch_reload, &trst)) {
			wi->touch_reload_mtime = trst.st_mtime;
		}
	}

	wi->callable = up.loaders[loader](arg1);

	if (!wi->callable) {
		uwsgi_log("unable to load app %d (mountpoint='%s') (callable not found or import error)\n", id, wi->mountpoint);
		goto doh;
	}

	// the module contains multiple apps
	if (PyDict_Check((PyObject *)wi->callable)) {
		applications = wi->callable;
		uwsgi_log("found a multiapp module...\n");
		app_list = PyDict_Keys(applications);
		multiapp = PyList_Size(app_list);
		if (multiapp < 1) {
			uwsgi_log("you have to define at least one app in the apllications dictionary\n");
			goto doh;
		}		

		PyObject *app_mnt = PyList_GetItem(app_list, 0);
		if (!PyString_Check(app_mnt)) {
			uwsgi_log("the app mountpoint must be a string\n");
			goto doh;
		}
		char *tmp_mountpoint = PyString_AsString(app_mnt);
		wi->mountpoint_len = strlen(wi->mountpoint) < 0xff ? strlen(wi->mountpoint) : (0xff-1);
		strncpy(wi->mountpoint, tmp_mountpoint, wi->mountpoint_len);
		wsgi_req->appid = wi->mountpoint;
		wsgi_req->appid_len = wi->mountpoint_len;
#ifdef UWSGI_DEBUG
		uwsgi_log("main mountpoint = %s\n", wi->mountpoint);
#endif
		wi->callable = PyDict_GetItem(applications, app_mnt);
		if (PyString_Check((PyObject *) wi->callable)) {
			PyObject *callables_dict = get_uwsgi_pydict((char *)arg1);
			if (callables_dict) {
				wi->callable = PyDict_GetItem(callables_dict, (PyObject *)wi->callable);	
			}
		}
	}

	Py_INCREF((PyObject *)wi->callable);

	wi->environ = malloc(sizeof(PyObject*)*uwsgi.cores);
	if (!wi->environ) {
		uwsgi_error("malloc()");
		exit(1);
	}

	for(i=0;i<uwsgi.cores;i++) {
		wi->environ[i] = PyDict_New();
		if (!wi->environ[i]) {
			uwsgi_log("unable to allocate new env dictionary for app\n");
			exit(1);
		}
	}

	wi->argc = 1;

	if (app_type == PYTHON_APP_TYPE_WSGI) {
#ifdef UWSGI_DEBUG
		uwsgi_log("-- WSGI callable selected --\n");
#endif
		wi->request_subhandler = uwsgi_request_subhandler_wsgi;
		wi->response_subhandler = uwsgi_response_subhandler_wsgi;
		wi->argc = 2;
	}
	else if (app_type == PYTHON_APP_TYPE_WEB3) {
#ifdef UWSGI_DEBUG
		uwsgi_log("-- Web3 callable selected --\n");
#endif
		wi->request_subhandler = uwsgi_request_subhandler_web3;
		wi->response_subhandler = uwsgi_response_subhandler_web3;
	}
	else if (app_type == PYTHON_APP_TYPE_PUMP) {
#ifdef UWSGI_DEBUG
		uwsgi_log("-- Pump callable selected --\n");
#endif
		wi->request_subhandler = uwsgi_request_subhandler_pump;
		wi->response_subhandler = uwsgi_response_subhandler_pump;
	}

	wi->args = malloc(sizeof(PyObject*)*uwsgi.cores);
	if (!wi->args) {
		uwsgi_error("malloc()");
		exit(1);
	}

	for(i=0;i<uwsgi.cores;i++) {
		wi->args[i] = PyTuple_New(wi->argc);
		if (!wi->args[i]) {
			uwsgi_log("unable to allocate new tuple for app args\n");
			exit(1);
		}

		// add start_response on WSGI app
		Py_INCREF((PyObject *)up.wsgi_spitout);
		if (app_type == PYTHON_APP_TYPE_WSGI) {
			if (PyTuple_SetItem(wi->args[i], 1, up.wsgi_spitout)) {
				uwsgi_log("unable to set start_response in args tuple\n");
				exit(1);
			}
		}
	}

	if (app_type == PYTHON_APP_TYPE_WSGI) {
		// prepare sendfile() for WSGI app
		wi->sendfile = PyCFunction_New(uwsgi_sendfile_method, NULL);

		wi->eventfd_read = PyCFunction_New(uwsgi_eventfd_read_method, NULL);
		wi->eventfd_write = PyCFunction_New(uwsgi_eventfd_write_method, NULL);
	}

	// cache most used values
	wi->error = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL);
	Py_INCREF((PyObject *)wi->error);

	wi->gateway_version = PyTuple_New(2);
        PyTuple_SetItem(wi->gateway_version, 0, PyInt_FromLong(1));
        PyTuple_SetItem(wi->gateway_version, 1, PyInt_FromLong(0));
	Py_INCREF((PyObject *)wi->gateway_version);

	wi->uwsgi_version = PyString_FromString(UWSGI_VERSION);
	Py_INCREF((PyObject *)wi->uwsgi_version);

	wi->uwsgi_node = PyString_FromString(uwsgi.hostname);
	Py_INCREF((PyObject *)wi->uwsgi_node);

	if (uwsgi.threads > 1 && id) {
		// if we have multiple threads we need to initialize a PyThreadState for each one
		for(i=0;i<uwsgi.threads;i++) {
			//uwsgi_log("%p\n", uwsgi.core[i]->ts[id]);
			uwsgi.workers[uwsgi.mywid].cores[i].ts[id] = PyThreadState_New( ((PyThreadState *)wi->interpreter)->interp);
			if (!uwsgi.workers[uwsgi.mywid].cores[i].ts[id]) {
				uwsgi_log("unable to allocate new PyThreadState structure for app %s", wi->mountpoint);
				goto doh;
			}
		}
		PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_save_key) );
	}
	else if (interpreter == NULL && id) {
		PyThreadState_Swap(up.main_thread);
	}

	const char *default_app = "";

	if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
		default_app = " (default app)" ;
		uwsgi.default_app = id;
	}

	wi->started_at = now;
	wi->startup_time = uwsgi_now() - now;

	if (app_type == PYTHON_APP_TYPE_WSGI) {
		uwsgi_log( "WSGI app %d (mountpoint='%.*s') ready in %d seconds on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, (int) wi->startup_time, wi->interpreter, (int) getpid(), default_app);
	}
	else if (app_type == PYTHON_APP_TYPE_WEB3) {
		uwsgi_log( "Web3 app %d (mountpoint='%.*s') ready in %d seconds on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, (int) wi->startup_time, wi->interpreter, (int) getpid(), default_app);
	}
	else if (app_type == PYTHON_APP_TYPE_PUMP) {
		uwsgi_log( "Pump app %d (mountpoint='%.*s') ready in %d seconds on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, (int) wi->startup_time, wi->interpreter, (int) getpid(), default_app);
	}


	uwsgi_apps_cnt++;

	if (multiapp > 1) {
		for(i=1;i<multiapp;i++) {
			PyObject *app_mnt = PyList_GetItem(app_list, i);		
			if (!PyString_Check(app_mnt)) {
				uwsgi_log("applications dictionary key must be a string, skipping.\n");
				continue;
			}

			wsgi_req->appid = PyString_AsString(app_mnt);
			wsgi_req->appid_len = strlen(wsgi_req->appid);
			PyObject *a_callable = PyDict_GetItem(applications, app_mnt);
			if (PyString_Check(a_callable)) {

				PyObject *callables_dict = get_uwsgi_pydict((char *)arg1);
				if (callables_dict) {
					a_callable = PyDict_GetItem(callables_dict, a_callable);
				}
			}
			if (!a_callable) {
				uwsgi_log("skipping broken app %s\n", wsgi_req->appid);
				continue;
			}
			init_uwsgi_app(LOADER_CALLABLE, a_callable, wsgi_req, wi->interpreter, app_type);
		}
	}

	// emulate COW
	uwsgi_emulate_cow_for_apps(id);

	return id;

doh:
	if (PyErr_Occurred())
		PyErr_Print();
	if (interpreter == NULL && id) {
		Py_EndInterpreter(wi->interpreter);
		if (uwsgi.threads > 1) {
			PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_save_key));
		}
		else {
			PyThreadState_Swap(up.main_thread);
		}
	}
	return -1;
}
Ejemplo n.º 9
0
PyObject *uwsgi_paste_loader(void *arg1) {

	char *paste = (char *) arg1;
	PyObject *paste_module, *paste_dict, *paste_loadapp;
	PyObject *paste_arg, *paste_app;

	uwsgi_log( "Loading paste environment: %s\n", paste);

	if (up.paste_logger) {
		PyObject *paste_logger_dict = get_uwsgi_pydict("paste.script.util.logging_config");	
		if (paste_logger_dict) {
			PyObject *paste_logger_fileConfig = PyDict_GetItemString(paste_logger_dict, "fileConfig");
			if (paste_logger_fileConfig) {
				PyObject *paste_logger_arg = PyTuple_New(1);
				if (!paste_logger_arg) {
					PyErr_Print();
					exit(UWSGI_FAILED_APP_CODE);
				}
				PyTuple_SetItem(paste_logger_arg, 0, UWSGI_PYFROMSTRING(paste+7));
				if (python_call(paste_logger_fileConfig, paste_logger_arg, 0, NULL)) {
					PyErr_Print();
				}
			}
		}
	}

	paste_module = PyImport_ImportModule("paste.deploy");
	if (!paste_module) {
		PyErr_Print();
		exit(UWSGI_FAILED_APP_CODE);
	}

	paste_dict = PyModule_GetDict(paste_module);
	if (!paste_dict) {
		PyErr_Print();
		exit(UWSGI_FAILED_APP_CODE);
	}

	paste_loadapp = PyDict_GetItemString(paste_dict, "loadapp");
	if (!paste_loadapp) {
		PyErr_Print();
		exit(UWSGI_FAILED_APP_CODE);
	}

	paste_arg = PyTuple_New(1);
	if (!paste_arg) {
		PyErr_Print();
		exit(UWSGI_FAILED_APP_CODE);
	}

	if (PyTuple_SetItem(paste_arg, 0, UWSGI_PYFROMSTRING(paste))) {
		PyErr_Print();
		exit(UWSGI_FAILED_APP_CODE);
	}

	paste_app = PyEval_CallObject(paste_loadapp, paste_arg);
	if (!paste_app) {
		PyErr_Print();
		exit(UWSGI_FAILED_APP_CODE);
	}


	return paste_app;
}
Ejemplo n.º 10
0
static void gevent_loop() {

    if (!uwsgi.has_threads && uwsgi.mywid == 1) {
        uwsgi_log("!!! Running gevent without threads IS NOT recommended, enable them with --enable-threads !!!\n");
    }

    if (uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] < 30) {
        uwsgi_log("!!! Running gevent with a socket-timeout lower than 30 seconds is not recommended, tune it with --socket-timeout !!!\n");
    }

    // get the GIL
    UWSGI_GET_GIL

    up.gil_get = gil_gevent_get;
    up.gil_release = gil_gevent_release;

    uwsgi.wait_write_hook = uwsgi_gevent_wait_write_hook;
    uwsgi.wait_read_hook = uwsgi_gevent_wait_read_hook;

    struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;

    if (uwsgi.async < 2) {
        uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n");
        exit(1);
    }

    uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req;

    PyObject *gevent_dict = get_uwsgi_pydict("gevent");
    if (!gevent_dict) uwsgi_pyexit;

    PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
    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");
        exit(1);
    }

    ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
    if (!ugevent.spawn) uwsgi_pyexit;

    ugevent.signal = PyDict_GetItemString(gevent_dict, "signal");
    if (!ugevent.signal) uwsgi_pyexit;

    ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
    if (!ugevent.greenlet_switch) uwsgi_pyexit;

    ugevent.greenlet_switch_args = PyTuple_New(0);
    Py_INCREF(ugevent.greenlet_switch_args);


    PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");

    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) uwsgi_pyexit;

    ugevent.get_current_args = PyTuple_New(0);
    Py_INCREF(ugevent.get_current_args);


    ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop");
    if (!ugevent.hub_loop) uwsgi_pyexit;

    // main greenlet waiting for connection (one greenlet per-socket)
    PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
    Py_INCREF(uwsgi_gevent_main);

    // 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_request_greenlet);

    if (uwsgi.signal_socket > -1) {
        // and these are the watcher for signal sockets

        ugevent.signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1);
        if (!ugevent.signal_watcher) uwsgi_pyexit;

        ugevent.my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
        if (!ugevent.my_signal_watcher) uwsgi_pyexit;

        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(ugevent.signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit;
        if (!PyObject_CallMethod(ugevent.my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit;

    }

    // start a greenlet for each socket
    ugevent.watchers = uwsgi_malloc(sizeof(PyObject *) * uwsgi_count_sockets(uwsgi.sockets));
    int i = 0;
    while(uwsgi_sock) {
        // this is the watcher for server socket
        ugevent.watchers[i] = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1);
        if (!ugevent.watchers[i]) uwsgi_pyexit;

        // start the main greenlet
        PyObject_CallMethod(ugevent.watchers[i], "start", "Ol", uwsgi_gevent_main,(long)uwsgi_sock);
        uwsgi_sock = uwsgi_sock->next;
        i++;
    }

    // patch goodbye_cruel_world
    uwsgi.gbcw_hook = uwsgi_gevent_gbcw;

    // map SIGHUP with gevent.signal
    PyObject *ge_signal_tuple = PyTuple_New(2);
    PyTuple_SetItem(ge_signal_tuple, 0, PyInt_FromLong(SIGHUP));
    PyObject *uwsgi_gevent_unix_signal_handler = PyCFunction_New(uwsgi_gevent_unix_signal_handler_def, NULL);
    Py_INCREF(uwsgi_gevent_unix_signal_handler);
    PyTuple_SetItem(ge_signal_tuple, 1, uwsgi_gevent_unix_signal_handler);

    python_call(ugevent.signal, ge_signal_tuple, 0, NULL);

    for(;;) {
        if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) {
            PyErr_Print();
        }
        else {
            break;
        }
    }

    if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) {
        uwsgi_log("goodbye to the gevent Hub on worker %d (pid: %d)\n", uwsgi.mywid, uwsgi.mypid);
        if (ugevent.destroy) {
            exit(0);
        }
        exit(UWSGI_RELOAD_CODE);
    }

    uwsgi_log("the gevent Hub is no more :(\n");

}
Ejemplo n.º 11
0
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {

	PyObject *py_wsgi_req = PyTuple_GetItem(args, 0);
	struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req);

	PyObject *greenlet_switch = NULL;

	PyObject *current_greenlet = GET_CURRENT_GREENLET;
	// another hack to retrieve the current wsgi_req;
	PyObject_SetAttrString(current_greenlet, "uwsgi_wsgi_req", py_wsgi_req);

	// if in edge-triggered mode read from socket now !!!
	if (wsgi_req->socket->edge_trigger) {
		int status = wsgi_req->socket->proto(wsgi_req);
		if (status < 0) {
			goto end;
		}
		goto request;
	}

	greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch");

	for(;;) {
		int ret = uwsgi.wait_read_hook(wsgi_req->fd, uwsgi.socket_timeout);
                wsgi_req->switches++;

                if (ret <= 0) {
                        goto end;
                }

                int status = wsgi_req->socket->proto(wsgi_req);
                if (status < 0) {
                        goto end;
                }
                else if (status == 0) {
                        break;
                }
	}

request:

#ifdef UWSGI_ROUTING
	if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
		goto end;
	}
#endif

	for(;;) {
		if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) {
			goto end;
		}
		wsgi_req->switches++;
		// switch after each yield
		GEVENT_SWITCH;
	}

end:
	if (greenlet_switch) {
		Py_DECREF(greenlet_switch);
	}

	Py_DECREF(current_greenlet);

	uwsgi_close_request(wsgi_req);
	free_req_queue;


	if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) {
		int running_cores = 0;
		int i;
                for(i=0;i<uwsgi.async;i++) {
                        if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) {
                                running_cores++;
                        }
                }

                if (running_cores == 0) {
                        // no need to worry about freeing memory
                        PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
                        if (uwsgi_dict) {
                                PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit");
                                if (ae) {
                                        python_call(ae, PyTuple_New(0), 0, NULL);
                                }
                        }
                }
        } else {
                // If we stopped any watcher due to being out of async workers, restart it.
                int i = 0;
                struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
                for (; uwsgi_sock; uwsgi_sock = uwsgi_sock->next, ++i) {
                        PyObject *py_watcher_active = PyObject_GetAttrString(ugevent.watchers[i], "active");
                        if (py_watcher_active && PyBool_Check(py_watcher_active) &&
                            !PyInt_AsLong(py_watcher_active)) {
                            start_watcher(i, uwsgi_sock);
                        }
                        Py_XDECREF(py_watcher_active);
                }
        }

	Py_INCREF(Py_None);
	return Py_None;

}
Ejemplo n.º 12
0
void gevent_loop() {

	struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;

	if (uwsgi.async < 2) {
		uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n");
		exit(1);
	}


	PyObject *gevent_dict = get_uwsgi_pydict("gevent");
	if (!gevent_dict) uwsgi_pyexit;

	PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
	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");
		exit(1);
	}

	ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
	if (!ugevent.spawn) uwsgi_pyexit;

	ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
	if (!ugevent.greenlet_switch) uwsgi_pyexit;

	ugevent.greenlet_switch_args = PyTuple_New(0);
	Py_INCREF(ugevent.greenlet_switch_args);
	

	PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");

	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) uwsgi_pyexit;

	ugevent.get_current_args = PyTuple_New(0);
	Py_INCREF(ugevent.get_current_args);
	

	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) uwsgi_pyexit;

	// main greenlet waiting for connection
	PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
	Py_INCREF(uwsgi_gevent_main);

	// 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_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 *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
        	if (!my_signal_watcher) uwsgi_pyexit;

		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();
	}

	uwsgi_log("the gevent Hub is no more :(\n");

}
Ejemplo n.º 13
0
void gevent_loop() {

	if (!uwsgi.has_threads && uwsgi.mywid == 1) {
		uwsgi_log("!!! Running gevent without threads IS NOT recommended, enable them with --enable-threads !!!\n");
	}

	// get the GIL
	UWSGI_GET_GIL

	// ..then reset GIL subsystem as noop (gevent IO will take care of it...)
	up.gil_get = gil_fake_get;
        up.gil_release = gil_fake_release;

	struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;

	if (uwsgi.async < 2) {
		uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n");
		exit(1);
	}

	uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req;

	PyObject *gevent_dict = get_uwsgi_pydict("gevent");
	if (!gevent_dict) uwsgi_pyexit;

	PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
	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");
		exit(1);
	}

	ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
	if (!ugevent.spawn) uwsgi_pyexit;

	ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
	if (!ugevent.greenlet_switch) uwsgi_pyexit;

	ugevent.greenlet_switch_args = PyTuple_New(0);
	Py_INCREF(ugevent.greenlet_switch_args);
	

	PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");

	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) uwsgi_pyexit;

	ugevent.get_current_args = PyTuple_New(0);
	Py_INCREF(ugevent.get_current_args);
	

	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) uwsgi_pyexit;

	// main greenlet waiting for connection
	PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
	Py_INCREF(uwsgi_gevent_main);

	// 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_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 *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
        	if (!my_signal_watcher) uwsgi_pyexit;

		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();
	}

	uwsgi_log("the gevent Hub is no more :(\n");

}
Ejemplo n.º 14
0
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {

	PyObject *py_wsgi_req = PyTuple_GetItem(args, 0);
	struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req);

	PyObject *greenlet_switch = NULL;

	PyObject *current_greenlet = GET_CURRENT_GREENLET;
	// another hack to retrieve the current wsgi_req;
	PyObject_SetAttrString(current_greenlet, "uwsgi_wsgi_req", py_wsgi_req);

	// if in edge-triggered mode read from socket now !!!
	if (wsgi_req->socket->edge_trigger) {
		int status = wsgi_req->socket->proto(wsgi_req);
		if (status < 0) {
			goto end2;
		}
		goto request;
	}

	greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch");

	for(;;) {
		int ret = uwsgi.wait_read_hook(wsgi_req->fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
                wsgi_req->switches++;

                if (ret <= 0) {
                        goto end;
                }

                int status = wsgi_req->socket->proto(wsgi_req);
                if (status < 0) {
                        goto end;
                }
                else if (status == 0) {
                        break;
                }
	}

request:

#ifdef UWSGI_ROUTING
	if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
		goto end;
	}
#endif

	for(;;) {
		if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) {
			goto end;
		}
		wsgi_req->switches++;
		// switch after each yield
		GEVENT_SWITCH;
	}

end:
	Py_DECREF(greenlet_switch);
end2:
	Py_DECREF(current_greenlet);

	uwsgi_close_request(wsgi_req);
	free_req_queue;


	if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) {
		int running_cores = 0;
		int i;
          for(i=0;i<uwsgi.async;i++) {
            if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) {
              running_cores++;
            }
          }

          if (running_cores == 0) {
            // no need to worry about freeing memory
            PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
            if (uwsgi_dict) {
              PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit");
              if (ae) {
                python_call(ae, PyTuple_New(0), 0, NULL);
              }
            }
          }
        }

	Py_INCREF(Py_None);
	return Py_None;

}
Ejemplo n.º 15
0
static void tornado_loop() {

	if (!uwsgi.has_threads && uwsgi.mywid == 1) {
		uwsgi_log("!!! Running tornado without threads IS NOT recommended, enable them with --enable-threads !!!\n");
	}

	if (uwsgi.socket_timeout < 30) {
		uwsgi_log("!!! Running tornado with a socket-timeout lower than 30 seconds is not recommended, tune it with --socket-timeout !!!\n");
	}

	if (!uwsgi.async_waiting_fd_table)
                uwsgi.async_waiting_fd_table = uwsgi_calloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);
        if (!uwsgi.async_proto_fd_table)
                uwsgi.async_proto_fd_table = uwsgi_calloc(sizeof(struct wsgi_request *) * uwsgi.max_fd);

	// get the GIL
	UWSGI_GET_GIL

	up.gil_get = gil_tornado_get;
	up.gil_release = gil_tornado_release;

	uwsgi.wait_write_hook = uwsgi_tornado_wait_write_hook;
	uwsgi.wait_read_hook = uwsgi_tornado_wait_read_hook;

	uwsgi.schedule_fix = uwsgi_tornado_schedule_fix;

	if (uwsgi.async < 2) {
		uwsgi_log("the tornado loop engine requires async mode (--async <n>)\n");
		exit(1);
	}

	if (!uwsgi.schedule_to_main) {
                uwsgi_log("*** DANGER *** tornado mode without coroutine/greenthread engine loaded !!!\n");
        }

	PyObject *tornado_dict = get_uwsgi_pydict("tornado.ioloop");
	if (!tornado_dict) uwsgi_pyexit;

	PyObject *tornado_IOLoop = PyDict_GetItemString(tornado_dict, "IOLoop");
	if (!tornado_IOLoop) uwsgi_pyexit;

	utornado.ioloop = PyObject_CallMethod(tornado_IOLoop, "instance", NULL);
	if (!utornado.ioloop) uwsgi_pyexit;


	 // main greenlet waiting for connection (one greenlet per-socket)
        PyObject *uwsgi_tornado_accept = PyCFunction_New(uwsgi_tornado_accept_def, NULL);
	Py_INCREF(uwsgi_tornado_accept);

	utornado.request = PyCFunction_New(uwsgi_tornado_request_def, NULL);
	if (!utornado.request) uwsgi_pyexit;
	utornado.hook_fd = PyCFunction_New(uwsgi_tornado_hook_fd_def, NULL);
	if (!utornado.hook_fd) uwsgi_pyexit;
	utornado.hook_timeout = PyCFunction_New(uwsgi_tornado_hook_timeout_def, NULL);
	if (!utornado.hook_timeout) uwsgi_pyexit;
	utornado.hook_fix = PyCFunction_New(uwsgi_tornado_hook_fix_def, NULL);
	if (!utornado.hook_fix) uwsgi_pyexit;

	utornado.read = PyObject_GetAttrString(utornado.ioloop, "READ");
	if (!utornado.read) uwsgi_pyexit;
	utornado.write = PyObject_GetAttrString(utornado.ioloop, "WRITE");
	if (!utornado.write) uwsgi_pyexit;

	utornado.functools = PyImport_ImportModule("functools"); 
	if (!utornado.functools)  uwsgi_pyexit;
	
	Py_INCREF(utornado.request);
	Py_INCREF(utornado.hook_fd);
	Py_INCREF(utornado.hook_timeout);
	Py_INCREF(utornado.hook_fix);
	Py_INCREF(utornado.read);
	Py_INCREF(utornado.write);

	// call add_handler on each socket
	struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
	while(uwsgi_sock) {
		if (PyObject_CallMethod(utornado.ioloop, "add_handler", "iOO", uwsgi_sock->fd, uwsgi_tornado_accept, utornado.read) == NULL) {
			uwsgi_pyexit;
		}
		uwsgi_sock = uwsgi_sock->next;
	}	

	if (PyObject_CallMethod(utornado.ioloop, "start", NULL) == NULL) {
		uwsgi_pyexit;
	}

	// never here ?
}