From f4f4d5a6c02057d6ad645d868f431fdff1524d75 Mon Sep 17 00:00:00 2001 From: "roberto@oneiric64" Date: Fri, 10 Feb 2012 11:18:53 +0100 Subject: [PATCH] python atexit improvements from mod_wsgi --- logic.ini | 47 +++++++++++++++ plugins/python/python_plugin.c | 13 ++++ utils.c | 105 +++++++++++++++++++++++++++++---- uwsgi.c | 19 +++++- uwsgi.h | 4 ++ 5 files changed, 174 insertions(+), 14 deletions(-) create mode 100644 logic.ini diff --git a/logic.ini b/logic.ini new file mode 100644 index 00000000..0218da2d --- /dev/null +++ b/logic.ini @@ -0,0 +1,47 @@ +[uwsgi] + +for = 4031 14032 4033 14034 24035 + socket = /tmp/%(_)/uwsgi.sock + socket = 192.*:%(_) + print = ciao %(_) hello %(_) bye %(_) +endfor = + + +socket = :4045 +socket = :4046 +socket = :4047 +socket = :4048 + + +socket = :4049 +socket = :4050 +socket = :4051 + +show-config = + +if-env = PIPPO + print = + print = PIPPO e' definita e il suo valore e' %(_) boh +endif = + +socket = :5051 +socket = :5052 +socket = :5053 +socket = :5054 + +if-exists = /etc/services + print = il file %(_) esiste $(PATH) +endif = + +if-exists = /etc/foobar + print = il file %(_) esiste $(PATH) +endif = + +socket = :6060 +if-file = /etc/fstab + socket = :7171 +endif = + +ifdir = /tmp + print = %(_) is a directory +endif= diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 5d0b6a44..b800820f 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -257,6 +257,19 @@ void uwsgi_python_atexit() { python_call(ae, PyTuple_New(0), 0, NULL); } } + + // 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.threads > 1) { + if (!PyImport_AddModule("dummy_threading")) + PyErr_Clear(); + } + + Py_Finalize(); } void uwsgi_python_post_fork() { diff --git a/utils.c b/utils.c index 4aa3d31a..962847e0 100644 --- a/utils.c +++ b/utils.c @@ -1747,37 +1747,114 @@ struct uwsgi_option *uwsgi_opt_get(char *name) { return NULL; } -char *uwsgi_substitue(char *src, char *what, char *with) { +char *uwsgi_substitute(char *src, char *what, char *with) { - size_t len = strlen(src)+1; - size_t wlen = strlen(with)+1; - char *dst = uwsgi_calloc(len); + int count = 0; + if (!with) return src; + + size_t len = strlen(src); + size_t wlen = strlen(what); + + char *p = strstr(src, what); + if (!p) { + return src; + } + + while(p) { + count++; + p = strstr(p+wlen, what); + } + + len += (count * wlen) + 1; + + char *dst = uwsgi_calloc( len ); char *ptr = src; - char *p = strstr(ptr, what); + p = strstr(ptr, what); while(p) { - strncat(dst, ptr, (p-ptr)); - ptr = p + (wlen-2); - len += wlen; - dst = realloc(dst, len); + strncat(dst, ptr, (p-ptr)); strcat(dst, with); + ptr = p + wlen ; p = strstr(ptr, what); } + strcat(dst, ptr); + return dst; } +int uwsgi_is_file(char *filename) { + struct stat st; + if (stat(filename, &st)) { + return 0; + } + if (S_ISREG(st.st_mode)) + return 1; + return 0; +} + +int uwsgi_is_dir(char *filename) { + struct stat st; + if (stat(filename, &st)) { + return 0; + } + if (S_ISDIR(st.st_mode)) + return 1; + return 0; +} + +int uwsgi_logic_opt_if_env(char *key, char *value) { + + char *p = getenv(uwsgi.logic_opt_data); + if (p) { + add_exported_option(key, uwsgi_substitute(value, "%(_)", p), 0); + return 1; + } + + return 0; +} + +int uwsgi_logic_opt_if_file(char *key, char *value) { + + if (uwsgi_is_file(uwsgi.logic_opt_data)) { + add_exported_option(key, uwsgi_substitute(value, "%(_)", uwsgi.logic_opt_data), 0); + return 1; + } + + return 0; +} + +int uwsgi_logic_opt_if_dir(char *key, char *value) { + + if (uwsgi_is_dir(uwsgi.logic_opt_data)) { + add_exported_option(key, uwsgi_substitute(value, "%(_)", uwsgi.logic_opt_data), 0); + return 1; + } + + return 0; +} + + +int uwsgi_logic_opt_if_exists(char *key, char *value) { + + if (uwsgi_file_exists(uwsgi.logic_opt_data)) { + add_exported_option(key, uwsgi_substitute(value, "%(_)", uwsgi.logic_opt_data), 0); + return 1; + } + + return 0; +} + + int uwsgi_logic_opt_for(char *key, char *value) { char *p = strtok(uwsgi.logic_opt_data, " "); while(p) { - uwsgi.logic_opt_running = 1; - add_exported_option(key, uwsgi_substitue(value, "%(_)", p), 0); - uwsgi.logic_opt_running = 0; + add_exported_option(key, uwsgi_substitute(value, "%(_)", p), 0); p = strtok(NULL, " "); } - return 0; + return 1; } void add_exported_option(char *key, char *value, int configured) { @@ -1800,7 +1877,9 @@ void add_exported_option(char *key, char *value, int configured) { } uwsgi.logic_opt_data = uwsgi_str(uwsgi.logic_opt_arg); uwsgi.logic_opt_cycles++; + uwsgi.logic_opt_running = 1; uwsgi.logic_opt(key, value); + uwsgi.logic_opt_running = 0; return; } diff --git a/uwsgi.c b/uwsgi.c index 44e34855..79e91f2a 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -61,6 +61,19 @@ static struct uwsgi_option uwsgi_base_options[] = { {"for", required_argument, 0, "(opt logic) for cycle", uwsgi_opt_logic, (void *) uwsgi_logic_opt_for, UWSGI_OPT_IMMEDIATE}, {"endfor", optional_argument, 0, "(opt logic) end for cycle", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE}, + {"if-env", required_argument, 0, "(opt logic) check for environment variable", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_env, UWSGI_OPT_IMMEDIATE}, + {"ifenv", required_argument, 0, "(opt logic) check for environment variable", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_env, UWSGI_OPT_IMMEDIATE}, + + {"if-exists", required_argument, 0, "(opt logic) check for file/directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_exists, UWSGI_OPT_IMMEDIATE}, + {"ifexists", required_argument, 0, "(opt logic) check for file/directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_exists, UWSGI_OPT_IMMEDIATE}, + + {"if-file", required_argument, 0, "(opt logic) check for file existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_file, UWSGI_OPT_IMMEDIATE}, + {"if-dir", required_argument, 0, "(opt logic) check for directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_dir, UWSGI_OPT_IMMEDIATE}, + {"ifdir", required_argument, 0, "(opt logic) check for directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_dir, UWSGI_OPT_IMMEDIATE}, + {"if-directory", required_argument, 0, "(opt logic) check for directory existance", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_dir, UWSGI_OPT_IMMEDIATE}, + + {"endif", optional_argument, 0, "(opt logic) end if", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE}, + {"inherit", required_argument, 0, "use the specified file as config template", uwsgi_opt_load, NULL,0}, {"daemonize", required_argument, 'd', "daemonize uWSGI", uwsgi_opt_set_str, &uwsgi.daemonize, 0}, {"stop", required_argument, 0, "stop an instance", uwsgi_opt_pidfile_signal, (void *) SIGINT, UWSGI_OPT_IMMEDIATE}, @@ -2203,7 +2216,6 @@ skipzero: } } - /* gp/plugin initialization */ for (i = 0; i < uwsgi.gp_cnt; i++) { if (uwsgi.gp[i]->post_init) { @@ -3549,6 +3561,11 @@ void uwsgi_opt_load(char *opt, char *filename, void *none) { } void uwsgi_opt_logic(char *opt, char *arg, void *func) { + + if (uwsgi.logic_opt) { + uwsgi_log("recursive logic in options is not supported (option = %s)\n", opt); + exit(1); + } uwsgi.logic_opt = (int (*)(char *, char *)) func; uwsgi.logic_opt_cycles = 0; if (arg) { diff --git a/uwsgi.h b/uwsgi.h index 9370da89..38071ac8 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2565,6 +2565,10 @@ void uwsgi_opt_noop(char *, char *, void *); void uwsgi_opt_logic(char *, char *, void *); int uwsgi_logic_opt_for(char *, char *); +int uwsgi_logic_opt_if_env(char *, char *); +int uwsgi_logic_opt_if_exists(char *, char *); +int uwsgi_logic_opt_if_file(char *, char *); +int uwsgi_logic_opt_if_dir(char *, char *); #ifdef UWSGI_CAP