Ejemplo n.º 1
0
int uwsgi_python_signal_handler(uint8_t sig, void *handler) {

	UWSGI_GET_GIL;

	PyObject *args = PyTuple_New(1);
	PyObject *ret;

	if (!args)
		goto clear;

	if (!handler) goto clear;


	PyTuple_SetItem(args, 0, PyInt_FromLong(sig));

	ret = python_call(handler, args, 0, NULL);
	Py_DECREF(args);
	if (ret) {
		Py_DECREF(ret);
		UWSGI_RELEASE_GIL;
		return 0;
	}

clear:
	UWSGI_RELEASE_GIL;
	return -1;
}
Ejemplo n.º 2
0
int uwsgi_python_mule_msg(char *message, size_t len) {

	UWSGI_GET_GIL;

	PyObject *mule_msg_hook = PyDict_GetItemString(up.embedded_dict, "mule_msg_hook");
        if (!mule_msg_hook) {
                // ignore
                UWSGI_RELEASE_GIL;
                return 0;
        }

	PyObject *pyargs = PyTuple_New(1);
        PyTuple_SetItem(pyargs, 0, PyString_FromStringAndSize(message, len));

        PyObject *ret = python_call(mule_msg_hook, pyargs, 0, NULL);
	Py_DECREF(pyargs);
	if (ret) {
		Py_DECREF(ret);
	}

	if (PyErr_Occurred())
                PyErr_Print();

	UWSGI_RELEASE_GIL;
	return 1;
}
Ejemplo n.º 3
0
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {

	// hack to retrieve the socket address
	PyObject *py_uwsgi_sock = PyTuple_GetItem(args, 0);
        struct uwsgi_socket *uwsgi_sock = (struct uwsgi_socket *) PyLong_AsLong(py_uwsgi_sock);
	struct wsgi_request *wsgi_req = NULL;
edge:
	wsgi_req = find_first_available_wsgi_req();

	if (wsgi_req == NULL) {
		uwsgi_log("async queue is full !!!\n");
		goto clear;
	}

	// fill wsgi_request structure
	wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock );

	// mark core as used
	uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1;

	wsgi_req->start_of_request = uwsgi_micros();
	wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request/1000000;

	// enter harakiri mode
        if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
                set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
        }

	// accept the connection
	if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) {
		free_req_queue;
		if (uwsgi_sock->retry && uwsgi_sock->retry[wsgi_req->async_id]) {
			goto edge;
		}	
		goto clear;
	}

// on linux we need to set the socket in non-blocking as it is not inherited
#ifdef __linux__
	uwsgi_socket_nb(wsgi_req->poll.fd);
#endif

	// hack to easily pass wsgi_req pointer to the greenlet
	PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req));

	// spawn the request greenlet
	PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL);
	Py_DECREF(new_gl);

	if (uwsgi_sock->edge_trigger) {
#ifdef UWSGI_DEBUG
		uwsgi_log("i am an edge triggered socket !!!\n");
#endif
		goto edge;
	}

clear:
	Py_INCREF(Py_None);
	return Py_None;
}
Ejemplo n.º 4
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.º 5
0
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {

	// hack to retrieve the socket address
	PyObject *py_uwsgi_sock = PyTuple_GetItem(args, 0);
        struct uwsgi_socket *uwsgi_sock = (struct uwsgi_socket *) PyLong_AsLong(py_uwsgi_sock);
        long watcher_index = PyInt_AsLong(PyTuple_GetItem(args, 1));
	struct wsgi_request *wsgi_req = NULL;
edge:
	wsgi_req = find_first_available_wsgi_req();

	if (wsgi_req == NULL) {
		uwsgi_async_queue_is_full(uwsgi_now());
                PyObject_CallMethod(ugevent.watchers[watcher_index], "stop", NULL);
		goto clear;
	}

	// fill wsgi_request structure
	wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock );

	// mark core as used
	uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1;

	// accept the connection (since uWSGI 1.5 all of the sockets are non-blocking)
	if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) {
		free_req_queue;
		if (uwsgi_sock->retry && uwsgi_sock->retry[wsgi_req->async_id]) {
			goto edge;
		}	
		// in case of errors (or thundering herd, just rest it)
		uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 0;
		goto clear;
	}

	wsgi_req->start_of_request = uwsgi_micros();
	wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request/1000000;

	// enter harakiri mode
        if (uwsgi.harakiri_options.workers > 0) {
                set_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
        }

	// hack to easily pass wsgi_req pointer to the greenlet
	PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req));

	// spawn the request greenlet
	PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL);
	Py_DECREF(new_gl);

	if (uwsgi_sock->edge_trigger) {
#ifdef UWSGI_DEBUG
		uwsgi_log("i am an edge triggered socket !!!\n");
#endif
		goto edge;
	}

clear:
	Py_INCREF(Py_None);
	return Py_None;
}
Ejemplo n.º 6
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.º 7
0
// yes copy&paste no-DRY for me :P
PyObject *py_uwsgi_gevent_my_signal(PyObject * self, PyObject * args) {

    PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.my_signal_socket));

    // spawn the signal_handler greenlet
    PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
    Py_DECREF(new_gl);

    Py_INCREF(Py_None);
    return Py_None;
}
Ejemplo n.º 8
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.º 9
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.º 10
0
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) {

	int running_cores = 0;
	int rounds = 0;

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

retry:
	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;
			if (!rounds) {
				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);
		PyObject *gevent_sleep_args = PyTuple_New(1);
		PyTuple_SetItem(gevent_sleep_args, 0, PyInt_FromLong(1));
		PyObject *gswitch = python_call(ugevent.greenlet_switch, gevent_sleep_args, 0, NULL);
		Py_DECREF(gswitch);
		Py_DECREF(gevent_sleep_args);
		rounds++;
		goto retry;
	}

	if (!ugevent.wait_for_hub) {
		PyObject_CallMethod(ugevent.ctrl_gl, "kill", NULL);
	}

	Py_INCREF(Py_None);
	return Py_None;
}
Ejemplo n.º 11
0
char *uwsgi_python_code_string(char *id, char *code, char *function, char *key, uint16_t keylen) {

	PyObject *cs_module = NULL;
	PyObject *cs_dict = NULL;

	UWSGI_GET_GIL;

	cs_module = PyImport_ImportModule(id);
	if (!cs_module) {
		PyErr_Clear();
		cs_module = uwsgi_pyimport_by_filename(id, code);
	}

	if (!cs_module) {
		UWSGI_RELEASE_GIL;
		return NULL;
	}

	cs_dict = PyModule_GetDict(cs_module);
	if (!cs_dict) {
		PyErr_Print();
		UWSGI_RELEASE_GIL;
		return NULL;
	}
	
	PyObject *func = PyDict_GetItemString(cs_dict, function);
	if (!func) {
		uwsgi_log("function %s not available in %s\n", function, code);
		PyErr_Print();
		UWSGI_RELEASE_GIL;
		return NULL;
	}

	PyObject *args = PyTuple_New(1);

	PyTuple_SetItem(args, 0, PyString_FromStringAndSize(key, keylen));

	PyObject *ret = python_call(func, args, 0, NULL);
	Py_DECREF(args);
	if (ret && PyString_Check(ret)) {
		char *val = PyString_AsString(ret);
		UWSGI_RELEASE_GIL;
		return val;
	}

	UWSGI_RELEASE_GIL;
	return NULL;
	
}
Ejemplo n.º 12
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.º 13
0
uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {

	UWSGI_GET_GIL;

	uint8_t i;
	char *rv;
	size_t rl;

	PyObject *pyargs = PyTuple_New(argc);
	PyObject *ret;

	if (!pyargs)
		return 0;

	for (i = 0; i < argc; i++) {
		PyTuple_SetItem(pyargs, i, PyString_FromStringAndSize(argv[i], argvs[i]));
	}

	ret = python_call((PyObject *) func, pyargs, 0, NULL);
	Py_DECREF(pyargs);
	if (ret) {
		if (PyString_Check(ret)) {
			rv = PyString_AsString(ret);
			rl = PyString_Size(ret);
			if (rl <= 65536) {
				memcpy(buffer, rv, rl);
				Py_DECREF(ret);
				UWSGI_RELEASE_GIL;
				return rl;
			}
		}
		Py_DECREF(ret);
	}

	if (PyErr_Occurred())
		PyErr_Print();

	UWSGI_RELEASE_GIL;

	return 0;

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


	struct wsgi_request *wsgi_req = find_first_available_wsgi_req();

	if (wsgi_req == NULL) {
		uwsgi_log("async queue is full !!!\n");
		goto clear;
	}
	uwsgi.wsgi_req = wsgi_req;

	// fill wsgi_request structure
	wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets );

	// mark core as used
	uwsgi.core[wsgi_req->async_id]->in_request = 1;

	gettimeofday(&wsgi_req->start_of_request, NULL);

	// enter harakiri mode
        if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
                set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
        }

	// accept the connection
	if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) {
		uwsgi_close_request(wsgi_req);
		free_req_queue;
		goto clear;
	}

	// hack to easily pass wsgi_req pointer to the greenlet
	PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req));

	// spawn the request greenlet
	PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL);
	Py_DECREF(new_gl);

clear:
	Py_INCREF(Py_None);
	return Py_None;
}
Ejemplo n.º 15
0
void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {

	PyObject *zero;

	int i;
        PyObject *pydictkey, *pydictvalue;
        char *path_info;

        for (i = 0; i < wsgi_req->var_cnt; i += 2) {
#ifdef UWSGI_DEBUG
                uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
#endif
#ifdef PYTHREE
                pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
                pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
#else
                pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
                pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
#endif
                PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
                Py_DECREF(pydictkey);
                Py_DECREF(pydictvalue);
        }

        if (wsgi_req->uh->modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
                wsgi_req->uh->modifier1 = python_plugin.modifier1;
                pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
                if (pydictkey) {
                        if (PyString_Check(pydictkey)) {
                                pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO");
                                if (pydictvalue) {
                                        if (PyString_Check(pydictvalue)) {
                                                path_info = PyString_AsString(pydictvalue);
                                                PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey)));
                                        }
                                }
                        }
                }
        }

        // create wsgi.input custom object
        wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
        ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;

        PyDict_SetItemString(wsgi_req->async_environ, "web3.input", wsgi_req->async_input);

	PyDict_SetItemString(wsgi_req->async_environ, "web3.version", wi->gateway_version);

	zero = PyFile_FromFile(stderr, "web3_input", "w", NULL);
	PyDict_SetItemString(wsgi_req->async_environ, "web3.errors", zero);
	Py_DECREF(zero);

	PyDict_SetItemString(wsgi_req->async_environ, "web3.run_once", Py_False);

	PyDict_SetItemString(wsgi_req->async_environ, "web3.multithread", Py_False);
	if (uwsgi.numproc == 1) {
		PyDict_SetItemString(wsgi_req->async_environ, "web3.multiprocess", Py_False);
	}
	else {
		PyDict_SetItemString(wsgi_req->async_environ, "web3.multiprocess", Py_True);
	}

	if (wsgi_req->scheme_len > 0) {
		zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len);
	}
	else if (wsgi_req->https_len > 0) {
		if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') {
			zero = UWSGI_PYFROMSTRING("https");
		}
		else {
			zero = UWSGI_PYFROMSTRING("http");
		}
	}
	else {
		zero = UWSGI_PYFROMSTRING("http");
	}
	PyDict_SetItemString(wsgi_req->async_environ, "web3.url_scheme", zero);
	Py_DECREF(zero);


	wsgi_req->async_app = wi->callable;

	// export .env only in non-threaded mode
        if (uwsgi.threads < 2) {
        	PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
        }

        PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);

        if (uwsgi.cores > 1) {
                PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id));
        }

        PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node);


	// call

	if (PyTuple_GetItem(wsgi_req->async_args, 0) != wsgi_req->async_environ) {
	    if (PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ)) {
	        uwsgi_log_verbose("unable to set environ to the python application callable, consider using the holy env allocator\n");
	        return NULL;
	    }
	}
	return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req);
}
Ejemplo n.º 16
0
int uwsgi_python_spooler(char *filename, char *buf, uint16_t len, char *body, size_t body_len) {

	static int random_seed_reset = 0;

	UWSGI_GET_GIL;

	PyObject *spool_dict = PyDict_New();
	PyObject *spool_func, *pyargs, *ret;

	if (!random_seed_reset) {
		uwsgi_python_reset_random_seed();
		random_seed_reset = 1;	
	}

	if (!up.embedded_dict) {
		// ignore
		UWSGI_RELEASE_GIL;
		return 0;
	}

	spool_func = PyDict_GetItemString(up.embedded_dict, "spooler");
	if (!spool_func) {
		// ignore
		UWSGI_RELEASE_GIL;
		return 0;
	}

	if (uwsgi_hooked_parse(buf, len, uwsgi_python_add_item, spool_dict)) {
		// malformed packet, destroy it
		UWSGI_RELEASE_GIL;
		return -2;
	}

	pyargs = PyTuple_New(1);

	PyDict_SetItemString(spool_dict, "spooler_task_name", PyString_FromString(filename));

	if (body && body_len > 0) {
		PyDict_SetItemString(spool_dict, "body", PyString_FromStringAndSize(body, body_len));
	}
	PyTuple_SetItem(pyargs, 0, spool_dict);

	ret = python_call(spool_func, pyargs, 0, NULL);

	if (ret) {
		if (!PyInt_Check(ret)) {
			// error, retry
			UWSGI_RELEASE_GIL;
			return -1;
		}	

		int retval = (int) PyInt_AsLong(ret);
		UWSGI_RELEASE_GIL;
		return retval;
		
	}
	
	if (PyErr_Occurred())
		PyErr_Print();

	// error, retry
	UWSGI_RELEASE_GIL;
	return -1;
}
Ejemplo n.º 17
0
void *uwsgi_request_subhandler_pump(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {

	PyObject *zero;

	int i;
        PyObject *pydictkey, *pydictvalue;

	char *port = memchr(wsgi_req->host, ':', wsgi_req->host_len);
	if (port) {

		zero = PyString_FromStringAndSize(wsgi_req->host, (port-wsgi_req->host));
		PyDict_SetItemString(wsgi_req->async_environ, "server_name", zero);
		Py_DECREF(zero);

		zero = PyString_FromStringAndSize(port, wsgi_req->host_len-((port+1)-wsgi_req->host));
		PyDict_SetItemString(wsgi_req->async_environ, "server_port", zero);
		Py_DECREF(zero);
	}
	else {

		zero = PyString_FromStringAndSize(wsgi_req->host, wsgi_req->host_len);
		PyDict_SetItemString(wsgi_req->async_environ, "server_name", zero);
		Py_DECREF(zero);

		zero = PyString_FromStringAndSize("80", 2);
		PyDict_SetItemString(wsgi_req->async_environ, "server_port", zero);
		Py_DECREF(zero);
	}

	zero = PyString_FromStringAndSize(wsgi_req->remote_addr, wsgi_req->remote_addr_len);
	PyDict_SetItemString(wsgi_req->async_environ, "remote_addr", zero);
	Py_DECREF(zero);

	zero = PyString_FromStringAndSize(wsgi_req->path_info, wsgi_req->path_info_len);
	PyDict_SetItemString(wsgi_req->async_environ, "uri", zero);
	Py_DECREF(zero);

	if (wsgi_req->query_string_len > 0) {
		zero = PyString_FromStringAndSize(wsgi_req->query_string, wsgi_req->query_string_len);
		PyDict_SetItemString(wsgi_req->async_environ, "query_string", zero);
		Py_DECREF(zero);
	}

	zero = PyString_FromStringAndSize(uwsgi_lower(wsgi_req->method, wsgi_req->method_len), wsgi_req->method_len);
	PyDict_SetItemString(wsgi_req->async_environ, "method", zero);
	Py_DECREF(zero);

	if (wsgi_req->post_cl > 0) {
		PyDict_SetItemString(wsgi_req->async_environ, "content_length", PyInt_FromLong(wsgi_req->post_cl));
		if (wsgi_req->content_type_len > 0) {
			zero = PyString_FromStringAndSize(wsgi_req->content_type, wsgi_req->content_type_len);
                	PyDict_SetItemString(wsgi_req->async_environ, "content_type", zero);
                	Py_DECREF(zero);
		}
	}



	PyObject *headers = PyDict_New();

        for (i = 0; i < wsgi_req->var_cnt; i += 2) {
#ifdef UWSGI_DEBUG
                uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
#endif
		if (wsgi_req->hvec[i].iov_len < 6) continue;
		if (!uwsgi_startswith(wsgi_req->hvec[i].iov_base, "HTTP_", 5)) {
			(void) uwsgi_lower(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
#ifdef PYTHREE
                	pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5, NULL);
                	pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
#else
                	pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
                	pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
#endif
			PyObject *old_value = PyDict_GetItem(headers, pydictkey);
			if (old_value) {
				if (PyString_Check(old_value)) {
					PyObject *new_value = PyList_New(0);
					PyList_Append(new_value, old_value);
					old_value = new_value;
                			PyDict_SetItem(headers, pydictkey, old_value);
					Py_DECREF(old_value);
				}
				PyList_Append(old_value, pydictvalue);
			}
			else {
                		PyDict_SetItem(headers, pydictkey, pydictvalue);
			}
                	Py_DECREF(pydictkey);
                	Py_DECREF(pydictvalue);
		}
        }

	PyDict_SetItemString(wsgi_req->async_environ, "headers", headers);
	Py_DECREF(headers);

        // create wsgi.input custom object
        wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
        ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;

        PyDict_SetItemString(wsgi_req->async_environ, "body", wsgi_req->async_input);

	if (wsgi_req->scheme_len > 0) {
		zero = PyString_FromStringAndSize(wsgi_req->scheme, wsgi_req->scheme_len);
	}
	else if (wsgi_req->https_len > 0) {
		if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') {
			zero = PyString_FromString("https");
		}
		else {
			zero = PyString_FromString("http");
		}
	}
	else {
		zero = PyString_FromString("http");
	}
	PyDict_SetItemString(wsgi_req->async_environ, "scheme", zero);
	Py_DECREF(zero);


	wsgi_req->async_app = wi->callable;

	// export .env only in non-threaded mode
        if (uwsgi.threads < 2) {
        	PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
        }

        PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);

        if (uwsgi.cores > 1) {
                PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id));
        }

        PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node);

	// call

	PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ);
	return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req);
}
Ejemplo n.º 18
0
void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {

	PyObject *zero;
	int i;
	PyObject *pydictkey, *pydictvalue;
	char *path_info;

        for (i = 0; i < wsgi_req->var_cnt; i += 2) {
#ifdef UWSGI_DEBUG
                uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
#endif
#ifdef PYTHREE
                pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
                pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
#else
                pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
                pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
#endif

#ifdef UWSGI_DEBUG
		uwsgi_log("%p %d %p %d\n", pydictkey, wsgi_req->hvec[i].iov_len, pydictvalue, wsgi_req->hvec[i + 1].iov_len);
#endif
                PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
                Py_DECREF(pydictkey);
		Py_DECREF(pydictvalue);
        }

        if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
                wsgi_req->uh.modifier1 = 0;
                pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
                if (pydictkey) {
                        if (PyString_Check(pydictkey)) {
                                pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO");
                                if (pydictvalue) {
                                        if (PyString_Check(pydictvalue)) {
                                                path_info = PyString_AsString(pydictvalue);
                                                PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey)));
                                        }
                                }
                        }
                }
        }


        // if async_post is mapped as a file, directly use it as wsgi.input
        if (wsgi_req->async_post) {
#ifdef PYTHREE
                wsgi_req->async_input = PyFile_FromFd(fileno((FILE *)wsgi_req->async_post), "wsgi_input", "rb", 0, NULL, NULL, NULL, 0);
#else
                wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL);
#endif
        }
        else {
                // create wsgi.input custom object
                wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType);
                ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req;
                ((uwsgi_Input*)wsgi_req->async_input)->pos = 0;
                ((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0;
                ((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0;

        }


        PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input);

#ifdef UWSGI_SENDFILE
	PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile);
#endif

#ifdef UWSGI_ASYNC
	if (uwsgi.async > 1) {
		PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.readable", wi->eventfd_read);
		PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.writable", wi->eventfd_write);
		PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None);
	}
#endif

	PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version);

	zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL);
	PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero);
	Py_DECREF(zero);

	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);
	}
	else {
		PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_False);
	}
	if (uwsgi.numproc == 1) {
		PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_False);
	}
	else {
		PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_True);
	}


	if (wsgi_req->scheme_len > 0) {
		zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len);
	}
	else if (wsgi_req->https_len > 0) {
		if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') {
			zero = UWSGI_PYFROMSTRING("https");
		}
		else {
			zero = UWSGI_PYFROMSTRING("http");
		}
	}
	else {
		zero = UWSGI_PYFROMSTRING("http");
	}
	PyDict_SetItemString(wsgi_req->async_environ, "wsgi.url_scheme", zero);
	Py_DECREF(zero);

	wsgi_req->async_app = wi->callable;

	// export .env only in non-threaded mode
	if (uwsgi.threads < 2) {
		PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
	}

	PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);

	if (uwsgi.cores > 1) {
		zero = PyInt_FromLong(wsgi_req->async_id);
		PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", zero);
		Py_DECREF(zero);
	}

	// cache this ?
	if (uwsgi.cluster_fd >= 0) {
		zero = PyString_FromString(uwsgi.cluster);
		PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero);
		Py_DECREF(zero);
		zero = PyString_FromString(uwsgi.hostname);
		PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero);
		Py_DECREF(zero);
	}

	PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node);

	// call
	PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ);
	return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req);
}
Ejemplo n.º 19
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.º 20
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.º 21
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.º 22
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.º 23
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.º 24
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;

}